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>
27 #include <libraries/cybergraphics.h>
32 #include "muimaster_intern.h"
33 #include "datatypescache.h"
35 extern struct Library
*MUIMasterBase
;
37 static struct List dt_list
;
38 static int dt_initialized
;
41 /* A BltBitMaskPort() replacement which blits masks for interleaved bitmaps correctly */
45 struct Rectangle bounds
;
53 struct BitMap maskBitMap
;
54 struct BitMap
*srcBitMap
;
62 VOID
MyBltMaskBitMap( CONST
struct BitMap
*srcBitMap
, LONG xSrc
, LONG ySrc
, struct BitMap
*destBitMap
, LONG xDest
, LONG yDest
, LONG xSize
, LONG ySize
, struct BitMap
*maskBitMap
)
64 BltBitMap(srcBitMap
,xSrc
,ySrc
,destBitMap
, xDest
, yDest
, xSize
, ySize
, 0x99,~0,NULL
);
65 BltBitMap(maskBitMap
,xSrc
,ySrc
,destBitMap
, xDest
, yDest
, xSize
, ySize
, 0xe2,~0,NULL
);
66 BltBitMap(srcBitMap
,xSrc
,ySrc
,destBitMap
, xDest
, yDest
, xSize
, ySize
, 0x99,~0,NULL
);
70 ASM
void HookFunc_BltMask(REG(a0
, struct Hook
*hook
), REG(a1
,struct LayerHookMsg
*msg
), REG(a2
,struct RastPort
*rp
))
72 struct BltMaskHook
*h
= (struct BltMaskHook
*)hook
;
74 LONG width
= msg
->bounds
.MaxX
- msg
->bounds
.MinX
+1;
75 LONG height
= msg
->bounds
.MaxY
- msg
->bounds
.MinY
+1;
76 LONG offsetx
= h
->srcx
+ msg
->offsetx
- h
->destx
;
77 LONG offsety
= h
->srcy
+ msg
->offsety
- h
->desty
;
80 putreg(REG_A4
,(long)hook
->h_Data
);
83 MyBltMaskBitMap( h
->srcBitMap
, offsetx
, offsety
, rp
->BitMap
, msg
->bounds
.MinX
, msg
->bounds
.MinY
, width
, height
, &h
->maskBitMap
);
86 VOID
MyBltMaskBitMapRastPort( struct BitMap
*srcBitMap
, LONG xSrc
, LONG ySrc
, struct RastPort
*destRP
, LONG xDest
, LONG yDest
, LONG xSize
, LONG ySize
, ULONG minterm
, APTR bltMask
)
88 if (GetBitMapAttr(srcBitMap
,BMA_FLAGS
)&BMF_INTERLEAVED
)
90 LONG src_depth
= GetBitMapAttr(srcBitMap
,BMA_DEPTH
);
91 struct Rectangle rect
;
92 struct BltMaskHook hook
;
94 /* Define the destination rectangle in the rastport */
97 rect
.MaxX
= xDest
+ xSize
- 1;
98 rect
.MaxY
= yDest
+ ySize
- 1;
100 /* Initialize the hook */
101 hook
.hook
.h_Entry
= (HOOKFUNC
)HookFunc_BltMask
;
103 hook
.hook
.h_Data
= (void*)getreg(REG_A4
);
105 hook
.srcBitMap
= srcBitMap
;
111 /* Initialize a bitmap where all plane pointers points to the mask */
112 InitBitMap(&hook
.maskBitMap
,src_depth
,GetBitMapAttr(srcBitMap
,BMA_WIDTH
),GetBitMapAttr(srcBitMap
,BMA_HEIGHT
));
114 hook
.maskBitMap
.Planes
[--src_depth
] = bltMask
;
116 /* Blit onto the Rastport */
117 DoHookClipRects(&hook
.hook
,destRP
,&rect
);
120 BltMaskBitMapRastPort(srcBitMap
, xSrc
, ySrc
, destRP
, xDest
, yDest
, xSize
, ySize
, minterm
, bltMask
);
127 static Object
*LoadPicture(CONST_STRPTR filename
, struct Screen
*scr
)
131 struct Process
*myproc
= (struct Process
*)FindTask(NULL
);
132 APTR oldwindowptr
= myproc
->pr_WindowPtr
;
133 myproc
->pr_WindowPtr
= (APTR
)-1;
135 o
= NewDTObject((APTR
)filename
,
136 DTA_GroupID
, GID_PICTURE
,
137 OBP_Precision
, PRECISION_EXACT
,
138 PDTA_Screen
, (IPTR
)scr
,
139 PDTA_FreeSourceBitMap
, TRUE
,
140 PDTA_DestMode
, PMODE_V43
,
141 PDTA_UseFriendBitMap
, TRUE
,
144 myproc
->pr_WindowPtr
= oldwindowptr
;
145 D(bug("... picture=%lx\n", o
));
149 struct BitMapHeader
*bmhd
;
151 GetDTAttrs(o
,PDTA_BitMapHeader
, (IPTR
)&bmhd
, TAG_DONE
);
152 if (bmhd
->bmh_Masking
== mskHasAlpha
)
154 if (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_DEPTH
) >= 15)
156 SetAttrs(o
, PDTA_FreeSourceBitMap
, FALSE
,
162 struct FrameInfo fri
= {0};
164 D(bug("DTM_FRAMEBOX\n", o
));
165 DoMethod(o
,DTM_FRAMEBOX
,NULL
,(IPTR
)&fri
,(IPTR
)&fri
,sizeof(struct FrameInfo
),0);
167 if (fri
.fri_Dimensions
.Depth
>0)
169 D(bug("DTM_PROCLAYOUT\n", o
));
170 if (DoMethod(o
,DTM_PROCLAYOUT
,NULL
,1))
185 void dt_cleanup(void)
190 char *allocPath(char *str
) {
199 for (l
=0; s0
!= s1
; s0
++,l
++);
200 s
= AllocVec(l
+1, MEMF_CLEAR
);
201 if (s
) strncpy(s
, str
, l
);
206 void freeString(char *str
) {
207 if (str
) FreeVec(str
);
210 char *SkipChars(char *v
) {
217 int GetInt(char *v
) {
223 void GetIntegers(char *v
, int *v1
, int *v2
) {
225 char va1
[32], va2
[32];
229 cnt
= sscanf(c
, "%s %s", va1
, va2
);
233 } else if (cnt
== 2) {
240 struct NewImage
*NewImageContainer(UWORD w
, UWORD h
) {
242 /* Function: Create a new Image with the specified dimensions
244 * width and height ofthe wished Image
246 * Pointer to the Created image or NULL
247 * Bugs: Not known yet
248 * NOTES: Function will only return non-NULL if all allocations could be done
249 * so you have not to check something inside the NewImage structure
254 ni
= AllocVec(sizeof(struct NewImage
), MEMF_ANY
|MEMF_CLEAR
);
258 ni
->data
= AllocVec(w
*h
*4, MEMF_ANY
|MEMF_CLEAR
);
259 if (ni
->data
== NULL
) {
267 void DisposeImageContainer(struct NewImage
*ni
) {
269 /* Function: Remove all Memory used by an Image
270 * Input: NewImage ni:
271 * Pointer to an Image to be deallocated
278 if (ni
->o
!= NULL
) DisposeDTObject(ni
->o
);
283 struct NewImage
*GetImageFromFile(char *name
, struct Screen
*scr
) {
285 /* Function: Load an Image from a file
287 * Filename of the Image to load
289 * Pointer to the Created image or NULL
290 * Bugs: Not known yet
291 * NOTES: Function will only return non-NULL if all allocations could be done
292 * so you have not to check something inside the NewImage struct.
293 * This function uses DataTypes for loading images, so be sure to have
294 * the specific DataTypes installed
297 struct BitMapHeader
*bmhd
;
300 struct pdtBlitPixelArray pa
;
307 pic
= NewDTObject(name
, DTA_SourceType
, DTST_FILE
,
308 DTA_GroupID
, GID_PICTURE
,
310 PDTA_DestMode
, PMODE_V43
,
313 get(pic
, PDTA_BitMapHeader
, &bmhd
);
316 h
= bmhd
->bmh_Height
;
317 mask
= bmhd
->bmh_Masking
;
318 ni
= NewImageContainer(w
, h
);
320 pa
.MethodID
= PDTM_READPIXELARRAY
;
321 pa
.pbpa_PixelData
= (APTR
) ni
->data
;
322 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
323 pa
.pbpa_PixelArrayMod
= w
*4;
328 DoMethodA(pic
, (Msg
) &pa
);
329 if (mask
!= mskHasAlpha
) {
331 for (a
= 0; a
< (w
*h
); a
++) ni
->data
[a
] |= 0x000000ff;
333 for (a
= 0; a
< (w
*h
); a
++) ni
->data
[a
] |= 0xff000000;
338 depth
= (ULONG
) GetBitMapAttr(&scr
->BitMap
, BMA_DEPTH
);
340 if (depth
< 15) ni
->o
= LoadPicture(name
, scr
);
343 GetDTAttrs(ni
->o
, PDTA_DestBitMap
, (IPTR
)&ni
->bitmap
, TAG_DONE
);
344 if (ni
->bitmap
== NULL
) GetDTAttrs(ni
->o
, PDTA_BitMap
, (IPTR
)&ni
->bitmap
, TAG_DONE
);
346 if (ni
->bitmap
) GetDTAttrs(ni
->o
, PDTA_MaskPlane
, (IPTR
)&ni
->mask
, TAG_DONE
);
351 DisposeDTObject(pic
);
358 BOOL
ReadPropConfig(struct dt_node
*data
, struct Screen
*scr
) {
364 file
= Open(data
->filename
, MODE_OLDFILE
);
367 line
= FGets(file
, buffer
, 256);
369 if ((v
= strstr(line
, "ContainerTop ")) == line
) {
370 GetIntegers(v
, &data
->ContainerTop_o
, &data
->ContainerTop_s
);
371 } else if ((v
= strstr(line
, "ContainerVertTile ")) == line
) {
372 GetIntegers(v
, &data
->ContainerVertTile_o
, &data
->ContainerVertTile_s
);
373 } else if ((v
= strstr(line
, "KnobTop ")) == line
) {
374 GetIntegers(v
, &data
->KnobTop_o
, &data
->KnobTop_s
);
375 } else if ((v
= strstr(line
, "KnobTileTop ")) == line
) {
376 GetIntegers(v
, &data
->KnobTileTop_o
, &data
->KnobTileTop_s
);
377 } else if ((v
= strstr(line
, "KnobVertGripper ")) == line
) {
378 GetIntegers(v
, &data
->KnobVertGripper_o
, &data
->KnobVertGripper_s
);
379 } else if ((v
= strstr(line
, "KnobTileBottom ")) == line
) {
380 GetIntegers(v
, &data
->KnobTileBottom_o
, &data
->KnobTileBottom_s
);
381 } else if ((v
= strstr(line
, "KnobBottom ")) == line
) {
382 GetIntegers(v
, &data
->KnobBottom_o
, &data
->KnobBottom_s
);
383 } else if ((v
= strstr(line
, "ContainerBottom ")) == line
) {
384 GetIntegers(v
, &data
->ContainerBottom_o
, &data
->ContainerBottom_s
);
385 } else if ((v
= strstr(line
, "ContainerLeft ")) == line
) {
386 GetIntegers(v
, &data
->ContainerLeft_o
, &data
->ContainerLeft_s
);
387 } else if ((v
= strstr(line
, "ContainerHorTile ")) == line
) {
388 GetIntegers(v
, &data
->ContainerHorTile_o
, &data
->ContainerHorTile_s
);
389 } else if ((v
= strstr(line
, "KnobLeft ")) == line
) {
390 GetIntegers(v
, &data
->KnobLeft_o
, &data
->KnobLeft_s
);
391 } else if ((v
= strstr(line
, "KnobTileLeft ")) == line
) {
392 GetIntegers(v
, &data
->KnobTileLeft_o
, &data
->KnobTileLeft_s
);
393 } else if ((v
= strstr(line
, "KnobHorGripper ")) == line
) {
394 GetIntegers(v
, &data
->KnobHorGripper_o
, &data
->KnobHorGripper_s
);
395 } else if ((v
= strstr(line
, "KnobTileRight ")) == line
) {
396 GetIntegers(v
, &data
->KnobTileRight_o
, &data
->KnobTileRight_s
);
397 } else if ((v
= strstr(line
, "KnobRight ")) == line
) {
398 GetIntegers(v
, &data
->KnobRight_o
, &data
->KnobRight_s
);
399 } else if ((v
= strstr(line
, "ContainerRight ")) == line
) {
400 GetIntegers(v
, &data
->ContainerRight_o
, &data
->ContainerRight_s
);
406 STRPTR path
= allocPath(data
->filename
);
409 BPTR lock
= Lock(path
, ACCESS_READ
);
412 BPTR oldcd
= CurrentDir(lock
);
413 data
->img_verticalcontainer
= GetImageFromFile("Container/Vertical", scr
);
414 data
->img_verticalknob
= GetImageFromFile("Knob/Vertical", scr
);
415 data
->img_horizontalcontainer
= GetImageFromFile("Container/Horizontal", scr
);
416 data
->img_horizontalknob
= GetImageFromFile("Knob/Horizontal", scr
);
417 data
->img_up
= GetImageFromFile("ArrowUp/default", scr
);
418 data
->img_down
= GetImageFromFile("ArrowDown/default", scr
);
419 data
->img_left
= GetImageFromFile("ArrowLeft/default", scr
);
420 data
->img_right
= GetImageFromFile("ArrowRight/default", scr
);
429 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
;
433 void FreePropConfig(struct dt_node
*data
)
435 DisposeImageContainer(data
->img_verticalcontainer
);
436 DisposeImageContainer(data
->img_verticalknob
);
437 DisposeImageContainer(data
->img_horizontalcontainer
);
438 DisposeImageContainer(data
->img_horizontalknob
);
439 DisposeImageContainer(data
->img_up
);
440 DisposeImageContainer(data
->img_down
);
441 DisposeImageContainer(data
->img_left
);
442 DisposeImageContainer(data
->img_right
);
446 struct dt_node
*dt_load_picture(CONST_STRPTR filename
, struct Screen
*scr
)
448 struct dt_node
*node
;
449 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
456 node
= List_First(&dt_list
);
459 if (!Stricmp(filename
,node
->filename
) && scr
== node
->scr
)
462 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
465 node
= Node_Next(node
);
468 if ((node
= (struct dt_node
*)AllocVec(sizeof(struct dt_node
),MEMF_CLEAR
)))
471 if ((node
->filename
= StrDup(filename
)))
473 /* create the datatypes object */
474 D(bug("loading %s\n", filename
));
475 if ((Stricmp(FilePart(filename
), "prop.config") == 0) || (Stricmp(FilePart(filename
), "config") == 0)) /* special configuration image for prop gadgets */
477 if (ReadPropConfig(node
, scr
))
480 node
->mode
= MODE_PROP
;
483 AddTail((struct List
*)&dt_list
,(struct Node
*)node
);
484 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
489 FreePropConfig(node
);
494 if ((node
->o
= LoadPicture(filename
,scr
)))
496 struct BitMapHeader
*bmhd
;
497 GetDTAttrs(node
->o
,PDTA_BitMapHeader
, (IPTR
)&bmhd
, TAG_DONE
);
498 D(bug("picture %lx\n", node
->o
));
502 node
->width
= bmhd
->bmh_Width
;
503 node
->height
= bmhd
->bmh_Height
;
504 node
->mask
= bmhd
->bmh_Masking
;
505 D(bug("picture %lx = %ldx%ld\n", node
->o
, node
->width
, node
->height
));
509 AddTail((struct List
*)&dt_list
,(struct Node
*)node
);
510 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
514 FreeVec(node
->filename
);
518 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
522 void dt_dispose_picture(struct dt_node
*node
)
524 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
525 if (node
&& node
->count
)
530 Remove((struct Node
*)node
);
531 if (node
->mode
== MODE_PROP
) FreePropConfig(node
); else DisposeDTObject(node
->o
);
532 FreeVec(node
->filename
);
536 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
539 int dt_width(struct dt_node
*node
)
547 int dt_height(struct dt_node
*node
)
556 void dt_put_on_rastport(struct dt_node
*node
, struct RastPort
*rp
, int x
, int y
)
558 struct BitMap
*bitmap
= NULL
;
559 struct pdtBlitPixelArray pa
;
568 depth
= (ULONG
) GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
);
569 if ((depth
>= 15) && (node
->mask
== mskHasAlpha
))
571 img
= (ULONG
*) AllocVec(dt_width(node
) * dt_height(node
) * 4, MEMF_ANY
);
574 pa
.MethodID
= PDTM_READPIXELARRAY
;
575 pa
.pbpa_PixelData
= (UBYTE
*) img
;
576 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
577 pa
.pbpa_PixelArrayMod
= dt_width(node
) * 4;
580 pa
.pbpa_Width
= dt_width(node
);
581 pa
.pbpa_Height
= dt_height(node
);
582 DoMethodA(o
, (Msg
) &pa
);
583 WritePixelArrayAlpha(img
, 0, 0, dt_width(node
) * 4, rp
, x
, y
, dt_width(node
), dt_height(node
), 0xffffffff);
589 GetDTAttrs(o
, PDTA_DestBitMap
, (IPTR
)&bitmap
, TAG_DONE
);
591 GetDTAttrs(o
, PDTA_BitMap
, (IPTR
)&bitmap
, TAG_DONE
);
597 GetDTAttrs(o
, PDTA_MaskPlane
, (IPTR
)&mask
, TAG_DONE
);
601 MyBltMaskBitMapRastPort(bitmap
, 0, 0, rp
, x
, y
,
602 dt_width(node
), dt_height(node
), 0xe0,
605 BltMaskBitMapRastPort(bitmap
, 0, 0, rp
, x
, y
,
606 dt_width(node
), dt_height(node
), 0xe0,
611 BltBitMapRastPort(bitmap
, 0, 0, rp
, x
, y
,
612 dt_width(node
), dt_height(node
), 0xc0);
617 void dt_put_mim_on_rastport(struct dt_node
*node
, struct RastPort
*rp
, int x
, int y
,int state
)
619 struct BitMap
*bitmap
= NULL
;
620 struct pdtBlitPixelArray pa
;
629 int width
= dt_width(node
) >> 1;
630 depth
= (ULONG
) GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
);
631 if ((depth
>= 15) && (node
->mask
== mskHasAlpha
))
633 img
= (ULONG
*) AllocVec(dt_width(node
) * dt_height(node
) * 4, MEMF_ANY
);
637 int height
= dt_height(node
);
638 pa
.MethodID
= PDTM_READPIXELARRAY
;
639 pa
.pbpa_PixelData
= (UBYTE
*) img
;
640 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
641 pa
.pbpa_PixelArrayMod
= width
* 4;
642 pa
.pbpa_Left
= state
* width
;
644 pa
.pbpa_Width
= width
;
645 pa
.pbpa_Height
= height
;
646 DoMethodA(o
, (Msg
) &pa
);
647 WritePixelArrayAlpha(img
, 0, 0, width
* 4, rp
, x
, y
, width
, height
, 0xffffffff);
653 GetDTAttrs(o
, PDTA_DestBitMap
, (IPTR
)&bitmap
, TAG_DONE
);
655 GetDTAttrs(o
, PDTA_BitMap
, (IPTR
)&bitmap
, TAG_DONE
);
662 GetDTAttrs(o
, PDTA_MaskPlane
, (IPTR
)&mask
, TAG_DONE
);
666 MyBltMaskBitMapRastPort(bitmap
, width
*state
, 0, rp
, x
, y
,
667 width
, dt_height(node
), 0xe0,
670 BltMaskBitMapRastPort(bitmap
, width
*state
, 0, rp
, x
, y
,
671 width
, dt_height(node
), 0xe0,
676 BltBitMapRastPort(bitmap
, width
*state
, 0, rp
, x
, y
,
677 width
, dt_height(node
), 0xc0);
685 #define RECTSIZEX(r) ((r)->MaxX-(r)->MinX+1)
686 #define RECTSIZEY(r) ((r)->MaxY-(r)->MinY+1)
688 #define MOD(x,y) ((x)<0 ? (y)-((-(x))%(y)) : (x)%(y))
693 struct Rectangle Bounds
;
698 struct BackFillOptions
700 WORD MaxCopyWidth
; // maximum width for the copy
701 WORD MaxCopyHeight
; // maximum height for the copy
702 // BOOL CenterX; // center the tiles horizontally?
703 // BOOL CenterY; // center the tiles vertically?
704 WORD OffsetX
; // offset to add
705 WORD OffsetY
; // offset to add
706 BOOL OffsetTitleY
; // add the screen titlebar height to the vertical offset?
714 struct BitMap
*BitMap
;
715 /* struct Screen *Screen; */ /* Needed for centering */
718 struct BackFillOptions Options
;
724 static void CopyTiledBitMap(struct BitMap
*Src
,WORD SrcOffsetX
,WORD SrcOffsetY
,WORD SrcSizeX
,WORD SrcSizeY
,struct BitMap
*Dst
,struct Rectangle
*DstBounds
)
726 WORD FirstSizeX
; // the width of the rectangle to blit as the first column
727 WORD FirstSizeY
; // the height of the rectangle to blit as the first row
728 WORD SecondMinX
; // the left edge of the second column
729 WORD SecondMinY
; // the top edge of the second column
730 WORD SecondSizeX
; // the width of the second column
731 WORD SecondSizeY
; // the height of the second column
732 WORD Pos
; // used as starting position in the "exponential" blit
733 WORD Size
; // used as bitmap size in the "exponential" blit
735 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
736 SecondMinX
= DstBounds
->MinX
+FirstSizeX
; // the start for the second tile (if used)
737 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)
739 FirstSizeY
= MIN(SrcSizeY
-SrcOffsetY
,RECTSIZEY(DstBounds
)); // the same values are calculated for y direction
740 SecondMinY
= DstBounds
->MinY
+FirstSizeY
;
741 SecondSizeY
= MIN(SrcOffsetY
,DstBounds
->MaxY
-SecondMinY
+1);
743 BltBitMap(Src
,SrcOffsetX
,SrcOffsetY
,Dst
,DstBounds
->MinX
,DstBounds
->MinY
,FirstSizeX
,FirstSizeY
,0xC0,-1,NULL
); // blit the first piece of the tile
744 if (SecondSizeX
>0) // if SrcOffset was 0 or the dest rect was to narrow, we won't need a second column
745 BltBitMap(Src
,0,SrcOffsetY
,Dst
,SecondMinX
,DstBounds
->MinY
,SecondSizeX
,FirstSizeY
,0xC0,-1,NULL
);
746 if (SecondSizeY
>0) // is a second row necessary?
748 BltBitMap(Src
,SrcOffsetX
,0,Dst
,DstBounds
->MinX
,SecondMinY
,FirstSizeX
,SecondSizeY
,0xC0,-1,NULL
);
750 BltBitMap(Src
,0,0,Dst
,SecondMinX
,SecondMinY
,SecondSizeX
,SecondSizeY
,0xC0,-1,NULL
);
753 // this loop generates the first row of the tiles
754 for (Pos
= DstBounds
->MinX
+SrcSizeX
,Size
= MIN(SrcSizeX
,DstBounds
->MaxX
-Pos
+1);Pos
<=DstBounds
->MaxX
;)
756 BltBitMap(Dst
,DstBounds
->MinX
,DstBounds
->MinY
,Dst
,Pos
,DstBounds
->MinY
,Size
,MIN(SrcSizeY
,RECTSIZEY(DstBounds
)),0xC0,-1,NULL
);
758 Size
= MIN(Size
<<1,DstBounds
->MaxX
-Pos
+1);
761 // this loop blit the first row down several times to fill the whole dest rect
762 for (Pos
= DstBounds
->MinY
+SrcSizeY
,Size
= MIN(SrcSizeY
,DstBounds
->MaxY
-Pos
+1);Pos
<=DstBounds
->MaxY
;)
764 BltBitMap(Dst
,DstBounds
->MinX
,DstBounds
->MinY
,Dst
,DstBounds
->MinX
,Pos
,RECTSIZEX(DstBounds
),Size
,0xC0,-1,NULL
);
766 Size
= MIN(Size
<<1,DstBounds
->MaxY
-Pos
+1);
770 AROS_UFH3S(void, WindowPatternBackFillFunc
,
771 AROS_UFHA(struct Hook
*, Hook
, A0
),
772 AROS_UFHA(struct RastPort
*, RP
, A2
),
773 AROS_UFHA(struct BackFillMsg
*, BFM
, A1
))
777 WORD OffsetX
; // the offset within the tile in x direction
778 WORD OffsetY
; // the offset within the tile in y direction
780 struct BackFillInfo
*BFI
= (struct BackFillInfo
*)Hook
; // get the data for our backfillhook
783 putreg(12,(long)Hook
->h_Data
);
786 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)
787 // if (BFI->Options.CenterX) // horizontal centering?
788 // OffsetX -= (BFI->Screen->Width-BFI->Width)/2;
790 OffsetY
= BFM
->Bounds
.MinY
-BFI
->Options
.OffsetY
; // The same values are calculated for y direction
793 if (BFI->Options.OffsetTitleY) // shift the tiles down?
794 OffsetY -= BFI->Screen->BarHeight+1;
797 // if (BFI->Options.CenterY) // horizontal centering?
798 // OffsetY -= (BFI->Screen->Height - BFI->Height)/2;
800 CopyTiledBitMap(BFI
->BitMap
,MOD(OffsetX
+BFI
->OffsetX
,BFI
->Width
),MOD(OffsetY
+BFI
->OffsetY
,BFI
->Height
),BFI
->CopyWidth
,BFI
->CopyHeight
,RP
->BitMap
,&BFM
->Bounds
);
805 static void CalculateCopySizes(struct BackFillInfo
*BFI
)
807 BFI
->CopyWidth
= (BFI
->Width
>BFI
->Options
.MaxCopyWidth
) ? BFI
->Width
: BFI
->Options
.MaxCopyWidth
-BFI
->Options
.MaxCopyWidth
%BFI
->Width
;
808 BFI
->CopyHeight
= (BFI
->Height
>BFI
->Options
.MaxCopyHeight
) ? BFI
->Height
: BFI
->Options
.MaxCopyHeight
-BFI
->Options
.MaxCopyHeight
%BFI
->Height
;
811 **********************************************************/
813 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
)
815 struct Screen
*scr
= node
->scr
;
816 struct BitMap
*bitmap
;
822 GetDTAttrs(o
, PDTA_DestBitMap
, (IPTR
)&bitmap
, TAG_DONE
);
824 GetDTAttrs(o
, PDTA_BitMap
, (IPTR
)&bitmap
, TAG_DONE
);
828 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
832 struct BackFillInfo
*bfi
= (struct BackFillInfo
*)AllocVec(sizeof(struct BackFillInfo
),MEMF_CLEAR
);
835 LONG depth
= GetBitMapAttr(bitmap
,BMA_DEPTH
);
836 bfi
->Hook
.h_Entry
= (ULONG (*)())WindowPatternBackFillFunc
;
838 bfi
->Hook
.h_Data
= (APTR
)getreg(12); /* register A4 */
841 bfi
->Options
.MaxCopyWidth
= 256;
842 bfi
->Options
.MaxCopyHeight
= 256;
843 // bfi->Options.CenterX = FALSE; /* center the tiles horizontally? */
844 // bfi->Options.CenterY = FALSE; /* center the tiles vertically? */
845 bfi
->Options
.OffsetX
= 0; /* offset to add */
846 bfi
->Options
.OffsetY
= 0; /* offset to add */
847 bfi
->Options
.OffsetTitleY
= TRUE
; /* add the screen titlebar height to the vertical offset? */
848 bfi
->Width
= dt_width(node
);
849 bfi
->Height
= dt_height(node
);
851 CalculateCopySizes(bfi
);
853 if((bfi
->BitMap
= AllocBitMap(bfi
->CopyWidth
,bfi
->CopyHeight
,depth
, BMF_INTERLEAVED
|BMF_MINPLANES
,scr
->RastPort
.BitMap
)))
855 struct Rectangle CopyBounds
;
858 CopyBounds
.MaxX
= bfi
->CopyWidth
-1;
859 CopyBounds
.MaxY
= bfi
->CopyHeight
-1;
861 CopyTiledBitMap(bitmap
,0,0,bfi
->Width
,bfi
->Height
,bfi
->BitMap
,&CopyBounds
);
869 struct BackFillInfo
*bfi
= node
->bfi
;
870 struct Rectangle rect
;
879 LockLayer(0, rp
->Layer
);
880 xoffset
-= rp
->Layer
->bounds
.MinX
;
881 yoffset
-= rp
->Layer
->bounds
.MinY
;
884 bfi
->OffsetX
= xoffset
;
885 bfi
->OffsetY
= yoffset
;
887 DoHookClipRects((struct Hook
*)bfi
,rp
,&rect
);
891 UnlockLayer(rp
->Layer
);
894 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);