2 Copyright 2002-2011, 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
;
41 STACKED
struct Layer
*layer
;
42 STACKED
struct Rectangle bounds
;
50 struct BitMap maskBitMap
;
51 struct BitMap
*srcBitMap
;
58 /* A BltBitMaskPort() replacement which blits masks for interleaved bitmaps
61 VOID
MyBltMaskBitMap(CONST
struct BitMap
*srcBitMap
, LONG xSrc
, LONG ySrc
,
62 struct BitMap
*destBitMap
, LONG xDest
, LONG yDest
, LONG xSize
,
63 LONG ySize
, struct BitMap
*maskBitMap
)
65 BltBitMap(srcBitMap
, xSrc
, ySrc
, destBitMap
, xDest
, yDest
, xSize
, ySize
,
67 BltBitMap(maskBitMap
, xSrc
, ySrc
, destBitMap
, xDest
, yDest
, xSize
,
68 ySize
, 0xe2, ~0, NULL
);
69 BltBitMap(srcBitMap
, xSrc
, ySrc
, destBitMap
, xDest
, yDest
, xSize
, ySize
,
74 ASM
void HookFunc_BltMask(REG(a0
, struct Hook
*hook
), REG(a1
,
75 struct LayerHookMsg
*msg
), REG(a2
, struct RastPort
*rp
))
77 struct BltMaskHook
*h
= (struct BltMaskHook
*)hook
;
79 LONG width
= msg
->bounds
.MaxX
- msg
->bounds
.MinX
+ 1;
80 LONG height
= msg
->bounds
.MaxY
- msg
->bounds
.MinY
+ 1;
81 LONG offsetx
= h
->srcx
+ msg
->offsetx
- h
->destx
;
82 LONG offsety
= h
->srcy
+ msg
->offsety
- h
->desty
;
85 putreg(REG_A4
, (long)hook
->h_Data
);
88 MyBltMaskBitMap(h
->srcBitMap
, offsetx
, offsety
, rp
->BitMap
,
89 msg
->bounds
.MinX
, msg
->bounds
.MinY
, width
, height
, &h
->maskBitMap
);
92 VOID
MyBltMaskBitMapRastPort(struct BitMap
*srcBitMap
, LONG xSrc
, LONG ySrc
,
93 struct RastPort
*destRP
, LONG xDest
, LONG yDest
, LONG xSize
, LONG ySize
,
94 ULONG minterm
, APTR bltMask
)
96 if (GetBitMapAttr(srcBitMap
, BMA_FLAGS
) & BMF_INTERLEAVED
)
98 LONG src_depth
= GetBitMapAttr(srcBitMap
, BMA_DEPTH
);
99 struct Rectangle rect
;
100 struct BltMaskHook hook
;
102 /* Define the destination rectangle in the rastport */
105 rect
.MaxX
= xDest
+ xSize
- 1;
106 rect
.MaxY
= yDest
+ ySize
- 1;
108 /* Initialize the hook */
109 hook
.hook
.h_Entry
= (HOOKFUNC
) HookFunc_BltMask
;
111 hook
.hook
.h_Data
= (void *)getreg(REG_A4
);
113 hook
.srcBitMap
= srcBitMap
;
119 /* Initialize a bitmap where all plane pointers points to the mask */
120 InitBitMap(&hook
.maskBitMap
, src_depth
, GetBitMapAttr(srcBitMap
,
121 BMA_WIDTH
), GetBitMapAttr(srcBitMap
, BMA_HEIGHT
));
123 hook
.maskBitMap
.Planes
[--src_depth
] = bltMask
;
125 /* Blit onto the Rastport */
126 DoHookClipRects(&hook
.hook
, destRP
, &rect
);
130 BltMaskBitMapRastPort(srcBitMap
, xSrc
, ySrc
, destRP
, xDest
, yDest
,
131 xSize
, ySize
, minterm
, bltMask
);
138 static Object
*LoadPicture(CONST_STRPTR filename
, struct Screen
*scr
)
142 struct Process
*myproc
= (struct Process
*)FindTask(NULL
);
143 APTR oldwindowptr
= myproc
->pr_WindowPtr
;
144 myproc
->pr_WindowPtr
= (APTR
) - 1;
146 o
= NewDTObject((APTR
) filename
,
147 DTA_GroupID
, GID_PICTURE
,
148 OBP_Precision
, PRECISION_EXACT
,
149 PDTA_Screen
, (IPTR
) scr
,
150 PDTA_DestMode
, PMODE_V43
, PDTA_UseFriendBitMap
, TRUE
, TAG_DONE
);
152 myproc
->pr_WindowPtr
= oldwindowptr
;
153 D(bug("... picture=%lx\n", o
));
157 struct BitMapHeader
*bmhd
;
159 GetDTAttrs(o
, PDTA_BitMapHeader
, (IPTR
) & bmhd
, TAG_DONE
);
160 if (bmhd
->bmh_Masking
== mskHasAlpha
)
162 if (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_DEPTH
) >= 15)
164 SetAttrs(o
, PDTA_FreeSourceBitMap
, FALSE
,
165 PDTA_Remap
, FALSE
, TAG_DONE
);
169 struct FrameInfo fri
= { 0 };
171 D(bug("DTM_FRAMEBOX\n", o
));
172 DoMethod(o
, DTM_FRAMEBOX
, NULL
, (IPTR
) & fri
, (IPTR
) & fri
,
173 sizeof(struct FrameInfo
), 0);
175 if (fri
.fri_Dimensions
.Depth
> 0)
177 D(bug("DTM_PROCLAYOUT\n", o
));
178 if (DoMethod(o
, DTM_PROCLAYOUT
, NULL
, 1))
193 void dt_cleanup(void)
198 char *allocPath(const char *str
)
210 for (l
= 0; s0
!= s1
; s0
++, l
++);
211 s
= AllocVec(l
+ 1, MEMF_CLEAR
);
218 void freeString(char *str
)
224 char *SkipChars(char *v
)
239 BOOL
GetBool(char *v
, char *id
)
247 void GetIntegers(char *v
, int *v1
, int *v2
)
250 char va1
[32], va2
[32];
255 cnt
= sscanf(c
, "%s %s", va1
, va2
);
269 /* Function: Create a new Image with the specified dimensions
271 * width and height ofthe wished Image
273 * Pointer to the Created image or NULL
274 * Bugs: Not known yet
275 * NOTES: Function will only return non-NULL if all allocations could be done
276 * so you have not to check something inside the NewImage structure
278 struct NewImage
*NewImageContainer(UWORD w
, UWORD h
)
283 ni
= AllocVec(sizeof(struct NewImage
), MEMF_ANY
| MEMF_CLEAR
);
288 ni
->data
= AllocVec(w
* h
* 4, MEMF_ANY
| MEMF_CLEAR
);
289 if (ni
->data
== NULL
)
298 /* Function: Remove all Memory used by an Image
299 * Input: NewImage ni:
300 * Pointer to an Image to be deallocated
303 void DisposeImageContainer(struct NewImage
*ni
)
313 DisposeDTObject(ni
->o
);
318 /* Function: Load an Image from a file
320 * Filename of the Image to load
322 * Pointer to the Created image or NULL
323 * Bugs: Not known yet
324 * NOTES: Function will only return non-NULL if all allocations could be done
325 * so you have not to check something inside the NewImage struct.
326 * This function uses DataTypes for loading images, so be sure to have
327 * the specific DataTypes installed
329 struct NewImage
*GetImageFromFile(char *name
, struct Screen
*scr
)
332 struct BitMapHeader
*bmhd
= NULL
;
335 struct pdtBlitPixelArray pa
;
342 pic
= NewDTObject(name
, DTA_SourceType
, DTST_FILE
,
343 DTA_GroupID
, GID_PICTURE
,
344 PDTA_Remap
, FALSE
, PDTA_DestMode
, PMODE_V43
, TAG_DONE
);
347 get(pic
, PDTA_BitMapHeader
, &bmhd
);
351 h
= bmhd
->bmh_Height
;
352 mask
= bmhd
->bmh_Masking
;
353 ni
= NewImageContainer(w
, h
);
356 pa
.MethodID
= PDTM_READPIXELARRAY
;
357 pa
.pbpa_PixelData
= (APTR
) ni
->data
;
358 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
359 pa
.pbpa_PixelArrayMod
= w
* 4;
364 DoMethodA(pic
, (Msg
) & pa
);
365 if (mask
!= mskHasAlpha
)
368 for (a
= 0; a
< (w
* h
); a
++)
369 ni
->data
[a
] |= 0x000000ff;
371 for (a
= 0; a
< (w
* h
); a
++)
372 ni
->data
[a
] |= 0xff000000;
377 depth
= (ULONG
) GetBitMapAttr(&scr
->BitMap
, BMA_DEPTH
);
380 ni
->o
= LoadPicture(name
, scr
);
383 GetDTAttrs(ni
->o
, PDTA_DestBitMap
,
384 (IPTR
) & ni
->bitmap
, TAG_DONE
);
385 if (ni
->bitmap
== NULL
)
386 GetDTAttrs(ni
->o
, PDTA_BitMap
,
387 (IPTR
) & ni
->bitmap
, TAG_DONE
);
390 GetDTAttrs(ni
->o
, PDTA_MaskPlane
,
391 (IPTR
) & ni
->mask
, TAG_DONE
);
396 DisposeDTObject(pic
);
403 BOOL
ReadPropConfig(struct dt_node
* data
, struct Screen
* scr
)
410 file
= Open(data
->filename
, MODE_OLDFILE
);
415 line
= FGets(file
, buffer
, 256);
418 if ((v
= strstr(line
, "ContainerTop ")) == line
)
420 GetIntegers(v
, &data
->ContainerTop_o
,
421 &data
->ContainerTop_s
);
423 else if ((v
= strstr(line
, "ContainerVertTile ")) == line
)
425 GetIntegers(v
, &data
->ContainerVertTile_o
,
426 &data
->ContainerVertTile_s
);
428 else if ((v
= strstr(line
, "KnobTop ")) == line
)
430 GetIntegers(v
, &data
->KnobTop_o
, &data
->KnobTop_s
);
432 else if ((v
= strstr(line
, "KnobTileTop ")) == line
)
434 GetIntegers(v
, &data
->KnobTileTop_o
,
435 &data
->KnobTileTop_s
);
437 else if ((v
= strstr(line
, "KnobVertGripper ")) == line
)
439 GetIntegers(v
, &data
->KnobVertGripper_o
,
440 &data
->KnobVertGripper_s
);
442 else if ((v
= strstr(line
, "KnobTileBottom ")) == line
)
444 GetIntegers(v
, &data
->KnobTileBottom_o
,
445 &data
->KnobTileBottom_s
);
447 else if ((v
= strstr(line
, "KnobBottom ")) == line
)
449 GetIntegers(v
, &data
->KnobBottom_o
,
450 &data
->KnobBottom_s
);
452 else if ((v
= strstr(line
, "ContainerBottom ")) == line
)
454 GetIntegers(v
, &data
->ContainerBottom_o
,
455 &data
->ContainerBottom_s
);
457 else if ((v
= strstr(line
, "ContainerLeft ")) == line
)
459 GetIntegers(v
, &data
->ContainerLeft_o
,
460 &data
->ContainerLeft_s
);
462 else if ((v
= strstr(line
, "ContainerHorTile ")) == line
)
464 GetIntegers(v
, &data
->ContainerHorTile_o
,
465 &data
->ContainerHorTile_s
);
467 else if ((v
= strstr(line
, "KnobLeft ")) == line
)
469 GetIntegers(v
, &data
->KnobLeft_o
, &data
->KnobLeft_s
);
471 else if ((v
= strstr(line
, "KnobTileLeft ")) == line
)
473 GetIntegers(v
, &data
->KnobTileLeft_o
,
474 &data
->KnobTileLeft_s
);
476 else if ((v
= strstr(line
, "KnobHorGripper ")) == line
)
478 GetIntegers(v
, &data
->KnobHorGripper_o
,
479 &data
->KnobHorGripper_s
);
481 else if ((v
= strstr(line
, "KnobTileRight ")) == line
)
483 GetIntegers(v
, &data
->KnobTileRight_o
,
484 &data
->KnobTileRight_s
);
486 else if ((v
= strstr(line
, "KnobRight ")) == line
)
488 GetIntegers(v
, &data
->KnobRight_o
, &data
->KnobRight_s
);
490 else if ((v
= strstr(line
, "ContainerRight ")) == line
)
492 GetIntegers(v
, &data
->ContainerRight_o
,
493 &data
->ContainerRight_s
);
500 STRPTR path
= allocPath(data
->filename
);
503 BPTR lock
= Lock(path
, ACCESS_READ
);
506 BPTR oldcd
= CurrentDir(lock
);
507 data
->img_verticalcontainer
=
508 GetImageFromFile("Container/Vertical", scr
);
509 data
->img_verticalknob
= GetImageFromFile("Knob/Vertical", scr
);
510 data
->img_horizontalcontainer
=
511 GetImageFromFile("Container/Horizontal", scr
);
512 data
->img_horizontalknob
=
513 GetImageFromFile("Knob/Horizontal", scr
);
514 data
->img_up
= GetImageFromFile("ArrowUp/default", scr
);
515 data
->img_down
= GetImageFromFile("ArrowDown/default", scr
);
516 data
->img_left
= GetImageFromFile("ArrowLeft/default", scr
);
517 data
->img_right
= GetImageFromFile("ArrowRight/default", scr
);
526 if (data
->img_horizontalcontainer
&& data
->img_horizontalknob
527 && data
->img_verticalcontainer
&& data
->img_verticalknob
528 && data
->img_up
&& data
->img_down
&& data
->img_left
534 void FreePropConfig(struct dt_node
*data
)
536 DisposeImageContainer(data
->img_verticalcontainer
);
537 DisposeImageContainer(data
->img_verticalknob
);
538 DisposeImageContainer(data
->img_horizontalcontainer
);
539 DisposeImageContainer(data
->img_horizontalknob
);
540 DisposeImageContainer(data
->img_up
);
541 DisposeImageContainer(data
->img_down
);
542 DisposeImageContainer(data
->img_left
);
543 DisposeImageContainer(data
->img_right
);
547 BOOL
ReadFrameConfig(CONST_STRPTR filename
, struct dt_frame_image
*fi
,
557 file
= Open(filename
, MODE_OLDFILE
);
562 line
= FGets(file
, buffer
, 256);
565 if ((v
= strstr(line
, "TileLeft ")) == line
)
567 fi
->tile_left
= GetInt(v
);
569 else if ((v
= strstr(line
, "TileTop ")) == line
)
571 fi
->tile_top
= GetInt(v
);
573 else if ((v
= strstr(line
, "TileRight ")) == line
)
575 fi
->tile_right
= GetInt(v
);
577 else if ((v
= strstr(line
, "TileBottom ")) == line
)
579 fi
->tile_bottom
= GetInt(v
);
581 else if ((v
= strstr(line
, "InnerLeft ")) == line
)
583 fi
->inner_left
= GetInt(v
);
585 else if ((v
= strstr(line
, "InnerTop ")) == line
)
587 fi
->inner_top
= GetInt(v
);
589 else if ((v
= strstr(line
, "InnerRight ")) == line
)
591 fi
->inner_right
= GetInt(v
);
593 else if ((v
= strstr(line
, "InnerBottom ")) == line
)
595 fi
->inner_bottom
= GetInt(v
);
597 else if ((v
= strstr(line
, "NoAlpha ")) == line
)
599 fi
->noalpha
= GetBool(v
, "Yes");
607 STRPTR path
= allocPath(filename
);
610 BPTR lock
= Lock(path
, ACCESS_READ
);
613 BPTR oldcd
= CurrentDir(lock
);
614 fi
->img_up
= GetImageFromFile("up/default", scr
);
615 fi
->img_down
= GetImageFromFile("down/default", scr
);
623 if (fi
->img_up
&& fi
->img_down
)
628 void FreeFrameConfig(struct dt_frame_image
*fi
)
632 DisposeImageContainer(fi
->img_up
);
633 DisposeImageContainer(fi
->img_down
);
637 void dispose_custom_frame(struct dt_frame_image
*fi
)
646 struct dt_frame_image
*load_custom_frame(CONST_STRPTR filename
,
649 struct dt_frame_image
*fi
=
650 AllocVec(sizeof(struct dt_frame_image
), MEMF_ANY
);
654 /* special configuration image for prop gadgets */
655 if (Stricmp(FilePart(filename
), "frame.config") == 0)
657 if (ReadFrameConfig(filename
, fi
, scr
))
673 struct dt_node
*dt_load_picture(CONST_STRPTR filename
, struct Screen
*scr
)
675 struct dt_node
*node
;
676 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
683 node
= List_First(&dt_list
);
686 if (!Stricmp(filename
, node
->filename
) && scr
== node
->scr
)
689 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
692 node
= Node_Next(node
);
696 (struct dt_node
*)AllocVec(sizeof(struct dt_node
), MEMF_CLEAR
)))
699 if ((node
->filename
= StrDup(filename
)))
701 /* create the datatypes object */
702 D(bug("loading %s\n", filename
));
704 /* special configuration image for prop gadgets */
705 if ((Stricmp(FilePart(filename
), "prop.config") == 0)
706 || (Stricmp(FilePart(filename
), "config") == 0))
708 if (ReadPropConfig(node
, scr
))
711 node
->mode
= MODE_PROP
;
714 AddTail((struct List
*)&dt_list
, (struct Node
*)node
);
715 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
720 FreePropConfig(node
);
725 if ((node
->o
= LoadPicture(filename
, scr
)))
727 struct BitMapHeader
*bmhd
;
728 GetDTAttrs(node
->o
, PDTA_BitMapHeader
, (IPTR
) & bmhd
,
730 D(bug("picture %lx\n", node
->o
));
734 node
->width
= bmhd
->bmh_Width
;
735 node
->height
= bmhd
->bmh_Height
;
736 node
->mask
= bmhd
->bmh_Masking
;
737 D(bug("picture %lx = %ldx%ld\n", node
->o
,
738 node
->width
, node
->height
));
742 AddTail((struct List
*)&dt_list
, (struct Node
*)node
);
743 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
747 FreeVec(node
->filename
);
751 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
755 void dt_dispose_picture(struct dt_node
*node
)
757 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
758 if (node
&& node
->count
)
763 Remove((struct Node
*)node
);
764 if (node
->mode
== MODE_PROP
)
765 FreePropConfig(node
);
767 DisposeDTObject(node
->o
);
768 FreeVec(node
->filename
);
772 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
775 int dt_width(struct dt_node
*node
)
783 int dt_height(struct dt_node
*node
)
792 void dt_put_on_rastport(struct dt_node
*node
, struct RastPort
*rp
, int x
,
795 struct BitMap
*bitmap
= NULL
;
796 struct pdtBlitPixelArray pa
;
805 depth
= GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
);
807 if (depth
> 8 && node
->mask
== mskHasAlpha
)
810 (ULONG
*) AllocVec(dt_width(node
) * dt_height(node
) * 4,
814 pa
.MethodID
= PDTM_READPIXELARRAY
;
815 pa
.pbpa_PixelData
= (UBYTE
*) img
;
816 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
817 pa
.pbpa_PixelArrayMod
= dt_width(node
) * 4;
820 pa
.pbpa_Width
= dt_width(node
);
821 pa
.pbpa_Height
= dt_height(node
);
822 DoMethodA(o
, (Msg
) & pa
);
823 WritePixelArrayAlpha(img
, 0, 0, dt_width(node
) * 4, rp
, x
, y
,
824 dt_width(node
), dt_height(node
), 0xffffffff);
830 GetDTAttrs(o
, PDTA_DestBitMap
, (IPTR
) & bitmap
, TAG_DONE
);
832 GetDTAttrs(o
, PDTA_BitMap
, (IPTR
) & bitmap
, TAG_DONE
);
838 GetDTAttrs(o
, PDTA_MaskPlane
, (IPTR
) & mask
, TAG_DONE
);
842 MyBltMaskBitMapRastPort(bitmap
, 0, 0, rp
, x
, y
,
843 dt_width(node
), dt_height(node
), 0xe0, (PLANEPTR
) mask
);
845 BltMaskBitMapRastPort(bitmap
, 0, 0, rp
, x
, y
,
846 dt_width(node
), dt_height(node
), 0xe0, (PLANEPTR
) mask
);
850 BltBitMapRastPort(bitmap
, 0, 0, rp
, x
, y
,
851 dt_width(node
), dt_height(node
), 0xc0);
856 void dt_put_mim_on_rastport(struct dt_node
*node
, struct RastPort
*rp
,
857 int x
, int y
, int state
)
859 struct BitMap
*bitmap
= NULL
;
860 struct pdtBlitPixelArray pa
;
868 int width
= dt_width(node
) >> 1;
869 if (node
->mask
== mskHasAlpha
)
872 (ULONG
*) AllocVec(dt_width(node
) * dt_height(node
) * 4,
877 int height
= dt_height(node
);
878 pa
.MethodID
= PDTM_READPIXELARRAY
;
879 pa
.pbpa_PixelData
= (UBYTE
*) img
;
880 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
881 pa
.pbpa_PixelArrayMod
= width
* 4;
882 pa
.pbpa_Left
= state
* width
;
884 pa
.pbpa_Width
= width
;
885 pa
.pbpa_Height
= height
;
886 DoMethodA(o
, (Msg
) & pa
);
887 WritePixelArrayAlpha(img
, 0, 0, width
* 4, rp
, x
, y
, width
,
894 GetDTAttrs(o
, PDTA_DestBitMap
, (IPTR
) & bitmap
, TAG_DONE
);
896 GetDTAttrs(o
, PDTA_BitMap
, (IPTR
) & bitmap
, TAG_DONE
);
903 GetDTAttrs(o
, PDTA_MaskPlane
, (IPTR
) & mask
, TAG_DONE
);
907 MyBltMaskBitMapRastPort(bitmap
, width
* state
, 0, rp
, x
, y
,
908 width
, dt_height(node
), 0xe0, (PLANEPTR
) mask
);
910 BltMaskBitMapRastPort(bitmap
, width
* state
, 0, rp
, x
, y
,
911 width
, dt_height(node
), 0xe0, (PLANEPTR
) mask
);
915 BltBitMapRastPort(bitmap
, width
* state
, 0, rp
, x
, y
,
916 width
, dt_height(node
), 0xc0);
923 #define RECTSIZEX(r) ((r)->MaxX-(r)->MinX+1)
924 #define RECTSIZEY(r) ((r)->MaxY-(r)->MinY+1)
926 #define MOD(x,y) ((x)<0 ? (y)-((-(x))%(y)) : (x)%(y))
931 struct Rectangle Bounds
;
936 struct BackFillOptions
938 WORD MaxCopyWidth
; // maximum width for the copy
939 WORD MaxCopyHeight
; // maximum height for the copy
940 // BOOL CenterX; // center the tiles horizontally?
941 // BOOL CenterY; // center the tiles vertically?
942 WORD OffsetX
; // offset to add
943 WORD OffsetY
; // offset to add
944 BOOL OffsetTitleY
; // add the screen titlebar height to the vertical offset?
952 struct BitMap
*BitMap
;
953 /* struct Screen *Screen; */ /* Needed for centering */
956 struct BackFillOptions Options
;
962 static void CopyTiledBitMap(struct BitMap
*Src
, WORD SrcOffsetX
,
963 WORD SrcOffsetY
, WORD SrcSizeX
, WORD SrcSizeY
, struct BitMap
*Dst
,
964 struct Rectangle
*DstBounds
)
966 WORD FirstSizeX
; // the width of the rectangle to blit as the first column
967 WORD FirstSizeY
; // the height of the rectangle to blit as the first row
968 WORD SecondMinX
; // the left edge of the second column
969 WORD SecondMinY
; // the top edge of the second column
970 WORD SecondSizeX
; // the width of the second column
971 WORD SecondSizeY
; // the height of the second column
972 WORD Pos
; // used as starting position in the "exponential" blit
973 WORD Size
; // used as bitmap size in the "exponential" blit
975 // the width of the first tile, this is either the rest of the tile right
976 // to SrcOffsetX or the width of the dest rect, if the rect is narrow
977 FirstSizeX
= MIN(SrcSizeX
- SrcOffsetX
, RECTSIZEX(DstBounds
));
979 // the start for the second tile (if used)
980 SecondMinX
= DstBounds
->MinX
+ FirstSizeX
;
982 // the width of the second tile (we want the whole tile to be SrcSizeX
983 // pixels wide, if we use SrcSizeX-SrcOffsetX pixels for the left part
984 // we'll use SrcOffsetX for the right part)
985 SecondSizeX
= MIN(SrcOffsetX
, DstBounds
->MaxX
- SecondMinX
+ 1);
987 // the same values are calculated for y direction
988 FirstSizeY
= MIN(SrcSizeY
- SrcOffsetY
, RECTSIZEY(DstBounds
));
989 SecondMinY
= DstBounds
->MinY
+ FirstSizeY
;
990 SecondSizeY
= MIN(SrcOffsetY
, DstBounds
->MaxY
- SecondMinY
+ 1);
992 // blit the first piece of the tile
993 BltBitMap(Src
, SrcOffsetX
, SrcOffsetY
, Dst
, DstBounds
->MinX
,
994 DstBounds
->MinY
, FirstSizeX
, FirstSizeY
, 0xC0, -1, NULL
);
996 // if SrcOffset was 0 or the dest rect was to narrow, we won't need a
999 BltBitMap(Src
, 0, SrcOffsetY
, Dst
, SecondMinX
, DstBounds
->MinY
,
1000 SecondSizeX
, FirstSizeY
, 0xC0, -1, NULL
);
1002 // is a second row necessary?
1003 if (SecondSizeY
> 0)
1005 BltBitMap(Src
, SrcOffsetX
, 0, Dst
, DstBounds
->MinX
, SecondMinY
,
1006 FirstSizeX
, SecondSizeY
, 0xC0, -1, NULL
);
1007 if (SecondSizeX
> 0)
1008 BltBitMap(Src
, 0, 0, Dst
, SecondMinX
, SecondMinY
, SecondSizeX
,
1009 SecondSizeY
, 0xC0, -1, NULL
);
1012 // this loop generates the first row of the tiles
1013 for (Pos
= DstBounds
->MinX
+ SrcSizeX
, Size
=
1014 MIN(SrcSizeX
, DstBounds
->MaxX
- Pos
+ 1); Pos
<= DstBounds
->MaxX
;)
1016 BltBitMap(Dst
, DstBounds
->MinX
, DstBounds
->MinY
, Dst
, Pos
,
1017 DstBounds
->MinY
, Size
, MIN(SrcSizeY
, RECTSIZEY(DstBounds
)),
1020 Size
= MIN(Size
<< 1, DstBounds
->MaxX
- Pos
+ 1);
1023 // this loop blit the first row down several times to fill the whole
1025 for (Pos
= DstBounds
->MinY
+ SrcSizeY
, Size
=
1026 MIN(SrcSizeY
, DstBounds
->MaxY
- Pos
+ 1); Pos
<= DstBounds
->MaxY
;)
1028 BltBitMap(Dst
, DstBounds
->MinX
, DstBounds
->MinY
, Dst
,
1029 DstBounds
->MinX
, Pos
, RECTSIZEX(DstBounds
), Size
, 0xC0, -1,
1032 Size
= MIN(Size
<< 1, DstBounds
->MaxY
- Pos
+ 1);
1036 AROS_UFH3S(void, WindowPatternBackFillFunc
,
1037 AROS_UFHA(struct Hook
*, Hook
, A0
),
1038 AROS_UFHA(struct RastPort
*, RP
, A2
),
1039 AROS_UFHA(struct BackFillMsg
*, BFM
, A1
))
1043 WORD OffsetX
; // the offset within the tile in x direction
1044 WORD OffsetY
; // the offset within the tile in y direction
1046 // get the data for our backfillhook
1047 struct BackFillInfo
*BFI
= (struct BackFillInfo
*)Hook
;
1050 putreg(12, (long)Hook
->h_Data
);
1053 // The first tile normally isn't totally visible => calculate the offset
1054 // (offset 0 would mean that the left edge of the damage rectangle
1055 // coincides with the left edge of a tile)
1056 OffsetX
= BFM
->Bounds
.MinX
- BFI
->Options
.OffsetX
;
1057 // if (BFI->Options.CenterX) // horizontal centering?
1058 // OffsetX -= (BFI->Screen->Width-BFI->Width)/2;
1060 // The same values are calculated for y direction
1061 OffsetY
= BFM
->Bounds
.MinY
- BFI
->Options
.OffsetY
;
1064 if (BFI->Options.OffsetTitleY) // shift the tiles down?
1065 OffsetY -= BFI->Screen->BarHeight+1;
1068 // if (BFI->Options.CenterY) // horizontal centering?
1069 // OffsetY -= (BFI->Screen->Height - BFI->Height)/2;
1071 CopyTiledBitMap(BFI
->BitMap
, MOD(OffsetX
+ BFI
->OffsetX
, BFI
->Width
),
1072 MOD(OffsetY
+ BFI
->OffsetY
, BFI
->Height
), BFI
->CopyWidth
,
1073 BFI
->CopyHeight
, RP
->BitMap
, &BFM
->Bounds
);
1078 static void CalculateCopySizes(struct BackFillInfo
*BFI
)
1082 BFI
->Options
.MaxCopyWidth
) ? BFI
->Width
: BFI
->Options
.
1083 MaxCopyWidth
- BFI
->Options
.MaxCopyWidth
% BFI
->Width
;
1086 BFI
->Options
.MaxCopyHeight
) ? BFI
->Height
: BFI
->Options
.
1087 MaxCopyHeight
- BFI
->Options
.MaxCopyHeight
% BFI
->Height
;
1091 **********************************************************/
1092 void dt_put_on_rastport_tiled(struct dt_node
*node
, struct RastPort
*rp
,
1093 int x1
, int y1
, int x2
, int y2
, int xoffset
, int yoffset
)
1095 struct Screen
*scr
= node
->scr
;
1096 struct BitMap
*bitmap
;
1103 GetDTAttrs(o
, PDTA_DestBitMap
, (IPTR
) & bitmap
, TAG_DONE
);
1105 GetDTAttrs(o
, PDTA_BitMap
, (IPTR
) & bitmap
, TAG_DONE
);
1109 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
1113 struct BackFillInfo
*bfi
=
1114 (struct BackFillInfo
*)AllocVec(sizeof(struct BackFillInfo
),
1118 LONG depth
= GetBitMapAttr(bitmap
, BMA_DEPTH
);
1119 bfi
->Hook
.h_Entry
= (HOOKFUNC
) WindowPatternBackFillFunc
;
1121 bfi
->Hook
.h_Data
= (APTR
) getreg(12); /* register A4 */
1124 bfi
->Options
.MaxCopyWidth
= 256;
1125 bfi
->Options
.MaxCopyHeight
= 256;
1126 // bfi->Options.CenterX = FALSE; /* center the tiles horizontally? */
1127 // bfi->Options.CenterY = FALSE; /* center the tiles vertically? */
1128 bfi
->Options
.OffsetX
= 0; /* offset to add */
1129 bfi
->Options
.OffsetY
= 0; /* offset to add */
1131 /* add the screen titlebar height to the vertical offset? */
1132 bfi
->Options
.OffsetTitleY
= TRUE
;
1133 bfi
->Width
= dt_width(node
);
1134 bfi
->Height
= dt_height(node
);
1136 CalculateCopySizes(bfi
);
1139 AllocBitMap(bfi
->CopyWidth
, bfi
->CopyHeight
, depth
,
1140 BMF_INTERLEAVED
| BMF_MINPLANES
,
1141 scr
->RastPort
.BitMap
)))
1143 struct Rectangle CopyBounds
;
1144 CopyBounds
.MinX
= 0;
1145 CopyBounds
.MinY
= 0;
1146 CopyBounds
.MaxX
= bfi
->CopyWidth
- 1;
1147 CopyBounds
.MaxY
= bfi
->CopyHeight
- 1;
1149 CopyTiledBitMap(bitmap
, 0, 0, bfi
->Width
, bfi
->Height
,
1150 bfi
->BitMap
, &CopyBounds
);
1158 struct BackFillInfo
*bfi
= node
->bfi
;
1159 struct Rectangle rect
;
1168 LockLayer(0, rp
->Layer
);
1169 xoffset
-= rp
->Layer
->bounds
.MinX
;
1170 yoffset
-= rp
->Layer
->bounds
.MinY
;
1173 bfi
->OffsetX
= xoffset
;
1174 bfi
->OffsetY
= yoffset
;
1176 DoHookClipRects((struct Hook
*)bfi
, rp
, &rect
);
1180 UnlockLayer(rp
->Layer
);
1183 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);