2 Copyright 2002-2007, The AROS Development Team.
13 #define DT_V44_SUPPORT
15 #include <datatypes/pictureclass.h>
17 #include <clib/alib_protos.h>
18 #include <proto/exec.h>
19 #include <proto/dos.h>
20 #include <proto/datatypes.h>
21 #include <proto/graphics.h>
22 #include <proto/intuition.h>
23 #include <proto/utility.h>
24 #include <proto/layers.h>
25 #include <proto/cybergraphics.h>
30 #include "muimaster_intern.h"
31 #include "datatypescache.h"
33 extern struct Library
*MUIMasterBase
;
35 static struct List dt_list
;
36 static int dt_initialized
;
39 /* A BltBitMaskPort() replacement which blits masks for interleaved bitmaps correctly */
42 STACKED
struct Layer
*layer
;
43 STACKED
struct Rectangle bounds
;
51 struct BitMap maskBitMap
;
52 struct BitMap
*srcBitMap
;
60 VOID
MyBltMaskBitMap( CONST
struct BitMap
*srcBitMap
, LONG xSrc
, LONG ySrc
, struct BitMap
*destBitMap
, LONG xDest
, LONG yDest
, LONG xSize
, LONG ySize
, struct BitMap
*maskBitMap
)
62 BltBitMap(srcBitMap
,xSrc
,ySrc
,destBitMap
, xDest
, yDest
, xSize
, ySize
, 0x99,~0,NULL
);
63 BltBitMap(maskBitMap
,xSrc
,ySrc
,destBitMap
, xDest
, yDest
, xSize
, ySize
, 0xe2,~0,NULL
);
64 BltBitMap(srcBitMap
,xSrc
,ySrc
,destBitMap
, xDest
, yDest
, xSize
, ySize
, 0x99,~0,NULL
);
68 ASM
void HookFunc_BltMask(REG(a0
, struct Hook
*hook
), REG(a1
,struct LayerHookMsg
*msg
), REG(a2
,struct RastPort
*rp
))
70 struct BltMaskHook
*h
= (struct BltMaskHook
*)hook
;
72 LONG width
= msg
->bounds
.MaxX
- msg
->bounds
.MinX
+1;
73 LONG height
= msg
->bounds
.MaxY
- msg
->bounds
.MinY
+1;
74 LONG offsetx
= h
->srcx
+ msg
->offsetx
- h
->destx
;
75 LONG offsety
= h
->srcy
+ msg
->offsety
- h
->desty
;
78 putreg(REG_A4
,(long)hook
->h_Data
);
81 MyBltMaskBitMap( h
->srcBitMap
, offsetx
, offsety
, rp
->BitMap
, msg
->bounds
.MinX
, msg
->bounds
.MinY
, width
, height
, &h
->maskBitMap
);
84 VOID
MyBltMaskBitMapRastPort( struct BitMap
*srcBitMap
, LONG xSrc
, LONG ySrc
, struct RastPort
*destRP
, LONG xDest
, LONG yDest
, LONG xSize
, LONG ySize
, ULONG minterm
, APTR bltMask
)
86 if (GetBitMapAttr(srcBitMap
,BMA_FLAGS
)&BMF_INTERLEAVED
)
88 LONG src_depth
= GetBitMapAttr(srcBitMap
,BMA_DEPTH
);
89 struct Rectangle rect
;
90 struct BltMaskHook hook
;
92 /* Define the destination rectangle in the rastport */
95 rect
.MaxX
= xDest
+ xSize
- 1;
96 rect
.MaxY
= yDest
+ ySize
- 1;
98 /* Initialize the hook */
99 hook
.hook
.h_Entry
= (HOOKFUNC
)HookFunc_BltMask
;
101 hook
.hook
.h_Data
= (void*)getreg(REG_A4
);
103 hook
.srcBitMap
= srcBitMap
;
109 /* Initialize a bitmap where all plane pointers points to the mask */
110 InitBitMap(&hook
.maskBitMap
,src_depth
,GetBitMapAttr(srcBitMap
,BMA_WIDTH
),GetBitMapAttr(srcBitMap
,BMA_HEIGHT
));
112 hook
.maskBitMap
.Planes
[--src_depth
] = bltMask
;
114 /* Blit onto the Rastport */
115 DoHookClipRects(&hook
.hook
,destRP
,&rect
);
118 BltMaskBitMapRastPort(srcBitMap
, xSrc
, ySrc
, destRP
, xDest
, yDest
, xSize
, ySize
, minterm
, bltMask
);
125 static Object
*LoadPicture(CONST_STRPTR filename
, struct Screen
*scr
)
129 struct Process
*myproc
= (struct Process
*)FindTask(NULL
);
130 APTR oldwindowptr
= myproc
->pr_WindowPtr
;
131 myproc
->pr_WindowPtr
= (APTR
)-1;
133 o
= NewDTObject((APTR
)filename
,
134 DTA_GroupID
, GID_PICTURE
,
135 OBP_Precision
, PRECISION_EXACT
,
136 PDTA_Screen
, (IPTR
)scr
,
137 PDTA_FreeSourceBitMap
, TRUE
,
138 PDTA_DestMode
, PMODE_V43
,
139 PDTA_UseFriendBitMap
, TRUE
,
142 myproc
->pr_WindowPtr
= oldwindowptr
;
143 D(bug("... picture=%lx\n", o
));
147 struct BitMapHeader
*bmhd
;
149 GetDTAttrs(o
,PDTA_BitMapHeader
, (IPTR
)&bmhd
, TAG_DONE
);
150 if (bmhd
->bmh_Masking
== mskHasAlpha
)
152 if (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_DEPTH
) >= 15)
154 SetAttrs(o
, PDTA_FreeSourceBitMap
, FALSE
,
160 struct FrameInfo fri
= {0};
162 D(bug("DTM_FRAMEBOX\n", o
));
163 DoMethod(o
,DTM_FRAMEBOX
,NULL
,(IPTR
)&fri
,(IPTR
)&fri
,sizeof(struct FrameInfo
),0);
165 if (fri
.fri_Dimensions
.Depth
>0)
167 D(bug("DTM_PROCLAYOUT\n", o
));
168 if (DoMethod(o
,DTM_PROCLAYOUT
,NULL
,1))
183 void dt_cleanup(void)
188 char *allocPath(char *str
) {
197 for (l
=0; s0
!= s1
; s0
++,l
++);
198 s
= AllocVec(l
+1, MEMF_CLEAR
);
199 if (s
) strncpy(s
, str
, l
);
204 void freeString(char *str
) {
205 if (str
) FreeVec(str
);
208 char *SkipChars(char *v
) {
215 int GetInt(char *v
) {
221 BOOL
GetBool(char *v
, char *id
)
223 if (strstr(v
, id
)) return TRUE
; else return FALSE
;
226 void GetIntegers(char *v
, int *v1
, int *v2
) {
228 char va1
[32], va2
[32];
232 cnt
= sscanf(c
, "%s %s", va1
, va2
);
236 } else if (cnt
== 2) {
243 struct NewImage
*NewImageContainer(UWORD w
, UWORD h
) {
245 /* Function: Create a new Image with the specified dimensions
247 * width and height ofthe wished Image
249 * Pointer to the Created image or NULL
250 * Bugs: Not known yet
251 * NOTES: Function will only return non-NULL if all allocations could be done
252 * so you have not to check something inside the NewImage structure
257 ni
= AllocVec(sizeof(struct NewImage
), MEMF_ANY
|MEMF_CLEAR
);
261 ni
->data
= AllocVec(w
*h
*4, MEMF_ANY
|MEMF_CLEAR
);
262 if (ni
->data
== NULL
) {
270 void DisposeImageContainer(struct NewImage
*ni
) {
272 /* Function: Remove all Memory used by an Image
273 * Input: NewImage ni:
274 * Pointer to an Image to be deallocated
281 if (ni
->o
!= NULL
) DisposeDTObject(ni
->o
);
286 struct NewImage
*GetImageFromFile(char *name
, struct Screen
*scr
) {
288 /* Function: Load an Image from a file
290 * Filename of the Image to load
292 * Pointer to the Created image or NULL
293 * Bugs: Not known yet
294 * NOTES: Function will only return non-NULL if all allocations could be done
295 * so you have not to check something inside the NewImage struct.
296 * This function uses DataTypes for loading images, so be sure to have
297 * the specific DataTypes installed
300 struct BitMapHeader
*bmhd
;
303 struct pdtBlitPixelArray pa
;
310 pic
= NewDTObject(name
, DTA_SourceType
, DTST_FILE
,
311 DTA_GroupID
, GID_PICTURE
,
313 PDTA_DestMode
, PMODE_V43
,
316 get(pic
, PDTA_BitMapHeader
, &bmhd
);
319 h
= bmhd
->bmh_Height
;
320 mask
= bmhd
->bmh_Masking
;
321 ni
= NewImageContainer(w
, h
);
323 pa
.MethodID
= PDTM_READPIXELARRAY
;
324 pa
.pbpa_PixelData
= (APTR
) ni
->data
;
325 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
326 pa
.pbpa_PixelArrayMod
= w
*4;
331 DoMethodA(pic
, (Msg
) &pa
);
332 if (mask
!= mskHasAlpha
) {
334 for (a
= 0; a
< (w
*h
); a
++) ni
->data
[a
] |= 0x000000ff;
336 for (a
= 0; a
< (w
*h
); a
++) ni
->data
[a
] |= 0xff000000;
341 depth
= (ULONG
) GetBitMapAttr(&scr
->BitMap
, BMA_DEPTH
);
343 if (depth
< 15) ni
->o
= LoadPicture(name
, scr
);
346 GetDTAttrs(ni
->o
, PDTA_DestBitMap
, (IPTR
)&ni
->bitmap
, TAG_DONE
);
347 if (ni
->bitmap
== NULL
) GetDTAttrs(ni
->o
, PDTA_BitMap
, (IPTR
)&ni
->bitmap
, TAG_DONE
);
349 if (ni
->bitmap
) GetDTAttrs(ni
->o
, PDTA_MaskPlane
, (IPTR
)&ni
->mask
, TAG_DONE
);
354 DisposeDTObject(pic
);
361 BOOL
ReadPropConfig(struct dt_node
*data
, struct Screen
*scr
) {
367 file
= Open(data
->filename
, MODE_OLDFILE
);
370 line
= FGets(file
, buffer
, 256);
372 if ((v
= strstr(line
, "ContainerTop ")) == line
) {
373 GetIntegers(v
, &data
->ContainerTop_o
, &data
->ContainerTop_s
);
374 } else if ((v
= strstr(line
, "ContainerVertTile ")) == line
) {
375 GetIntegers(v
, &data
->ContainerVertTile_o
, &data
->ContainerVertTile_s
);
376 } else if ((v
= strstr(line
, "KnobTop ")) == line
) {
377 GetIntegers(v
, &data
->KnobTop_o
, &data
->KnobTop_s
);
378 } else if ((v
= strstr(line
, "KnobTileTop ")) == line
) {
379 GetIntegers(v
, &data
->KnobTileTop_o
, &data
->KnobTileTop_s
);
380 } else if ((v
= strstr(line
, "KnobVertGripper ")) == line
) {
381 GetIntegers(v
, &data
->KnobVertGripper_o
, &data
->KnobVertGripper_s
);
382 } else if ((v
= strstr(line
, "KnobTileBottom ")) == line
) {
383 GetIntegers(v
, &data
->KnobTileBottom_o
, &data
->KnobTileBottom_s
);
384 } else if ((v
= strstr(line
, "KnobBottom ")) == line
) {
385 GetIntegers(v
, &data
->KnobBottom_o
, &data
->KnobBottom_s
);
386 } else if ((v
= strstr(line
, "ContainerBottom ")) == line
) {
387 GetIntegers(v
, &data
->ContainerBottom_o
, &data
->ContainerBottom_s
);
388 } else if ((v
= strstr(line
, "ContainerLeft ")) == line
) {
389 GetIntegers(v
, &data
->ContainerLeft_o
, &data
->ContainerLeft_s
);
390 } else if ((v
= strstr(line
, "ContainerHorTile ")) == line
) {
391 GetIntegers(v
, &data
->ContainerHorTile_o
, &data
->ContainerHorTile_s
);
392 } else if ((v
= strstr(line
, "KnobLeft ")) == line
) {
393 GetIntegers(v
, &data
->KnobLeft_o
, &data
->KnobLeft_s
);
394 } else if ((v
= strstr(line
, "KnobTileLeft ")) == line
) {
395 GetIntegers(v
, &data
->KnobTileLeft_o
, &data
->KnobTileLeft_s
);
396 } else if ((v
= strstr(line
, "KnobHorGripper ")) == line
) {
397 GetIntegers(v
, &data
->KnobHorGripper_o
, &data
->KnobHorGripper_s
);
398 } else if ((v
= strstr(line
, "KnobTileRight ")) == line
) {
399 GetIntegers(v
, &data
->KnobTileRight_o
, &data
->KnobTileRight_s
);
400 } else if ((v
= strstr(line
, "KnobRight ")) == line
) {
401 GetIntegers(v
, &data
->KnobRight_o
, &data
->KnobRight_s
);
402 } else if ((v
= strstr(line
, "ContainerRight ")) == line
) {
403 GetIntegers(v
, &data
->ContainerRight_o
, &data
->ContainerRight_s
);
409 STRPTR path
= allocPath(data
->filename
);
412 BPTR lock
= Lock(path
, ACCESS_READ
);
415 BPTR oldcd
= CurrentDir(lock
);
416 data
->img_verticalcontainer
= GetImageFromFile("Container/Vertical", scr
);
417 data
->img_verticalknob
= GetImageFromFile("Knob/Vertical", scr
);
418 data
->img_horizontalcontainer
= GetImageFromFile("Container/Horizontal", scr
);
419 data
->img_horizontalknob
= GetImageFromFile("Knob/Horizontal", scr
);
420 data
->img_up
= GetImageFromFile("ArrowUp/default", scr
);
421 data
->img_down
= GetImageFromFile("ArrowDown/default", scr
);
422 data
->img_left
= GetImageFromFile("ArrowLeft/default", scr
);
423 data
->img_right
= GetImageFromFile("ArrowRight/default", scr
);
432 if (data
->img_horizontalcontainer
&& data
->img_horizontalknob
&& data
->img_verticalcontainer
&& data
->img_verticalknob
&& data
->img_up
&& data
->img_down
&& data
->img_left
&& data
->img_right
) return TRUE
;
436 void FreePropConfig(struct dt_node
*data
)
438 DisposeImageContainer(data
->img_verticalcontainer
);
439 DisposeImageContainer(data
->img_verticalknob
);
440 DisposeImageContainer(data
->img_horizontalcontainer
);
441 DisposeImageContainer(data
->img_horizontalknob
);
442 DisposeImageContainer(data
->img_up
);
443 DisposeImageContainer(data
->img_down
);
444 DisposeImageContainer(data
->img_left
);
445 DisposeImageContainer(data
->img_right
);
449 BOOL
ReadFrameConfig(STRPTR filename
, struct dt_frame_image
*fi
, struct Screen
*scr
) {
457 file
= Open(filename
, MODE_OLDFILE
);
460 line
= FGets(file
, buffer
, 256);
462 if ((v
= strstr(line
, "TileLeft ")) == line
) {
463 fi
->tile_left
= GetInt(v
);
464 } else if ((v
= strstr(line
, "TileTop ")) == line
) {
465 fi
->tile_top
= GetInt(v
);
466 } else if ((v
= strstr(line
, "TileRight ")) == line
) {
467 fi
->tile_right
= GetInt(v
);
468 } else if ((v
= strstr(line
, "TileBottom ")) == line
) {
469 fi
->tile_bottom
= GetInt(v
);
470 } else if ((v
= strstr(line
, "InnerLeft ")) == line
) {
471 fi
->inner_left
= GetInt(v
);
472 } else if ((v
= strstr(line
, "InnerTop ")) == line
) {
473 fi
->inner_top
= GetInt(v
);
474 } else if ((v
= strstr(line
, "InnerRight ")) == line
) {
475 fi
->inner_right
= GetInt(v
);
476 } else if ((v
= strstr(line
, "InnerBottom ")) == line
) {
477 fi
->inner_bottom
= GetInt(v
);
478 } else if ((v
= strstr(line
, "NoAlpha ")) == line
) {
479 fi
->noalpha
= GetBool(v
, "Yes");
486 STRPTR path
= allocPath(filename
);
489 BPTR lock
= Lock(path
, ACCESS_READ
);
492 BPTR oldcd
= CurrentDir(lock
);
493 fi
->img_up
= GetImageFromFile("up/default", scr
);
494 fi
->img_down
= GetImageFromFile("down/default", scr
);
502 if (fi
->img_up
&& fi
->img_down
) return TRUE
;
506 void FreeFrameConfig(struct dt_frame_image
*fi
)
510 DisposeImageContainer(fi
->img_up
);
511 DisposeImageContainer(fi
->img_down
);
515 void dispose_custom_frame(struct dt_frame_image
* fi
)
524 struct dt_frame_image
* load_custom_frame(CONST_STRPTR filename
, struct Screen
*scr
)
526 struct dt_frame_image
*fi
= AllocVec(sizeof(struct dt_frame_image
), MEMF_ANY
);
530 if (Stricmp(FilePart(filename
), "frame.config") == 0) /* special configuration image for prop gadgets */
532 if (ReadFrameConfig(filename
, fi
, scr
))
548 struct dt_node
*dt_load_picture(CONST_STRPTR filename
, struct Screen
*scr
)
550 struct dt_node
*node
;
551 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
558 node
= List_First(&dt_list
);
561 if (!Stricmp(filename
,node
->filename
) && scr
== node
->scr
)
564 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
567 node
= Node_Next(node
);
570 if ((node
= (struct dt_node
*)AllocVec(sizeof(struct dt_node
),MEMF_CLEAR
)))
573 if ((node
->filename
= StrDup(filename
)))
575 /* create the datatypes object */
576 D(bug("loading %s\n", filename
));
577 if ((Stricmp(FilePart(filename
), "prop.config") == 0) || (Stricmp(FilePart(filename
), "config") == 0)) /* special configuration image for prop gadgets */
579 if (ReadPropConfig(node
, scr
))
582 node
->mode
= MODE_PROP
;
585 AddTail((struct List
*)&dt_list
,(struct Node
*)node
);
586 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
591 FreePropConfig(node
);
596 if ((node
->o
= LoadPicture(filename
,scr
)))
598 struct BitMapHeader
*bmhd
;
599 GetDTAttrs(node
->o
,PDTA_BitMapHeader
, (IPTR
)&bmhd
, TAG_DONE
);
600 D(bug("picture %lx\n", node
->o
));
604 node
->width
= bmhd
->bmh_Width
;
605 node
->height
= bmhd
->bmh_Height
;
606 node
->mask
= bmhd
->bmh_Masking
;
607 D(bug("picture %lx = %ldx%ld\n", node
->o
, node
->width
, node
->height
));
611 AddTail((struct List
*)&dt_list
,(struct Node
*)node
);
612 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
616 FreeVec(node
->filename
);
620 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
624 void dt_dispose_picture(struct dt_node
*node
)
626 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
627 if (node
&& node
->count
)
632 Remove((struct Node
*)node
);
633 if (node
->mode
== MODE_PROP
) FreePropConfig(node
); else DisposeDTObject(node
->o
);
634 FreeVec(node
->filename
);
638 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
641 int dt_width(struct dt_node
*node
)
649 int dt_height(struct dt_node
*node
)
658 void dt_put_on_rastport(struct dt_node
*node
, struct RastPort
*rp
, int x
, int y
)
660 struct BitMap
*bitmap
= NULL
;
661 struct pdtBlitPixelArray pa
;
670 depth
= (ULONG
) GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
);
671 if ((depth
>= 15) && (node
->mask
== mskHasAlpha
))
673 img
= (ULONG
*) AllocVec(dt_width(node
) * dt_height(node
) * 4, MEMF_ANY
);
676 pa
.MethodID
= PDTM_READPIXELARRAY
;
677 pa
.pbpa_PixelData
= (UBYTE
*) img
;
678 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
679 pa
.pbpa_PixelArrayMod
= dt_width(node
) * 4;
682 pa
.pbpa_Width
= dt_width(node
);
683 pa
.pbpa_Height
= dt_height(node
);
684 DoMethodA(o
, (Msg
) &pa
);
685 WritePixelArrayAlpha(img
, 0, 0, dt_width(node
) * 4, rp
, x
, y
, dt_width(node
), dt_height(node
), 0xffffffff);
691 GetDTAttrs(o
, PDTA_DestBitMap
, (IPTR
)&bitmap
, TAG_DONE
);
693 GetDTAttrs(o
, PDTA_BitMap
, (IPTR
)&bitmap
, TAG_DONE
);
699 GetDTAttrs(o
, PDTA_MaskPlane
, (IPTR
)&mask
, TAG_DONE
);
703 MyBltMaskBitMapRastPort(bitmap
, 0, 0, rp
, x
, y
,
704 dt_width(node
), dt_height(node
), 0xe0,
707 BltMaskBitMapRastPort(bitmap
, 0, 0, rp
, x
, y
,
708 dt_width(node
), dt_height(node
), 0xe0,
713 BltBitMapRastPort(bitmap
, 0, 0, rp
, x
, y
,
714 dt_width(node
), dt_height(node
), 0xc0);
719 void dt_put_mim_on_rastport(struct dt_node
*node
, struct RastPort
*rp
, int x
, int y
,int state
)
721 struct BitMap
*bitmap
= NULL
;
722 struct pdtBlitPixelArray pa
;
731 int width
= dt_width(node
) >> 1;
732 depth
= (ULONG
) GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
);
733 if ((depth
>= 15) && (node
->mask
== mskHasAlpha
))
735 img
= (ULONG
*) AllocVec(dt_width(node
) * dt_height(node
) * 4, MEMF_ANY
);
739 int height
= dt_height(node
);
740 pa
.MethodID
= PDTM_READPIXELARRAY
;
741 pa
.pbpa_PixelData
= (UBYTE
*) img
;
742 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
743 pa
.pbpa_PixelArrayMod
= width
* 4;
744 pa
.pbpa_Left
= state
* width
;
746 pa
.pbpa_Width
= width
;
747 pa
.pbpa_Height
= height
;
748 DoMethodA(o
, (Msg
) &pa
);
749 WritePixelArrayAlpha(img
, 0, 0, width
* 4, rp
, x
, y
, width
, height
, 0xffffffff);
755 GetDTAttrs(o
, PDTA_DestBitMap
, (IPTR
)&bitmap
, TAG_DONE
);
757 GetDTAttrs(o
, PDTA_BitMap
, (IPTR
)&bitmap
, TAG_DONE
);
764 GetDTAttrs(o
, PDTA_MaskPlane
, (IPTR
)&mask
, TAG_DONE
);
768 MyBltMaskBitMapRastPort(bitmap
, width
*state
, 0, rp
, x
, y
,
769 width
, dt_height(node
), 0xe0,
772 BltMaskBitMapRastPort(bitmap
, width
*state
, 0, rp
, x
, y
,
773 width
, dt_height(node
), 0xe0,
778 BltBitMapRastPort(bitmap
, width
*state
, 0, rp
, x
, y
,
779 width
, dt_height(node
), 0xc0);
787 #define RECTSIZEX(r) ((r)->MaxX-(r)->MinX+1)
788 #define RECTSIZEY(r) ((r)->MaxY-(r)->MinY+1)
790 #define MOD(x,y) ((x)<0 ? (y)-((-(x))%(y)) : (x)%(y))
795 struct Rectangle Bounds
;
800 struct BackFillOptions
802 WORD MaxCopyWidth
; // maximum width for the copy
803 WORD MaxCopyHeight
; // maximum height for the copy
804 // BOOL CenterX; // center the tiles horizontally?
805 // BOOL CenterY; // center the tiles vertically?
806 WORD OffsetX
; // offset to add
807 WORD OffsetY
; // offset to add
808 BOOL OffsetTitleY
; // add the screen titlebar height to the vertical offset?
816 struct BitMap
*BitMap
;
817 /* struct Screen *Screen; */ /* Needed for centering */
820 struct BackFillOptions Options
;
826 static void CopyTiledBitMap(struct BitMap
*Src
,WORD SrcOffsetX
,WORD SrcOffsetY
,WORD SrcSizeX
,WORD SrcSizeY
,struct BitMap
*Dst
,struct Rectangle
*DstBounds
)
828 WORD FirstSizeX
; // the width of the rectangle to blit as the first column
829 WORD FirstSizeY
; // the height of the rectangle to blit as the first row
830 WORD SecondMinX
; // the left edge of the second column
831 WORD SecondMinY
; // the top edge of the second column
832 WORD SecondSizeX
; // the width of the second column
833 WORD SecondSizeY
; // the height of the second column
834 WORD Pos
; // used as starting position in the "exponential" blit
835 WORD Size
; // used as bitmap size in the "exponential" blit
837 FirstSizeX
= MIN(SrcSizeX
-SrcOffsetX
,RECTSIZEX(DstBounds
)); // the width of the first tile, this is either the rest of the tile right to SrcOffsetX or the width of the dest rect, if the rect is narrow
838 SecondMinX
= DstBounds
->MinX
+FirstSizeX
; // the start for the second tile (if used)
839 SecondSizeX
= MIN(SrcOffsetX
,DstBounds
->MaxX
-SecondMinX
+1); // the width of the second tile (we want the whole tile to be SrcSizeX pixels wide, if we use SrcSizeX-SrcOffsetX pixels for the left part we'll use SrcOffsetX for the right part)
841 FirstSizeY
= MIN(SrcSizeY
-SrcOffsetY
,RECTSIZEY(DstBounds
)); // the same values are calculated for y direction
842 SecondMinY
= DstBounds
->MinY
+FirstSizeY
;
843 SecondSizeY
= MIN(SrcOffsetY
,DstBounds
->MaxY
-SecondMinY
+1);
845 BltBitMap(Src
,SrcOffsetX
,SrcOffsetY
,Dst
,DstBounds
->MinX
,DstBounds
->MinY
,FirstSizeX
,FirstSizeY
,0xC0,-1,NULL
); // blit the first piece of the tile
846 if (SecondSizeX
>0) // if SrcOffset was 0 or the dest rect was to narrow, we won't need a second column
847 BltBitMap(Src
,0,SrcOffsetY
,Dst
,SecondMinX
,DstBounds
->MinY
,SecondSizeX
,FirstSizeY
,0xC0,-1,NULL
);
848 if (SecondSizeY
>0) // is a second row necessary?
850 BltBitMap(Src
,SrcOffsetX
,0,Dst
,DstBounds
->MinX
,SecondMinY
,FirstSizeX
,SecondSizeY
,0xC0,-1,NULL
);
852 BltBitMap(Src
,0,0,Dst
,SecondMinX
,SecondMinY
,SecondSizeX
,SecondSizeY
,0xC0,-1,NULL
);
855 // this loop generates the first row of the tiles
856 for (Pos
= DstBounds
->MinX
+SrcSizeX
,Size
= MIN(SrcSizeX
,DstBounds
->MaxX
-Pos
+1);Pos
<=DstBounds
->MaxX
;)
858 BltBitMap(Dst
,DstBounds
->MinX
,DstBounds
->MinY
,Dst
,Pos
,DstBounds
->MinY
,Size
,MIN(SrcSizeY
,RECTSIZEY(DstBounds
)),0xC0,-1,NULL
);
860 Size
= MIN(Size
<<1,DstBounds
->MaxX
-Pos
+1);
863 // this loop blit the first row down several times to fill the whole dest rect
864 for (Pos
= DstBounds
->MinY
+SrcSizeY
,Size
= MIN(SrcSizeY
,DstBounds
->MaxY
-Pos
+1);Pos
<=DstBounds
->MaxY
;)
866 BltBitMap(Dst
,DstBounds
->MinX
,DstBounds
->MinY
,Dst
,DstBounds
->MinX
,Pos
,RECTSIZEX(DstBounds
),Size
,0xC0,-1,NULL
);
868 Size
= MIN(Size
<<1,DstBounds
->MaxY
-Pos
+1);
872 AROS_UFH3S(void, WindowPatternBackFillFunc
,
873 AROS_UFHA(struct Hook
*, Hook
, A0
),
874 AROS_UFHA(struct RastPort
*, RP
, A2
),
875 AROS_UFHA(struct BackFillMsg
*, BFM
, A1
))
879 WORD OffsetX
; // the offset within the tile in x direction
880 WORD OffsetY
; // the offset within the tile in y direction
882 struct BackFillInfo
*BFI
= (struct BackFillInfo
*)Hook
; // get the data for our backfillhook
885 putreg(12,(long)Hook
->h_Data
);
888 OffsetX
= BFM
->Bounds
.MinX
-BFI
->Options
.OffsetX
; // The first tile normally isn't totally visible => calculate the offset (offset 0 would mean that the left edge of the damage rectangle coincides with the left edge of a tile)
889 // if (BFI->Options.CenterX) // horizontal centering?
890 // OffsetX -= (BFI->Screen->Width-BFI->Width)/2;
892 OffsetY
= BFM
->Bounds
.MinY
-BFI
->Options
.OffsetY
; // The same values are calculated for y direction
895 if (BFI->Options.OffsetTitleY) // shift the tiles down?
896 OffsetY -= BFI->Screen->BarHeight+1;
899 // if (BFI->Options.CenterY) // horizontal centering?
900 // OffsetY -= (BFI->Screen->Height - BFI->Height)/2;
902 CopyTiledBitMap(BFI
->BitMap
,MOD(OffsetX
+BFI
->OffsetX
,BFI
->Width
),MOD(OffsetY
+BFI
->OffsetY
,BFI
->Height
),BFI
->CopyWidth
,BFI
->CopyHeight
,RP
->BitMap
,&BFM
->Bounds
);
907 static void CalculateCopySizes(struct BackFillInfo
*BFI
)
909 BFI
->CopyWidth
= (BFI
->Width
>BFI
->Options
.MaxCopyWidth
) ? BFI
->Width
: BFI
->Options
.MaxCopyWidth
-BFI
->Options
.MaxCopyWidth
%BFI
->Width
;
910 BFI
->CopyHeight
= (BFI
->Height
>BFI
->Options
.MaxCopyHeight
) ? BFI
->Height
: BFI
->Options
.MaxCopyHeight
-BFI
->Options
.MaxCopyHeight
%BFI
->Height
;
913 **********************************************************/
915 void dt_put_on_rastport_tiled(struct dt_node
*node
, struct RastPort
*rp
, int x1
, int y1
, int x2
, int y2
, int xoffset
, int yoffset
)
917 struct Screen
*scr
= node
->scr
;
918 struct BitMap
*bitmap
;
924 GetDTAttrs(o
, PDTA_DestBitMap
, (IPTR
)&bitmap
, TAG_DONE
);
926 GetDTAttrs(o
, PDTA_BitMap
, (IPTR
)&bitmap
, TAG_DONE
);
930 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
934 struct BackFillInfo
*bfi
= (struct BackFillInfo
*)AllocVec(sizeof(struct BackFillInfo
),MEMF_CLEAR
);
937 LONG depth
= GetBitMapAttr(bitmap
,BMA_DEPTH
);
938 bfi
->Hook
.h_Entry
= (HOOKFUNC
)WindowPatternBackFillFunc
;
940 bfi
->Hook
.h_Data
= (APTR
)getreg(12); /* register A4 */
943 bfi
->Options
.MaxCopyWidth
= 256;
944 bfi
->Options
.MaxCopyHeight
= 256;
945 // bfi->Options.CenterX = FALSE; /* center the tiles horizontally? */
946 // bfi->Options.CenterY = FALSE; /* center the tiles vertically? */
947 bfi
->Options
.OffsetX
= 0; /* offset to add */
948 bfi
->Options
.OffsetY
= 0; /* offset to add */
949 bfi
->Options
.OffsetTitleY
= TRUE
; /* add the screen titlebar height to the vertical offset? */
950 bfi
->Width
= dt_width(node
);
951 bfi
->Height
= dt_height(node
);
953 CalculateCopySizes(bfi
);
955 if((bfi
->BitMap
= AllocBitMap(bfi
->CopyWidth
,bfi
->CopyHeight
,depth
, BMF_INTERLEAVED
|BMF_MINPLANES
,scr
->RastPort
.BitMap
)))
957 struct Rectangle CopyBounds
;
960 CopyBounds
.MaxX
= bfi
->CopyWidth
-1;
961 CopyBounds
.MaxY
= bfi
->CopyHeight
-1;
963 CopyTiledBitMap(bitmap
,0,0,bfi
->Width
,bfi
->Height
,bfi
->BitMap
,&CopyBounds
);
971 struct BackFillInfo
*bfi
= node
->bfi
;
972 struct Rectangle rect
;
981 LockLayer(0, rp
->Layer
);
982 xoffset
-= rp
->Layer
->bounds
.MinX
;
983 yoffset
-= rp
->Layer
->bounds
.MinY
;
986 bfi
->OffsetX
= xoffset
;
987 bfi
->OffsetY
= yoffset
;
989 DoHookClipRects((struct Hook
*)bfi
,rp
,&rect
);
993 UnlockLayer(rp
->Layer
);
996 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);