picture.datatype: gi_RastPort should not be directly accessed
[AROS.git] / workbench / classes / datatypes / picture / pictureclass.c
blobaeb122de4421811c63deb762191027b160ec907b
1 /*
2 Copyright © 1995-2012, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /* Supported Attributes (Init (new), Set, Get)
7 I.. ULONG Precision;
8 ISG ULONG ModeID;
9 ..G struct BitMapHeader bmhd;
10 ISG struct BitMap *SrcBM;
11 ISG struct BitMap *ClassBM;
12 ..G ULONG CRegs[768];
13 ..G struct BitMap *DestBM;
14 ..G ULONG GRegs[768];
15 IS. struct Screen *DestScreen;
16 ..G struct ColorRegister ColMap[256];
17 ..G UBYTE ColTable[256];
18 ..G UBYTE ColTable2[256];
19 ISG UWORD NumColors;
20 ..G UWORD NumAlloc;
21 ..G ULONG Allocated;
22 I.. UBYTE SparseTable[256];
23 I.. UWORD NumSparse;
24 ISG Point Grab;
25 ISG BOOL FreeSource;
26 I.. BOOL Remap;
27 ISG BOOL UseFriendBM;
28 ISG BOOL DestMode
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
35 #include <exec/types.h>
36 #include <exec/memory.h>
37 #include <dos/dostags.h>
38 #include <graphics/gfxbase.h>
39 #include <graphics/rpattr.h>
40 #include <intuition/imageclass.h>
41 #include <intuition/icclass.h>
42 #include <intuition/gadgetclass.h>
43 #include <intuition/cghooks.h>
44 #include <datatypes/datatypesclass.h>
45 #include <datatypes/pictureclass.h>
46 #include <cybergraphx/cybergraphics.h>
48 #include <clib/alib_protos.h>
49 #include <proto/exec.h>
50 #include <proto/dos.h>
51 #include <proto/intuition.h>
52 #include <proto/graphics.h>
53 #include <proto/utility.h>
54 #include <proto/iffparse.h>
55 #include <proto/layers.h>
56 #include <proto/datatypes.h>
57 #include <proto/cybergraphics.h>
59 #ifndef __AROS__
60 #include "compilerspecific.h"
61 #else
62 #ifdef STATIC
63 #undef STATIC
64 #endif
65 #define STATIC
66 #endif
67 #include "debug.h"
68 #include "pictureclass.h"
69 #include "prefs.h"
70 #include "colorhandling.h"
72 #ifdef MYDEBUG
73 #include "methods.h"
74 #endif
76 #define DGS(x) D(x)
77 //#define DGS(x)
79 /**************************************************************************************************/
81 const IPTR SupportedMethods[] =
83 OM_NEW,
84 OM_GET,
85 OM_SET,
86 OM_UPDATE,
87 OM_DISPOSE,
89 GM_LAYOUT,
90 GM_HITTEST,
91 GM_GOACTIVE,
92 GM_HANDLEINPUT,
93 GM_RENDER,
95 DTM_PROCLAYOUT,
96 DTM_ASYNCLAYOUT,
97 DTM_FRAMEBOX,
99 DTM_OBTAINDRAWINFO,
100 DTM_DRAW,
101 DTM_RELEASEDRAWINFO,
103 // DTM_SELECT,
104 // DTM_CLEARSELECTED,
105 // DTM_COPY,
106 DTM_PRINT,
107 // DTM_WRITE,
109 PDTM_WRITEPIXELARRAY,
110 PDTM_READPIXELARRAY,
111 PDTM_SCALE,
113 (~0)
116 /**************************************************************************************************/
118 STATIC IPTR DT_SetMethod(struct IClass *cl, struct Gadget *g, struct opSet *msg);
120 /**************************************************************************************************/
122 IPTR NotifyAttrChanges(Object * o, VOID * ginfo, ULONG flags, Tag tag1, ...)
124 AROS_SLOWSTACKTAGS_PRE(tag1)
125 retval = DoMethod(o, OM_NOTIFY, AROS_SLOWSTACKTAGS_ARG(tag1), (IPTR) ginfo, flags);
126 AROS_SLOWSTACKTAGS_POST
129 /**************************************************************************************************/
131 STATIC struct Gadget *DT_NewMethod(struct IClass *cl, Object *o, struct opSet *msg)
133 struct Gadget *g;
134 struct TagItem *attrs = msg->ops_AttrList;
135 struct TagItem *ti;
136 struct Picture_Data *pd;
138 #if 0 /* DTA_SourceType is handled by subclasses */
139 IPTR sourcetype;
140 IPTR handle;
142 sourcetype = GetTagData(DTA_SourceType, DTST_FILE, attrs);
143 handle = GetTagData(DTA_Handle, NULL, attrs);
145 if( sourcetype == DTST_RAM && handle == NULL )
147 D(bug("picture.datatype/OM_NEW: Creating an empty object\n"));
149 else if( !(sourcetype==DTST_CLIPBOARD || sourcetype==DTST_FILE) )
151 D(bug("picture.datatype/OM_NEW: wrong DTA_SourceType\n"));
152 SetIoErr(ERROR_OBJECT_WRONG_TYPE);
153 return FALSE;
155 #endif /* 0 */
157 g = (struct Gadget *) DoSuperMethodA(cl, o, (Msg) msg);
158 if( !g )
160 return FALSE;
162 D(bug("picture.datatype/OM_NEW: Created object 0x%lx\n", (long)g));
164 /* initialize our class structure with zeros (or FALSE for BOOL's) */
165 pd = (struct Picture_Data *) INST_DATA(cl, g);
166 memset(pd, 0, sizeof(struct Picture_Data));
168 /* initialize some non-zero values */
169 pd->Precision = PRECISION_IMAGE;
170 pd->ModeID = INVALID_ID;
171 pd->Remap = TRUE;
172 pd->SrcPixelFormat = -1;
173 pd->DitherQuality = 0;
174 pd->UseFriendBM = 1;
175 pd->DestMode = 1; /* needs to be changed to FALSE after Multiview adaptation */
177 /* Prefs overrides default, but application overrides Prefs */
178 ReadPrefs(pd);
179 while((ti=NextTagItem(&attrs)))
181 switch (ti->ti_Tag)
183 case OBP_Precision:
184 pd->Precision = (ULONG) ti->ti_Data;
185 DGS(bug("picture.datatype/OM_NEW: Tag ID OBP_Precision: %ld\n", (long)pd->Precision));
186 break;
188 case PDTA_Remap:
189 pd->Remap = (BOOL) ti->ti_Data;
190 DGS(bug("picture.datatype/OM_NEW: Tag ID PDTA_Remap: %ld\n", (long)pd->Remap));
191 break;
193 case PDTA_NumSparse:
194 pd->NumSparse = (UWORD) ti->ti_Data;
195 DGS(bug("picture.datatype/OM_NEW: Tag ID PDTA_NumSparse: %ld\n", (long)pd->NumSparse));
196 break;
198 case PDTA_SparseTable:
199 DGS(bug("picture.datatype/OM_NEW: Tag ID PDTA_SparseTable\n"));
200 if(!(pd->NumSparse && ti->ti_Data))
202 break;
204 CopyMem((APTR) ti->ti_Data, (APTR) pd->SparseTable, pd->NumSparse);
205 break;
207 #ifdef __AROS__
208 case PDTA_DelayRead:
209 if(!pd->NoDelay)
210 pd->DelayRead = (BOOL) ti->ti_Data;
211 DGS(bug("picture.datatype/OM_NEW: Tag ID PDTA_DelayRead: %ld\n", (long)pd->DelayRead));
212 break;
213 #endif
217 D(bug("picture.datatype/OM_NEW: Setting attributes\n"));
218 DT_SetMethod(cl, g, msg);
220 return g;
223 /**************************************************************************************************/
225 STATIC IPTR DT_DisposeMethod(struct IClass *cl, Object *o, Msg msg)
227 struct Picture_Data *pd;
228 IPTR RetVal;
230 RetVal = 1;
232 pd = (struct Picture_Data *) INST_DATA(cl, o);
234 if(pd)
236 FreeDest(pd);
237 FreeSource(pd);
240 RetVal += DoSuperMethodA(cl, o, msg);
242 return RetVal;
245 /**************************************************************************************************/
247 STATIC IPTR DT_SetMethod(struct IClass *cl, struct Gadget *g, struct opSet *msg)
249 struct Picture_Data *pd;
250 struct TagItem *tl = msg->ops_AttrList;
251 struct TagItem *ti;
252 IPTR RetVal;
253 struct RastPort *rp;
255 pd=(struct Picture_Data *) INST_DATA(cl, g);
256 RetVal=0;
258 while((ti=NextTagItem(&tl)))
260 switch (ti->ti_Tag)
262 case DTA_VisibleHoriz:
263 case DTA_VisibleVert:
264 RetVal = 1;
265 break;
267 case PDTA_ModeID:
268 pd->ModeID = (ULONG) ti->ti_Data;
269 DGS(bug("picture.datatype/OM_SET: Tag PDTA_ModeID: 0x%lx\n", (long)pd->ModeID));
270 break;
272 case PDTA_ClassBitMap:
273 pd->KeepSrcBM = TRUE;
274 DGS(bug("picture.datatype/OM_GET: Tag PDTA_ClassBitMap: Handled as PDTA_BitMap\n"));
275 case PDTA_BitMap:
276 pd->SrcBM = (struct BitMap *) ti->ti_Data;
277 DGS(bug("picture.datatype/OM_SET: Tag PDTA_BitMap: 0x%lx\n", (long)pd->SrcBM));
278 break;
280 case PDTA_Screen:
281 pd->DestScreen = (struct Screen *) ti->ti_Data;
282 DGS(bug("picture.datatype/OM_SET: Tag PDTA_Screen: 0x%lx\n", (long)pd->DestScreen));
283 break;
285 case PDTA_NumColors:
286 pd->NumColors = (UWORD) ti->ti_Data;
287 DGS(bug("picture.datatype/OM_SET: Tag PDTA_NumColors: %ld\n", (long)pd->NumColors));
288 break;
290 case PDTA_Grab:
292 Point *ThePoint;
294 DGS(bug("picture.datatype/OM_SET: Tag PDTA_Grab\n"));
295 ThePoint = (Point *) ti->ti_Data;
296 if(!ThePoint)
298 break;
300 pd->Grab.x = ThePoint->x;
301 pd->Grab.y = ThePoint->y;
302 break;
305 case PDTA_SourceMode:
306 DGS(bug("picture.datatype/OM_SET: Tag PDTA_SourceMode (ignored): %ld\n", (long)ti->ti_Data));
307 break;
309 case PDTA_DestMode:
310 pd->DestMode = (BOOL) ti->ti_Data;
311 DGS(bug("picture.datatype/OM_SET: Tag PDTA_DestMode: %ld\n", (long)pd->DestMode));
312 break;
314 case PDTA_FreeSourceBitMap:
315 pd->FreeSource = (BOOL) ti->ti_Data;
316 DGS(bug("picture.datatype/OM_SET: Tag PDTA_FreeSourceBitMap: %ld\n", (long)pd->FreeSource));
317 break;
319 case PDTA_UseFriendBitMap:
320 pd->UseFriendBM = (BOOL) ti->ti_Data;
321 DGS(bug("picture.datatype/OM_SET: Tag PDTA_UseFriendBitMap: %ld\n", (long)pd->UseFriendBM));
322 break;
324 case PDTA_MaxDitherPens:
325 pd->MaxDitherPens = (UWORD) ti->ti_Data;
326 DGS(bug("picture.datatype/OM_SET: Tag PDTA_MaxDitherPens: %ld\n", (long)pd->MaxDitherPens));
327 break;
329 case PDTA_DitherQuality:
330 pd->DitherQuality = (UWORD) ti->ti_Data;
331 DGS(bug("picture.datatype/OM_SET: Tag PDTA_DitherQuality: %ld\n", (long)pd->DitherQuality));
332 break;
334 case PDTA_ScaleQuality:
335 pd->ScaleQuality = (UWORD) ti->ti_Data;
336 DGS(bug("picture.datatype/OM_SET: Tag PDTA_ScaleQuality: %ld\n", (long)pd->ScaleQuality));
337 break;
339 case PDTA_Remap:
340 pd->Remap = (BOOL) ti->ti_Data;
341 DGS(bug("picture.datatype/OM_SET: Tag ID PDTA_Remap: %ld\n", (long)pd->Remap));
342 break;
344 #ifdef __AROS__
345 case PDTA_DelayedRead:
346 pd->DelayedRead = (BOOL) ti->ti_Data;
347 DGS(bug("picture.datatype/OM_SET: Tag PDTA_DelayedRead: %ld\n", (long)pd->DelayedRead));
348 break;
349 #endif
351 #ifdef MYDEBUG
352 default:
354 register int i;
355 int Known;
357 Known=FALSE;
359 for(i=0; i<NumAttribs; i++)
361 if(ti->ti_Tag==KnownAttribs[i])
363 Known=TRUE;
365 DGS(bug("picture.datatype/OM_SET: Tag %s: 0x%lx (%ld)\n", AttribNames[i], (long)ti->ti_Data, (long)ti->ti_Data));
369 if(!Known)
371 DGS(bug("picture.datatype/OM_SET: Tag ID 0x%lx: 0x%lx\n", (long)ti->ti_Tag, (long)ti->ti_Data));
374 #endif /* MYDEBUG */
378 #if 0
379 if(msg->ops_GInfo)
381 DoMethod((Object *) g, GM_LAYOUT, msg->ops_GInfo, TRUE);
383 #endif
385 /* Do not call the SuperMethod if you come from OM_NEW! */
386 if(!(msg->MethodID == OM_NEW))
388 RetVal += (IPTR) DoSuperMethodA(cl, (Object *) g, (Msg) msg);
391 if(msg->ops_GInfo)
393 #if 1
394 if (RetVal)
395 #else
396 if(OCLASS((Object *) g) == cl)
397 #endif
399 rp=ObtainGIRPort(msg->ops_GInfo);
400 if(rp)
402 DoMethod((Object *) g, GM_RENDER, (IPTR) msg->ops_GInfo, (IPTR) rp, GREDRAW_UPDATE);
403 ReleaseGIRPort (rp);
407 #if 0 /* stegerg: ?? */
408 if(msg->MethodID == OM_UPDATE)
410 DoMethod((Object *) g, OM_NOTIFY, msg->ops_AttrList, msg->ops_GInfo, 0);
412 #endif
415 return(RetVal);
418 /**************************************************************************************************/
420 STATIC IPTR DT_GetMethod(struct IClass *cl, struct Gadget *g, struct opGet *msg)
422 struct Picture_Data *pd;
424 pd=(struct Picture_Data *) INST_DATA(cl, g);
426 switch(msg->opg_AttrID)
428 case PDTA_ModeID:
429 DGS(bug("picture.datatype/OM_GET: Tag PDTA_ModeID: 0x%lx\n", (long)pd->ModeID));
430 *(msg->opg_Storage)=pd->ModeID;
431 break;
433 case PDTA_BitMapHeader:
434 DGS(bug("picture.datatype/OM_GET: Tag PDTA_BitMapHeader: 0x%lx\n", (long)&pd->bmhd));
435 *(msg->opg_Storage)=(IPTR) &pd->bmhd;
436 break;
438 case PDTA_ClassBitMap:
439 DGS(bug("picture.datatype/OM_GET: Tag PDTA_ClassBitMap: Handled as PDTA_BitMap\n"));
440 case PDTA_BitMap:
441 if( !pd->SrcBM )
442 ConvertChunky2Bitmap( pd );
443 DGS(bug("picture.datatype/OM_GET: Tag PDTA_BitMap: 0x%lx\n", (long)pd->SrcBM));
444 *(msg->opg_Storage)=(IPTR) pd->SrcBM;
445 break;
447 case PDTA_DestBitMap:
448 DGS(bug("picture.datatype/OM_GET: Tag PDTA_DestBitMap: 0x%lx\n", (long)pd->DestBM));
449 *(msg->opg_Storage)=(IPTR) pd->DestBM;
450 break;
452 case PDTA_MaskPlane:
453 CreateMaskPlane( pd );
454 DGS(bug("picture.datatype/OM_GET: Tag PDTA_MaskPlane: 0x%lx\n", (long)pd->MaskPlane));
455 *(msg->opg_Storage)=(IPTR) pd->MaskPlane;
456 break;
458 case PDTA_Screen:
459 DGS(bug("picture.datatype/OM_GET: Tag PDTA_Screen: 0x%lx\n", (long)pd->DestScreen));
460 *(msg->opg_Storage)=(IPTR) pd->DestScreen;
461 break;
463 case PDTA_ColorRegisters:
464 DGS(bug("picture.datatype/OM_GET: Tag PDTA_ColorRegisters: 0x%lx\n", (long)&pd->ColMap));
465 *(msg->opg_Storage)=(IPTR) &pd->ColMap;
466 break;
468 case PDTA_CRegs:
469 DGS(bug("picture.datatype/OM_GET: Tag PDTA_CRegs: 0x%lx\n", (long)&pd->SrcColRegs));
470 *(msg->opg_Storage)=(IPTR) &pd->SrcColRegs;
471 break;
473 case PDTA_GRegs:
474 DGS(bug("picture.datatype/OM_GET: Tag PDTA_GRegs: 0x%lx\n", (long)&pd->DestColRegs));
475 *(msg->opg_Storage)=(IPTR) &pd->DestColRegs;
476 break;
478 case PDTA_AllocatedPens:
479 DGS(bug("picture.datatype/OM_GET: Tag PDTA_AllocatedPens: Handled by PDTA_ColorTable2\n"));
480 case PDTA_ColorTable2:
481 DGS(bug("picture.datatype/OM_GET: Tag PDTA_ColorTable2: Handled by PDTA_ColorTable\n"));
482 case PDTA_ColorTable:
483 DGS(bug("picture.datatype/OM_GET: Tag PDTA_ColorTable: 0x%lx\n", (long)&pd->ColTable));
484 *(msg->opg_Storage)=(IPTR) &pd->ColTable;
485 break;
487 case PDTA_NumColors:
488 DGS(bug("picture.datatype/OM_GET: Tag PDTA_NumColors: %ld\n", (long)pd->NumColors));
489 *(msg->opg_Storage)=(IPTR) pd->NumColors;
490 break;
492 case PDTA_NumAlloc:
493 DGS(bug("picture.datatype/OM_GET: Tag PDTA_NumAlloc: %ld\n", (long)pd->NumAlloc));
494 *(msg->opg_Storage)=(IPTR) pd->NumAlloc;
495 break;
497 case PDTA_Grab:
498 DGS(bug("picture.datatype/OM_GET: Tag PDTA_Grab: 0x%lx\n", (long)&pd->Grab));
499 *(msg->opg_Storage)=(IPTR) &pd->Grab;
500 break;
502 case PDTA_SourceMode:
503 DGS(bug("picture.datatype/OM_GET: Tag PDTA_SourceMode: 0x%lx\n", (long)PMODE_V43));
504 *(msg->opg_Storage)=(IPTR) PMODE_V43;
505 break;
507 case PDTA_DestMode:
508 DGS(bug("picture.datatype/OM_GET: Tag PDTA_DestMode: 0x%lx\n", (long)pd->DestMode));
509 *(msg->opg_Storage)=(IPTR) pd->DestMode;
510 break;
512 case PDTA_FreeSourceBitMap:
513 DGS(bug("picture.datatype/OM_GET: Tag PDTA_FreeSourceBitMap: 0x%lx\n", (long)pd->FreeSource));
514 *(msg->opg_Storage)=(IPTR) pd->FreeSource;
515 break;
517 case PDTA_UseFriendBitMap:
518 DGS(bug("picture.datatype/OM_GET: Tag PDTA_UseFriendBitMap: 0x%lx\n", (long)pd->UseFriendBM));
519 *(msg->opg_Storage)=(IPTR) pd->UseFriendBM;
520 break;
522 case PDTA_MaxDitherPens:
523 DGS(bug("picture.datatype/OM_GET: Tag PDTA_MaxDitherPens: 0x%lx\n", (long)pd->MaxDitherPens));
524 *(msg->opg_Storage)=(IPTR) pd->MaxDitherPens;
525 break;
527 case PDTA_DitherQuality:
528 DGS(bug("picture.datatype/OM_GET: Tag PDTA_DitherQuality: 0x%lx\n", (long)pd->DitherQuality));
529 *(msg->opg_Storage)=(IPTR) pd->DitherQuality;
530 break;
532 case PDTA_ScaleQuality:
533 DGS(bug("picture.datatype/OM_GET: Tag PDTA_ScaleQuality: 0x%lx\n", (long)pd->ScaleQuality));
534 *(msg->opg_Storage)=(IPTR) pd->ScaleQuality;
535 break;
537 #ifdef __AROS__
538 case PDTA_DelayedRead:
539 DGS(bug("picture.datatype/OM_GET: Tag PDTA_DelayedRead: 0x%lx\n", (long)pd->DelayedRead));
540 *(msg->opg_Storage)=(IPTR) pd->DelayedRead;
541 break;
542 #endif
544 case DTA_Methods:
545 DGS(bug("picture.datatype/OM_GET: Tag DTA_Methods: 0x%lx\n", (long)SupportedMethods));
546 *(msg->opg_Storage)=(IPTR) SupportedMethods;
547 break;
549 default:
552 #ifdef MYDEBUG
553 register int i;
554 int Known;
556 Known=FALSE;
558 for(i=0; i<NumAttribs; i++)
560 if(msg->opg_AttrID==KnownAttribs[i])
562 Known=TRUE;
564 DGS(bug("picture.datatype/OM_GET: Tag ID: %s\n", AttribNames[i]));
568 if(!Known)
570 DGS(bug("picture.datatype/OM_GET: Tag ID: 0x%lx\n", msg->opg_AttrID));
572 #endif /* MYDEBUG */
574 return(DoSuperMethodA(cl, (Object *) g, (Msg) msg));
576 } /* switch AttrID */
578 return TRUE;
580 /**************************************************************************************************/
581 static void render_on_rastport(struct Picture_Data *pd, struct Gadget *g, LONG SrcX, LONG SrcY, struct RastPort * destRP,
582 LONG DestX, LONG DestY, LONG SizeX, LONG SizeY)
584 ULONG depth;
585 struct BitMapHeader * bmhd;
587 depth = (ULONG) GetBitMapAttr(destRP->BitMap, BMA_DEPTH);
588 GetDTAttrs((Object *) g, PDTA_BitMapHeader, (IPTR)&bmhd, TAG_DONE);
590 if ((depth >= 15) && (bmhd->bmh_Masking == mskHasAlpha))
592 /* Transparency on high color rast port with alpha channel in picture */
593 struct RastPort srcRP;
594 ULONG * img = (ULONG *) AllocVec(SizeX * SizeY * 4, MEMF_ANY);
595 if (img)
597 InitRastPort(&srcRP);
598 srcRP.BitMap = pd->DestBM;
600 ReadPixelArray(img, 0, 0, SizeX * 4, &srcRP, SrcX, SrcY, SizeX, SizeY, RECTFMT_ARGB);
602 WritePixelArrayAlpha(img, 0, 0, SizeX * 4, destRP, DestX, DestY, SizeX, SizeY, 0xffffffff);
603 FreeVec((APTR) img);
606 else
608 if ((bmhd->bmh_Masking == mskHasMask) || (bmhd->bmh_Masking == mskHasTransparentColor))
610 /* Transparency with mask */
611 APTR mask = NULL;
613 GetDTAttrs((Object *) g, PDTA_MaskPlane, (IPTR)&mask, TAG_DONE);
615 if (mask)
616 BltMaskBitMapRastPort(pd->DestBM,
617 SrcX,
618 SrcY,
619 destRP,
620 DestX,
621 DestY,
622 SizeX,
623 SizeY,
624 0xE0,
625 (PLANEPTR)mask);
627 else
629 /* All other cases */
630 BltBitMapRastPort( pd->DestBM,
631 SrcX,
632 SrcY,
633 destRP,
634 DestX,
635 DestY,
636 SizeX,
637 SizeY,
638 0xC0);
643 /**************************************************************************************************/
645 STATIC IPTR DT_Render(struct IClass *cl, struct Gadget *g, struct gpRender *msg)
647 struct Picture_Data *pd;
648 struct DTSpecialInfo *si;
650 struct IBox *domain;
651 IPTR TopVert, TopHoriz;
653 long SrcX, SrcY, DestX, DestY, SizeX, SizeY;
655 pd = (struct Picture_Data *) INST_DATA(cl, g);
656 si = (struct DTSpecialInfo *) g->SpecialInfo;
658 if(!pd->Layouted)
660 D(bug("picture.datatype/GM_RENDER: No layout done yet !\n"));
661 return FALSE;
664 if(si->si_Flags & DTSIF_LAYOUT)
666 D(bug("picture.datatype/GM_RENDER: In layout process !\n"));
667 return FALSE;
670 if(!(GetDTAttrs((Object *) g, DTA_Domain, (IPTR) &domain,
671 DTA_TopHoriz, (IPTR) &TopHoriz,
672 DTA_TopVert, (IPTR) &TopVert,
673 TAG_DONE) == 3))
675 D(bug("picture.datatype/GM_RENDER: Couldn't get dimensions\n"));
676 return FALSE;
679 ObtainSemaphore(&(si->si_Lock));
680 D(bug("picture.datatype/GM_RENDER: Domain: left %ld top %ld width %ld height %ld\n", domain->Left, domain->Top, domain->Width, domain->Height));
681 D(bug("picture.datatype/GM_RENDER: TopHoriz %ld TopVert %ld Width %ld Height %ld\n", (long)TopHoriz, (long)TopVert, (long)pd->DestWidth, (long)pd->DestHeight));
683 if( pd->DestBM )
685 SrcX = MIN( TopHoriz, pd->DestWidth );
686 SrcY = MIN( TopVert, pd->DestHeight );
687 DestX = domain->Left;
688 DestY = domain->Top;
689 SizeX = MIN( pd->DestWidth - SrcX, domain->Width );
690 SizeY = MIN( pd->DestHeight - SrcY, domain->Height );
691 D(bug("picture.datatype/GM_RENDER: SizeX/Y %ld/%ld\n SrcX/Y %ld/%ld DestX/Y %ld/%ld\n",
692 SizeX, SizeY, SrcX, SrcY, DestX, DestY));
694 render_on_rastport(pd, g, SrcX, SrcY, msg->gpr_RPort, DestX, DestY, SizeX, SizeY);
696 else
698 D(bug("picture.datatype/GM_RENDER: No destination picture present !\n"));
699 return FALSE;
701 ReleaseSemaphore(&(si->si_Lock));
703 return TRUE;
706 /**************************************************************************************************/
708 STATIC IPTR DT_GoActiveMethod(struct IClass *cl, struct Gadget *g, struct gpInput *msg)
710 struct DTSpecialInfo *dtsi = (struct DTSpecialInfo *)g->SpecialInfo;
711 struct Picture_Data *pd = INST_DATA(cl, g);
712 IPTR retval = GMR_NOREUSE;
714 if (!AttemptSemaphore(&dtsi->si_Lock))
716 return GMR_NOREUSE;
719 if (dtsi->si_Flags & DTSIF_DRAGSELECT)
721 ReleaseSemaphore(&dtsi->si_Lock);
723 return DoSuperMethodA(cl, (Object *)g, (Msg)msg);
725 else if (msg->gpi_IEvent && !(dtsi->si_Flags & DTSIF_LAYOUT))
727 IPTR toph, topv;
729 GetDTAttrs((Object *)g, DTA_TopVert, (IPTR)&topv,
730 DTA_TopHoriz, (IPTR)&toph,
731 TAG_DONE);
733 pd->ClickX = msg->gpi_Mouse.X + (LONG)toph;
734 pd->ClickY = msg->gpi_Mouse.Y + (LONG)topv;
736 retval = GMR_MEACTIVE;
739 ReleaseSemaphore(&dtsi->si_Lock);
741 return retval;
744 STATIC IPTR DT_HandleInputMethod(struct IClass *cl, struct Gadget *g, struct gpInput *msg)
746 struct DTSpecialInfo *dtsi = (struct DTSpecialInfo *)g->SpecialInfo;
747 struct Picture_Data *pd = INST_DATA(cl, g);
748 IPTR retval = GMR_MEACTIVE;
750 if (!AttemptSemaphore(&dtsi->si_Lock))
752 return GMR_NOREUSE;
755 if (dtsi->si_Flags & DTSIF_DRAGSELECT)
757 ReleaseSemaphore(&dtsi->si_Lock);
758 return DoSuperMethodA(cl, (Object *)g, (Msg)msg);
761 if (dtsi->si_Flags & DTSIF_LAYOUT)
763 ReleaseSemaphore(&dtsi->si_Lock);
764 return GMR_NOREUSE;
767 switch(msg->gpi_IEvent->ie_Class)
769 case IECLASS_RAWMOUSE:
770 switch(msg->gpi_IEvent->ie_Code)
772 case SELECTUP:
773 retval = GMR_NOREUSE;
774 break;
776 case IECODE_NOBUTTON:
778 IPTR toph, totalh, visibleh;
779 IPTR topv, totalv, visiblev;
780 LONG newtoph, newtopv;
782 GetDTAttrs((Object *)g, DTA_TopVert , (IPTR) &topv,
783 DTA_TotalVert , (IPTR) &totalv,
784 DTA_VisibleVert , (IPTR) &visiblev,
785 DTA_TopHoriz , (IPTR) &toph,
786 DTA_TotalHoriz , (IPTR) &totalh,
787 DTA_VisibleHoriz, (IPTR) &visibleh,
788 TAG_DONE);
790 newtoph = pd->ClickX - msg->gpi_Mouse.X;
791 newtopv = pd->ClickY - msg->gpi_Mouse.Y;
793 if (newtoph + (LONG)visibleh > (LONG)totalh) newtoph = (LONG)totalh - (LONG)visibleh;
794 if (newtoph < 0) newtoph = 0;
796 if (newtopv + (LONG)visiblev > (LONG)totalv) newtopv = (LONG)totalv - (LONG)visiblev;
797 if (newtopv < 0) newtopv = 0;
799 if ((newtoph != (LONG)toph) || (newtopv != (LONG)topv))
801 NotifyAttrChanges((Object *) g, msg->gpi_GInfo, 0,
802 GA_ID, g->GadgetID,
803 DTA_TopHoriz, newtoph,
804 DTA_TopVert, newtopv,
805 TAG_DONE);
808 break;
812 break;
815 ReleaseSemaphore(&dtsi->si_Lock);
817 return retval;
820 /**************************************************************************************************/
822 STATIC IPTR DT_Layout(struct IClass *cl, struct Gadget *g, struct gpLayout *msg)
824 IPTR RetVal;
826 D(bug("picture.datatype/GM_LAYOUT: Initial %d\n", (int)msg->gpl_Initial));
827 NotifyAttrChanges((Object *) g, msg->gpl_GInfo, 0,
828 GA_ID, g->GadgetID,
829 DTA_Busy, TRUE,
830 TAG_DONE);
832 RetVal=DoSuperMethodA(cl, (Object *) g, (Msg) msg);
834 RetVal += (IPTR) DoAsyncLayout((Object *) g, msg);
836 return(RetVal);
839 /**************************************************************************************************/
841 STATIC IPTR DT_AsyncLayout(struct IClass *cl, struct Gadget *g, struct gpLayout *msg)
843 struct Picture_Data *pd;
844 struct DTSpecialInfo *si;
845 ULONG SrcWidth, SrcHeight;
846 unsigned int SrcDepth;
847 BOOL success;
849 pd = (struct Picture_Data *) INST_DATA(cl, g);
850 si = (struct DTSpecialInfo *) g->SpecialInfo;
852 SrcWidth = pd->bmhd.bmh_Width;
853 SrcHeight = pd->bmhd.bmh_Height;
854 SrcDepth = pd->bmhd.bmh_Depth;
855 D(bug("picture.datatype/DTM_ASYNCLAYOUT: Source Width %ld Height %ld Depth %ld\n", SrcWidth, SrcHeight, (long)SrcDepth));
856 D(bug("picture.datatype/DTM_ASYNCLAYOUT: Masking %d Transparent %d Initial %d Layouted %d\n", (int)pd->bmhd.bmh_Masking, (int)pd->bmhd.bmh_Transparent, (int)msg->gpl_Initial, (int)pd->Layouted));
858 if( !SrcWidth || !SrcHeight || !SrcDepth )
860 D(bug("picture.datatype/DTM_ASYNCLAYOUT: Neccessary fields in BitMapHeader not set !\n"));
861 return FALSE;
864 if( !pd->SrcBuffer && !pd->SrcBM )
866 D(bug("picture.datatype/DTM_ASYNCLAYOUT: No source picture given !\n"));
867 return FALSE;
870 ObtainSemaphore( &(si->si_Lock) ); /* lock object data */
872 success = TRUE;
873 if( msg->gpl_Initial | !pd->Layouted ) /* we need to do it just once at startup or after scaling */
875 FreeDest( pd );
876 if( pd->Remap )
878 /* determine destination screen depth */
879 if( !pd->DestScreen && msg->gpl_GInfo )
881 pd->DestScreen = msg->gpl_GInfo->gi_Screen;
883 if( !pd->DestScreen )
885 D(bug("picture.datatype/DTM_ASYNCLAYOUT: No screen given !\n"));
886 ReleaseSemaphore(&si->si_Lock); /* unlock object data */
887 return FALSE;
889 pd->DestDepth = GetBitMapAttr( pd->DestScreen->RastPort.BitMap, BMA_DEPTH );
891 else
893 #if 0 // stegerg: CHECKME
894 if( pd->SrcDepth > 8 )
896 D(bug("picture.datatype/DTM_ASYNCLAYOUT: Remap=FALSE option only for colormapped source !\n"));
897 ReleaseSemaphore(&si->si_Lock); /* unlock object data */
898 return FALSE;
900 #endif
901 if( pd->Scale )
903 D(bug("picture.datatype/DTM_ASYNCLAYOUT: Scaling doesn't work with Remap=FALSE !\n"));
904 ReleaseSemaphore(&si->si_Lock); /* unlock object data */
905 return FALSE;
907 #if 0 // stegerg: CHECKME
908 pd->DestScreen = NULL;
909 #endif
910 pd->DestDepth = SrcDepth;
913 if( pd->DestDepth > 8 )
915 pd->TrueColorDest = TRUE;
916 if( !pd->DestMode )
918 D(bug("picture.datatype/DTM_ASYNCLAYOUT: Forcing colormapped dest depth of 8 instead of %ld\n", (long)pd->DestDepth));
919 pd->DestDepth = 8;
920 pd->TrueColorDest = FALSE;
923 else
925 pd->TrueColorDest = FALSE;
928 /* allocate destination Bitmap */
929 FreeDest( pd );
930 if( !pd->Scale )
932 pd->DestWidth = SrcWidth;
933 pd->DestHeight = SrcHeight;
935 D(bug("picture.datatype/DTM_ASYNCLAYOUT: Destination Width %ld Height %ld Depth %ld\n", pd->DestWidth, pd->DestHeight, (long)pd->DestDepth));
936 if( !AllocDestBM( pd ) )
938 D(bug("picture.datatype/DTM_ASYNCLAYOUT: Didn't get dest BM !\n"));
939 ReleaseSemaphore(&si->si_Lock); /* unlock object data */
940 return FALSE;
943 /* remap picture depending on the source/dest color case */
944 if( pd->TrueColorSrc )
946 if( !pd->SrcBuffer )
948 D(bug("picture.datatype/DTM_ASYNCLAYOUT: Bitmap source only possible with up to 8 bits !\n"));
949 ReleaseSemaphore(&si->si_Lock); /* unlock object data */
950 return FALSE;
952 if( pd->TrueColorDest )
954 success = ConvertTC2TC( pd );
956 else
958 success = ConvertTC2CM( pd );
961 else /* if(pd->TrueColorSrc) */
963 if( !pd->SrcBuffer )
965 if( !ConvertBitmap2Chunky( pd ) )
967 ReleaseSemaphore(&si->si_Lock); /* unlock object data */
968 return FALSE;
971 if( pd->TrueColorDest )
973 success = ConvertCM2TC( pd );
975 else
977 success = ConvertCM2CM( pd );
979 } /* else(pd->TrueColorSrc) */
981 /* free source, if asked */
982 if( pd->FreeSource )
984 CreateMaskPlane( pd );
985 FreeSource( pd );
988 /* layout done */
989 pd->Layouted = TRUE;
990 D(bug("picture.datatype/DTM_ASYNCLAYOUT: Initial layout done\n"));
991 } /* if( msg->gpl_Initial | !pd->Layouted ) */
993 ReleaseSemaphore( &si->si_Lock ); /* unlock object data */
994 if( !success )
996 D(bug("picture.datatype/DTM_ASYNCLAYOUT: Layout failed during remapping !\n"));
997 return FALSE;
1001 struct IBox *domain;
1002 IPTR Width, Height;
1003 STRPTR Title;
1006 * get attributes
1008 if(!(GetDTAttrs((Object *) g, DTA_Domain, (IPTR) &domain,
1009 DTA_ObjName, (IPTR) &Title,
1010 DTA_NominalHoriz, (IPTR) &Width,
1011 DTA_NominalVert, (IPTR) &Height,
1012 TAG_DONE) == 4))
1014 return FALSE;
1017 #ifdef __AROS__
1018 si->si_VertUnit = 1;
1019 si->si_VisVert = domain->Height;
1020 si->si_TotVert = Height;
1022 si->si_HorizUnit = 1;
1023 si->si_VisHoriz = domain->Width;
1024 si->si_TotHoriz = Width;
1025 #endif
1027 NotifyAttrChanges((Object *) g, msg->gpl_GInfo, 0,
1028 GA_ID, g->GadgetID,
1030 DTA_VisibleVert, domain->Height,
1031 DTA_TotalVert, Height,
1032 DTA_NominalVert, Height,
1033 DTA_VertUnit, 1,
1035 DTA_VisibleHoriz, domain->Width,
1036 DTA_TotalHoriz, Width,
1037 DTA_NominalHoriz, Width,
1038 DTA_HorizUnit, 1,
1040 DTA_Title, (IPTR) Title,
1041 DTA_Busy, TRUE,
1042 DTA_Sync, TRUE,
1043 TAG_DONE);
1044 D(bug("picture.datatype/DTM_ASYNCLAYOUT: NotifyAttrChanges done, Layouted %d\n", (int)pd->Layouted));
1046 return TRUE;
1049 /**************************************************************************************************/
1051 STATIC IPTR DT_ProcLayout(struct IClass *cl, struct Gadget *g, struct gpLayout *msg)
1053 NotifyAttrChanges((Object *) g, msg->gpl_GInfo, 0,
1054 GA_ID, g->GadgetID,
1055 DTA_Busy, TRUE,
1056 TAG_DONE);
1058 DoSuperMethodA(cl, (Object *) g, (Msg) msg);
1060 return DT_AsyncLayout(cl, g, msg);
1063 /**************************************************************************************************/
1065 STATIC IPTR PDT_WritePixelArray(struct IClass *cl, struct Gadget *g, struct pdtBlitPixelArray *msg)
1067 struct Picture_Data *pd;
1069 int pixelformat;
1070 int pixelbytes;
1072 pd = (struct Picture_Data *) INST_DATA(cl, g);
1074 /* Do some checks first */
1075 pixelformat = (long)msg->pbpa_PixelFormat;
1076 if ( pixelformat != pd->SrcPixelFormat ) /* This also checks for pd->SrcBuffer */
1078 if( !pd->SrcBuffer )
1080 /* Initial call: Set new pixel format and allocate Chunky or RGB buffer */
1081 if( pd->SrcBM )
1083 D(bug("picture.datatype/DTM_WRITEPIXELARRAY: Not possible in bitmap mode !\n"));
1084 return FALSE;
1086 if( !pd->bmhd.bmh_Width || !pd->bmhd.bmh_Height || !pd->bmhd.bmh_Depth )
1088 D(bug("picture.datatype/DTM_WRITEPIXELARRAY: BitMapHeader not set !\n"));
1089 return FALSE;
1092 switch( pixelformat )
1094 case PBPAFMT_GREY8:
1095 InitGreyColTable( pd );
1096 pixelbytes = 1;
1097 break;
1098 case PBPAFMT_LUT8:
1099 pixelbytes = 1;
1100 break;
1101 case PBPAFMT_RGB:
1102 InitRGBColTable( pd );
1103 pixelbytes = 3;
1104 pd->TrueColorSrc = TRUE;
1105 break;
1106 case PBPAFMT_ARGB:
1107 InitRGBColTable( pd );
1108 pixelbytes = 4;
1109 pd->TrueColorSrc = TRUE;
1110 break;
1111 case PBPAFMT_RGBA:
1112 InitRGBColTable( pd );
1113 pixelbytes = 4;
1114 pd->TrueColorSrc = TRUE;
1115 break;
1116 default:
1117 D(bug("picture.datatype/DTM_WRITEPIXELARRAY: Unknown PixelFormat mode %d !\n", pixelformat));
1118 return FALSE;
1120 if( !AllocSrcBuffer( pd, pd->bmhd.bmh_Width, pd->bmhd.bmh_Height, pixelformat, pixelbytes ) )
1121 return FALSE;
1122 D(bug("picture.datatype/DTM_WRITEPIXELARRAY: Initialized SrcBuffer 0x%lx, PixelFormat %ld\n", (long)pd->SrcBuffer, pd->SrcPixelFormat));
1123 D(bug("picture.datatype/DTM_WRITEPIXELARRAY: Width %ld WidthBytes %ld Height %ld\n", pd->SrcWidth, pd->SrcWidthBytes, pd->SrcHeight));
1125 #if 0 /* fill chunky buffer with something colorful, works only with PBPAFMT_RGB */
1126 if( pixelformat == PBPAFMT_RGB )
1128 long x, y;
1129 long Width = pd->SrcWidth;
1130 long WidthBytes = pd->SrcWidthBytes;
1131 long Height = pd->SrcHeight;
1133 for (y=0; y<Height; y++)
1135 for (x=0; x<Width; x++)
1137 pd->SrcBuffer[x*pixelbytes+y*WidthBytes+0] = x*256/Width;
1138 pd->SrcBuffer[x*pixelbytes+y*WidthBytes+1] = y*256/Height;
1139 pd->SrcBuffer[x*pixelbytes+y*WidthBytes+2] =
1140 ( (Width-x)*256/Width + (Height-y)*256/Height )/2;
1144 #endif
1147 else /* if(!pd->SrcBuffer) */
1149 D(bug("picture.datatype/DTM_WRITEPIXELARRAY: PixelFormat mismatch !\n"));
1150 return FALSE;
1152 } /* if(pixelformat != pd->SrcPixelFormat) */
1154 /* Copy picture data */
1156 LONG line, lines;
1157 STRPTR srcstart;
1158 STRPTR deststart;
1159 ULONG srcwidth, numbytes;
1160 ULONG srcmod, destmod;
1162 /* Now copy the new source data to the ChunkyBuffer line by line */
1163 pixelbytes = pd->SrcPixelBytes;
1164 srcmod = msg->pbpa_PixelArrayMod;
1165 srcstart = msg->pbpa_PixelData;
1166 srcwidth = msg->pbpa_Width;
1167 destmod = pd->SrcWidthBytes;
1168 deststart = pd->SrcBuffer + msg->pbpa_Left * pixelbytes + msg->pbpa_Top * destmod;
1169 lines = msg->pbpa_Height;
1170 numbytes = srcwidth * pixelbytes;
1171 /* simply copy data */
1172 for( line=0; line<lines; line++ )
1174 // D(bug("picture.datatype/DTM_WRITEPIXELARRAY: COPY src 0x%lx dest 0x%lx bytes %ld\n", (long)srcstart, (long)deststart, numbytes));
1175 CopyMem((APTR) srcstart, (APTR) deststart, numbytes);
1176 srcstart += srcmod;
1177 deststart += destmod;
1181 pd->Layouted = FALSE; /* re-layout required */
1182 return TRUE;
1185 /**************************************************************************************************/
1187 STATIC IPTR PDT_ReadPixelArray(struct IClass *cl, struct Gadget *g, struct pdtBlitPixelArray *msg)
1189 struct Picture_Data *pd;
1191 int pixelformat;
1192 int pixelbytes;
1194 pd = (struct Picture_Data *) INST_DATA(cl, g);
1196 /* Do some checks first */
1197 if (!pd->DestMode)
1199 D(bug("picture.datatype/DTM_READPIXELARRAY: Wrong DestMode\n"));
1200 return FALSE;
1203 if( !pd->SrcBuffer)
1205 ConvertBitmap2Chunky(pd);
1208 if (!pd->SrcBuffer)
1210 D(bug("picture.datatype/DTM_READPIXELARRAY: No source buffer\n"));
1211 return FALSE;
1213 pixelformat = (long)msg->pbpa_PixelFormat;
1214 D(bug("picture.datatype/DTM_READPIXELARRAY: Source/Dest Pixelformat %d / %ld\n", pixelformat, pd->SrcPixelFormat));
1216 if ( pixelformat == pd->SrcPixelFormat )
1218 /* Copy picture data, as source pixmode = dest pixmode */
1219 long line, lines;
1220 STRPTR srcstart;
1221 STRPTR deststart;
1222 long srcmod, destmod;
1223 long destwidth, numbytes;
1225 /* Now copy the new source data to the ChunkyBuffer line by line */
1226 pixelbytes = pd->SrcPixelBytes;
1227 srcmod = pd->SrcWidthBytes;
1228 srcstart = pd->SrcBuffer + msg->pbpa_Left * pixelbytes + msg->pbpa_Top * srcmod;
1229 destmod = msg->pbpa_PixelArrayMod;
1230 deststart = msg->pbpa_PixelData;
1231 destwidth = msg->pbpa_Width;
1232 lines = msg->pbpa_Height;
1233 numbytes = destwidth * pixelbytes;
1235 /* simply copy data */
1236 for( line=0; line<lines; line++ )
1238 // D(bug("picture.datatype/DTM_READPIXELARRAY: COPY src 0x%lx dest 0x%lx bytes %ld\n", (long)srcstart, (long)deststart, numbytes));
1239 CopyMem((APTR) srcstart, (APTR) deststart, numbytes);
1240 srcstart += srcmod;
1241 deststart += destmod;
1244 else if ( pixelformat == PBPAFMT_RGB || pixelformat == PBPAFMT_RGBA || pixelformat == PBPAFMT_ARGB )
1246 /* Copy picture data pixel by pixel (this is not fast, but compatible :-) */
1247 UBYTE r=0, g=0, b=0, a=0xff;
1248 long line, x, col;
1249 int srcpixelformat;
1250 STRPTR srcstart;
1251 UBYTE *srcptr;
1252 STRPTR deststart;
1253 UBYTE *destptr;
1254 long srcmod, destmod;
1255 ULONG * colregs;
1257 /* Now copy the new source data to the ChunkyBuffer line by line */
1258 srcpixelformat = pd->SrcPixelFormat;
1259 srcmod = pd->SrcWidthBytes;
1260 srcstart = pd->SrcBuffer + msg->pbpa_Left * pd->SrcPixelBytes + msg->pbpa_Top * srcmod;
1261 destmod = msg->pbpa_PixelArrayMod;
1262 deststart = msg->pbpa_PixelData;
1263 colregs = pd->SrcColRegs;
1265 for( line=0; line<msg->pbpa_Height; line++ )
1267 srcptr = srcstart;
1268 destptr = deststart;
1269 for( x=0; x<pd->SrcWidth; x++ )
1271 switch( srcpixelformat )
1273 case PBPAFMT_GREY8:
1274 case PBPAFMT_LUT8:
1275 col = 3 * (*srcptr++);
1276 r = colregs[col++] >> 24;
1277 g = colregs[col++] >> 24;
1278 b = colregs[col] >> 24;
1279 break;
1280 case PBPAFMT_ARGB:
1281 a = *srcptr++;
1282 case PBPAFMT_RGB:
1283 r = *srcptr++;
1284 g = *srcptr++;
1285 b = *srcptr++;
1286 break;
1287 case PBPAFMT_RGBA:
1288 r = *srcptr++;
1289 g = *srcptr++;
1290 b = *srcptr++;
1291 a = *srcptr++;
1292 break;
1294 if( pixelformat == PBPAFMT_ARGB )
1295 *destptr++ = a;
1296 *destptr++ = r;
1297 *destptr++ = g;
1298 *destptr++ = b;
1299 if( pixelformat == PBPAFMT_RGBA )
1300 *destptr++ = a;
1302 srcstart += srcmod;
1303 deststart += destmod;
1306 else
1308 D(bug("picture.datatype/DTM_READPIXELARRAY: Source/Dest Pixelformat mismatch (not yet supported)\n"));
1309 return FALSE;
1311 return TRUE;
1314 /**************************************************************************************************/
1316 STATIC IPTR PDT_Scale(struct IClass *cl, struct Gadget *g, struct pdtScale *msg)
1318 struct Picture_Data *pd;
1319 ULONG xscale, yscale;
1320 struct DTSpecialInfo *si;
1322 pd = (struct Picture_Data *) INST_DATA(cl, g);
1323 si = (struct DTSpecialInfo *) g->SpecialInfo;
1325 ObtainSemaphore( &(si->si_Lock) ); /* lock object data */
1326 D(bug("picture.datatype/PDTM_SCALE: newwidth %ld newheight %ld flags %08lx\n", msg->ps_NewWidth, msg->ps_NewHeight, msg->ps_Flags));
1328 pd->DestWidth = msg->ps_NewWidth;
1329 pd->DestHeight = msg->ps_NewHeight;
1331 /* FIXME: PDT_Scale() set bmh_Width/bmh_Height to new size yes or no? */
1332 pd->bmhd.bmh_Width = msg->ps_NewWidth;
1333 pd->bmhd.bmh_Height = msg->ps_NewHeight;
1335 if( pd->SrcWidth == pd->DestWidth && pd->SrcHeight == pd->DestHeight )
1336 pd->Scale = FALSE;
1337 else
1338 pd->Scale = TRUE;
1340 xscale = (pd->SrcWidth << 16) / pd->DestWidth;
1341 yscale = (pd->SrcHeight << 16) / pd->DestHeight;
1342 #ifdef __AROS__
1343 if( msg->ps_Flags & PScale_KeepAspect )
1345 xscale = yscale = MAX(xscale, yscale);
1346 pd->DestWidth = (pd->SrcWidth << 16) / xscale;
1347 pd->DestHeight = (pd->SrcHeight << 16) / yscale;
1349 #endif
1350 pd->XScale = xscale;
1351 pd->YScale = yscale;
1352 D(bug("picture.datatype/PDTM_SCALE: srcwidth %ld srcheight %ld destwidth %ld destheight %ld xscale %06lx yscale %06lx\n", pd->SrcWidth, pd->SrcHeight, pd->DestWidth, pd->DestHeight, pd->XScale, pd->YScale));
1354 SetDTAttrs((Object *) g, NULL, NULL,
1355 DTA_NominalHoriz, pd->DestWidth,
1356 DTA_NominalVert , pd->DestHeight,
1357 TAG_DONE);
1358 pd->Layouted = FALSE; /* re-layout required */
1360 ReleaseSemaphore( &si->si_Lock ); /* unlock object data */
1361 return TRUE;
1364 /**************************************************************************************************/
1366 STATIC IPTR DT_FrameBox(struct IClass *cl, struct Gadget *g, struct dtFrameBox *msg)
1368 struct Picture_Data *pd;
1369 ULONG Width, Height, Depth;
1370 IPTR RetVal;
1372 pd=(struct Picture_Data *) INST_DATA(cl, g);
1374 RetVal=0;
1376 Width=pd->bmhd.bmh_Width;
1377 Height=pd->bmhd.bmh_Height;
1378 Depth=pd->bmhd.bmh_Depth;
1380 D(bug("picture.datatype/DTM_FRAMEBOX: Width %ld\n", (long) Width));
1381 D(bug("picture.datatype/DTM_FRAMEBOX: Height %ld\n", (long) Height));
1382 D(bug("picture.datatype/DTM_FRAMEBOX: Depth %ld\n", (long) Depth));
1384 /* FIXME: DT_FrameBox implementation may need to be checked */
1386 /* It is not really clear/documented what's the correct thing to do
1387 here. And what effect FRAMEF_SPECIFY has *here*. The demo sources on
1388 the Amiga Dev CD 2.1 are conflicting.
1390 ClipView source on Amiga Dev CD 2.1 uses ContentsInfo and FRAMEF_SPECIFY
1391 and (!) uninitialized FrameInfo. So accessing FrameInfo here would crash.
1393 Most other sources on the Dev CD set both ContentsInfo and FrameInfo
1394 to the same struct. Without using FRAMEF_SPECIFY.
1396 Another source (Reference/Amiga_Mail_Vol2/IV-101/dtpic.c) uses FrameInfo
1397 and NULLs ContentsInfo and no FRAMEF_SPECIFY. */
1399 #if 1
1400 if(msg->dtf_ContentsInfo)
1402 msg->dtf_ContentsInfo->fri_Dimensions.Height = Height;
1403 msg->dtf_ContentsInfo->fri_Dimensions.Width = Width;
1404 msg->dtf_ContentsInfo->fri_Dimensions.Depth = Depth;
1405 msg->dtf_ContentsInfo->fri_Flags = FIF_SCROLLABLE;
1407 RetVal = 1;
1409 #else
1410 if(msg->dtf_FrameInfo)
1412 msg->dtf_FrameInfo->fri_Dimensions.Height = Height;
1413 msg->dtf_FrameInfo->fri_Dimensions.Width = Width;
1414 msg->dtf_FrameInfo->fri_Dimensions.Depth = Depth;
1415 msg->dtf_FrameInfo->fri_Flags = FIF_SCROLLABLE;
1417 RetVal = 1;
1419 #endif
1421 return(RetVal);
1424 /**************************************************************************************************/
1426 STATIC IPTR DT_ObtainDrawInfo(struct IClass *cl, struct Gadget *g, struct opSet *msg)
1428 struct Picture_Data *pd;
1429 IPTR RetVal;
1431 pd = (struct Picture_Data *) INST_DATA(cl, g);
1433 RetVal = FALSE;
1435 if( !pd->UseAsImage )
1437 RetVal = DoMethod( (Object *)g, DTM_PROCLAYOUT, (IPTR) NULL, 1L );
1438 if( RetVal )
1440 pd->UseAsImage = TRUE;
1441 D(bug("picture.datatype/DTM_OBTAINDRAWINFO: Switched to image mode\n"));
1445 return RetVal;
1448 /**************************************************************************************************/
1450 STATIC IPTR DT_Draw(struct IClass *cl, struct Gadget *g, struct dtDraw *msg)
1452 struct Picture_Data *pd;
1453 IPTR RetVal;
1455 pd=(struct Picture_Data *) INST_DATA(cl, g);
1457 RetVal = FALSE;
1459 if( pd->UseAsImage && pd->DestBM )
1461 long SrcX, SrcY, DestX, DestY, SizeX, SizeY;
1463 SrcX = MIN( msg->dtd_TopHoriz, pd->DestWidth );
1464 SrcY = MIN( msg->dtd_TopVert, pd->DestHeight );
1465 DestX = msg->dtd_Left;
1466 DestY = msg->dtd_Top;
1467 SizeX = MIN( pd->DestWidth - SrcX, msg->dtd_Width );
1468 SizeY = MIN( pd->DestHeight - SrcY, msg->dtd_Height );
1469 D(bug("picture.datatype/DTM_DRAW: SizeX/Y %ld/%ld SrcX/Y %ld/%ld DestX/Y %ld/%ld\n",
1470 SizeX, SizeY, SrcX, SrcY, DestX, DestY));
1472 render_on_rastport(pd, g, SrcX, SrcY, msg->dtd_RPort, DestX, DestY, SizeX, SizeY);
1473 D(bug("picture.datatype/DTM_DRAW: Switched to image mode\n"));
1474 RetVal = TRUE;
1477 return RetVal;
1480 /**************************************************************************************************/
1482 STATIC IPTR DT_Print(struct IClass *cl, Object *o, struct dtPrint *msg)
1484 IPTR RetVal;
1485 struct IODRPReq *pio = &msg->dtp_PIO->iodrp;
1486 struct RastPort *rp = NULL;
1487 struct TagItem *tag, *tags = msg->dtp_AttrList;
1488 IPTR w = 0, h = 0, th = 0, tw = 0;
1489 struct GadgetInfo *gi = msg->dtp_GInfo;
1491 GetDTAttrs(o, DTA_NominalHoriz, &w, DTA_NominalVert, &h);
1492 GetDTAttrs(o, DTA_TopHoriz, &tw, DTA_TopVert, &th);
1494 if (w == 0 || h == 0)
1495 return 0;
1497 RetVal = PDERR_CANCEL;
1499 pio->io_Command = PRD_DUMPRPORT;
1500 pio->io_SrcX = 0;
1501 pio->io_SrcY = 0;
1502 pio->io_SrcWidth = w;
1503 pio->io_SrcHeight = h;
1504 pio->io_DestCols = 0;
1505 pio->io_DestRows = 0;
1506 pio->io_Special = 0;
1508 while ((tag = NextTagItem(&tags))) {
1509 switch (tag->ti_Tag) {
1510 case DTA_DestCols: pio->io_DestCols = (LONG)tag->ti_Data; break;
1511 case DTA_DestRows: pio->io_DestRows = (LONG)tag->ti_Data; break;
1512 case DTA_RastPort: rp = (struct RastPort *)tag->ti_Data; break;
1513 case DTA_Special: pio->io_Special = (UWORD)tag->ti_Data; break;
1514 default: break;
1517 tags = msg->dtp_AttrList;
1519 if (rp) {
1520 /* Print from supplied (non colormap) rastport */
1521 pio->io_RastPort = rp;
1522 pio->io_ColorMap = NULL;
1523 pio->io_Modes = INVALID_ID;
1524 RetVal = DoIO((struct IORequest *)pio);
1525 } else if (gi) {
1526 /* Print as Gadget */
1527 struct Screen *s;
1529 if ((s = gi->gi_Screen)) {
1530 if ((pio->io_Modes = GetVPModeID(&s->ViewPort)) != INVALID_ID) {
1531 pio->io_ColorMap = s->ViewPort.ColorMap;
1532 if ((pio->io_RastPort = ObtainGIRPort(gi))) {
1533 RetVal = DoIO((struct IORequest *)pio);
1534 ReleaseGIRPort(pio->io_RastPort);
1538 } else {
1539 /* Print as a 24-bit color image */
1540 struct RastPort baseRP;
1541 struct BitMap *bm;
1543 rp = &baseRP;
1545 pio->io_ColorMap = NULL;
1546 pio->io_Modes = INVALID_ID;
1547 pio->io_RastPort = rp;
1548 InitRastPort(rp);
1549 /* Maybe we should do strip printing to save memory?
1551 * Too bad native AOS's PostScript driver doesn't
1552 * support that.
1554 * Well, if 24 bit color fails, try 12 bit (4096 color),
1555 * and if that fails, just do black & white.
1557 if ((bm = AllocBitMap(w, h, 24, 0, NULL)) ||
1558 (bm = AllocBitMap(w, h, 12, 0, NULL)) ||
1559 (bm = AllocBitMap(w, h, 1, 0, NULL))) {
1560 struct Layer_Info *li;
1561 rp->BitMap = bm;
1562 if ((li = NewLayerInfo())) {
1563 struct Layer *layer;
1564 if ((layer = CreateUpfrontLayer(li, bm, 0, 0, w, h, 0, NULL))) {
1565 APTR drawInfo;
1566 rp->Layer = layer;
1567 if ((drawInfo = ObtainDTDrawInfo(o, tags))) {
1568 if (DrawDTObject(rp, o, 0, 0, w, h, th, tw, tags)) {
1569 RetVal = DoIO((struct IORequest *)pio);
1571 ReleaseDTDrawInfo(o, drawInfo);
1573 DeleteLayer(0, layer);
1575 DisposeLayerInfo(li);
1577 FreeBitMap(bm);
1581 return RetVal;
1584 /**************************************************************************************************/
1586 STATIC IPTR DT_ReleaseDrawInfo(struct IClass *cl, struct Gadget *g, struct dtReleaseDrawInfo *msg)
1588 struct Picture_Data *pd;
1589 IPTR RetVal;
1591 pd = (struct Picture_Data *) INST_DATA(cl, g);
1593 RetVal = FALSE;
1595 if( pd->UseAsImage )
1597 pd->UseAsImage = FALSE;
1598 RetVal = TRUE;
1601 return RetVal;
1604 /**************************************************************************************************/
1606 #ifndef __AROS__
1607 ASM ULONG DT_Dispatcher(register __a0 struct IClass *cl, register __a2 Object *o, register __a1 Msg msg)
1609 IPTR RetVal;
1610 #ifdef MYDEBUG
1611 register int i;
1612 int Known;
1614 Known=FALSE;
1615 #endif /* MYDEBUG */
1617 putreg(REG_A4, (long) cl->cl_Dispatcher.h_SubEntry); /* Small Data */
1619 RetVal=(IPTR) 0;
1621 switch(msg->MethodID)
1623 case OM_NEW:
1625 D(bug("picture.datatype/DT_Dispatcher: Method OM_NEW\n"));
1626 RetVal=(IPTR) DT_NewMethod(cl, o, (struct opSet *) msg);
1627 break;
1630 case OM_GET:
1632 // DGS(bug("picture.datatype/DT_Dispatcher: Method OM_GET\n"));
1633 RetVal=(IPTR) DT_GetMethod(cl, (struct Gadget *) o, (struct opGet *) msg);
1634 break;
1637 case OM_SET:
1638 case OM_UPDATE:
1640 DGS(bug("picture.datatype/DT_Dispatcher: Method %s\n", (msg->MethodID==OM_UPDATE) ? "OM_UPDATE" : "OM_SET"));
1641 RetVal=(IPTR) DT_SetMethod(cl, (struct Gadget *) o, (struct opSet *) msg);
1642 break;
1645 case OM_DISPOSE:
1647 D(bug("picture.datatype/DT_Dispatcher: Method OM_DISPOSE\n"));
1648 RetVal=(IPTR) DT_DisposeMethod(cl, o, (Msg) msg);
1649 break;
1652 case GM_LAYOUT:
1654 D(bug("picture.datatype/DT_Dispatcher: Method GM_LAYOUT\n"));
1655 RetVal=(IPTR) DT_Layout(cl, (struct Gadget *) o, (struct gpLayout *) msg);
1656 break;
1659 case GM_GOACTIVE:
1661 D(bug("picture.datatype/DT_Dispatcher: Method GM_GOACTIVE\n"));
1662 RetVal = DT_GoActiveMethod(cl, (struct Gadget *)o, (struct gpInput *)msg);
1663 break;
1666 case GM_HANDLEINPUT:
1668 D(bug("picture.datatype/DT_Dispatcher: Method GM_HANDLEINPUT\n"));
1669 RetVal = DT_HandleInputMethod(cl, (struct Gadget *)o, (struct gpInput *)msg);
1670 break;
1673 case DTM_PROCLAYOUT:
1675 D(bug("picture.datatype/DT_Dispatcher: Method DTM_PROCLAYOUT\n"));
1676 RetVal=(IPTR) DT_ProcLayout(cl, (struct Gadget *) o, (struct gpLayout *) msg);
1677 break;
1680 case DTM_ASYNCLAYOUT:
1682 D(bug("picture.datatype/DT_Dispatcher: Method DTM_ASYNCLAYOUT\n"));
1683 RetVal=(IPTR) DT_AsyncLayout(cl, (struct Gadget *) o, (struct gpLayout *) msg);
1684 break;
1687 case GM_RENDER:
1689 D(bug("picture.datatype/DT_Dispatcher: Method GM_RENDER\n"));
1690 RetVal=(IPTR) DT_Render(cl, (struct Gadget *) o, (struct gpRender *) msg);
1691 break;
1694 case DTM_FRAMEBOX:
1696 D(bug("picture.datatype/DT_Dispatcher: Method DTM_FRAMEBOX\n"));
1697 RetVal=(IPTR) DT_FrameBox(cl, (struct Gadget *) o, (struct dtFrameBox *) msg);
1698 break;
1701 case DTM_OBTAINDRAWINFO:
1703 D(bug("picture.datatype/DT_Dispatcher: Method DTM_OBTAINDRAWINFO\n"));
1704 RetVal=(IPTR) DT_ObtainDrawInfo(cl, (struct Gadget *) o, (struct opSet *) msg);
1705 break;
1708 case DTM_PRINT:
1710 D(bug("picture.datatype/DT_Dispatcher: Method DTM_PRINT\n"));
1711 RetVal=(IPTR) DT_Print(cl, o, (struct dtPrint *) msg);
1712 break;
1715 case DTM_DRAW:
1717 D(bug("picture.datatype/DT_Dispatcher: Method DTM_DRAW\n"));
1718 RetVal=(IPTR) DT_Draw(cl, (struct Gadget *) o, (struct dtDraw *) msg);
1719 break;
1722 case DTM_RELEASEDRAWINFO:
1724 D(bug("picture.datatype/DT_Dispatcher: Method DTM_RELEASEDRAWINFO\n"));
1725 RetVal=(IPTR) DT_ReleaseDrawInfo(cl, (struct Gadget *) o, (struct dtReleaseDrawInfo *) msg);
1726 break;
1729 case PDTM_WRITEPIXELARRAY:
1731 // D(bug("picture.datatype/DT_Dispatcher: Method PDTM_WRITEPIXELARRAY\n"));
1732 RetVal=(IPTR) PDT_WritePixelArray(cl, (struct Gadget *) o, (struct pdtBlitPixelArray *) msg);
1733 break;
1736 case PDTM_READPIXELARRAY:
1738 // D(bug("picture.datatype/DT_Dispatcher: Method PDTM_READPIXELARRAY\n"));
1739 RetVal=(IPTR) PDT_ReadPixelArray(cl, (struct Gadget *) o, (struct pdtBlitPixelArray *) msg);
1740 break;
1743 case PDTM_SCALE:
1745 D(bug("picture.datatype/DT_Dispatcher: Method PDTM_SCALE\n"));
1746 RetVal=(IPTR) PDT_Scale(cl, (struct Gadget *) o, (struct pdtScale *) msg);
1747 break;
1750 default:
1752 #ifdef MYDEBUG
1753 for(i=0; i<NumMethods; i++)
1755 if(msg->MethodID==KnownMethods[i])
1757 Known=TRUE;
1759 D(bug("picture.datatype/DT_Dispatcher: Method %s\n", MethodNames[i]));
1763 if(!Known)
1765 D(bug("picture.datatype/DT_Dispatcher: Method 0x%lx\n", (unsigned long) msg->MethodID));
1767 #endif /* MYDEBUG */
1768 RetVal=DoSuperMethodA(cl, o, (Msg) msg);
1769 break;
1773 return(RetVal);
1776 /**************************************************************************************************/
1778 struct IClass *DT_MakeClass(struct Library *picturebase)
1780 struct IClass *cl = MakeClass("picture.datatype", DATATYPESCLASS, NULL, sizeof(struct Picture_Data), 0);
1782 if (cl)
1784 cl->cl_Dispatcher.h_Entry = (HOOKFUNC) DT_Dispatcher;
1785 cl->cl_Dispatcher.h_SubEntry = (HOOKFUNC) getreg(REG_A4);
1786 cl->cl_UserData = (IPTR) picturebase; /* Required by datatypes */
1789 return cl;
1791 #endif /* !__AROS__ */
1793 /**************************************************************************************************/