2 Copyright © 2002-2013, The AROS Development Team. All rights reserved.
12 #define DT_V44_SUPPORT
14 #include <datatypes/pictureclass.h>
16 #include <clib/alib_protos.h>
17 #include <proto/exec.h>
18 #include <proto/dos.h>
19 #include <proto/datatypes.h>
20 #include <proto/graphics.h>
21 #include <proto/intuition.h>
22 #include <proto/utility.h>
23 #include <proto/layers.h>
24 #include <proto/cybergraphics.h>
29 #include "muimaster_intern.h"
30 #include "datatypescache.h"
32 extern struct Library
*MUIMasterBase
;
34 static struct List dt_list
;
35 static int dt_initialized
;
40 STACKED
struct Layer
*layer
;
41 STACKED
struct Rectangle bounds
;
49 struct BitMap maskBitMap
;
50 struct BitMap
*srcBitMap
;
55 #define RECTSIZEX(r) ((r)->MaxX-(r)->MinX+1)
56 #define RECTSIZEY(r) ((r)->MaxY-(r)->MinY+1)
58 #define MOD(x,y) ((x)<0 ? (y)-((-(x))%(y)) : (x)%(y))
63 struct Rectangle Bounds
;
68 struct BackFillOptions
70 WORD MaxCopyWidth
; // maximum width for the copy
71 WORD MaxCopyHeight
; // maximum height for the copy
72 // BOOL CenterX; // center the tiles horizontally?
73 // BOOL CenterY; // center the tiles vertically?
74 WORD OffsetX
; // offset to add
75 WORD OffsetY
; // offset to add
76 BOOL OffsetTitleY
; // add the screen titlebar height to the vertical offset?
84 struct BitMap
*BitMap
;
85 /* struct Screen *Screen; */ /* Needed for centering */
88 struct BackFillOptions Options
;
95 /* A BltBitMaskPort() replacement which blits masks for interleaved bitmaps
98 VOID
MyBltMaskBitMap(CONST
struct BitMap
*srcBitMap
, LONG xSrc
, LONG ySrc
,
99 struct BitMap
*destBitMap
, LONG xDest
, LONG yDest
, LONG xSize
,
100 LONG ySize
, struct BitMap
*maskBitMap
)
102 BltBitMap(srcBitMap
, xSrc
, ySrc
, destBitMap
, xDest
, yDest
, xSize
, ySize
,
104 BltBitMap(maskBitMap
, xSrc
, ySrc
, destBitMap
, xDest
, yDest
, xSize
,
105 ySize
, 0xe2, ~0, NULL
);
106 BltBitMap(srcBitMap
, xSrc
, ySrc
, destBitMap
, xDest
, yDest
, xSize
, ySize
,
111 ASM
void HookFunc_BltMask(REG(a0
, struct Hook
*hook
), REG(a1
,
112 struct LayerHookMsg
*msg
), REG(a2
, struct RastPort
*rp
))
114 struct BltMaskHook
*h
= (struct BltMaskHook
*)hook
;
116 LONG width
= msg
->bounds
.MaxX
- msg
->bounds
.MinX
+ 1;
117 LONG height
= msg
->bounds
.MaxY
- msg
->bounds
.MinY
+ 1;
118 LONG offsetx
= h
->srcx
+ msg
->offsetx
- h
->destx
;
119 LONG offsety
= h
->srcy
+ msg
->offsety
- h
->desty
;
122 putreg(REG_A4
, (long)hook
->h_Data
);
125 MyBltMaskBitMap(h
->srcBitMap
, offsetx
, offsety
, rp
->BitMap
,
126 msg
->bounds
.MinX
, msg
->bounds
.MinY
, width
, height
, &h
->maskBitMap
);
129 VOID
MyBltMaskBitMapRastPort(struct BitMap
*srcBitMap
, LONG xSrc
, LONG ySrc
,
130 struct RastPort
*destRP
, LONG xDest
, LONG yDest
, LONG xSize
, LONG ySize
,
131 ULONG minterm
, APTR bltMask
)
133 if (GetBitMapAttr(srcBitMap
, BMA_FLAGS
) & BMF_INTERLEAVED
)
135 LONG src_depth
= GetBitMapAttr(srcBitMap
, BMA_DEPTH
);
136 struct Rectangle rect
;
137 struct BltMaskHook hook
;
139 /* Define the destination rectangle in the rastport */
142 rect
.MaxX
= xDest
+ xSize
- 1;
143 rect
.MaxY
= yDest
+ ySize
- 1;
145 /* Initialize the hook */
146 hook
.hook
.h_Entry
= (HOOKFUNC
) HookFunc_BltMask
;
148 hook
.hook
.h_Data
= (void *)getreg(REG_A4
);
150 hook
.srcBitMap
= srcBitMap
;
156 /* Initialize a bitmap where all plane pointers points to the mask */
157 InitBitMap(&hook
.maskBitMap
, src_depth
, GetBitMapAttr(srcBitMap
,
158 BMA_WIDTH
), GetBitMapAttr(srcBitMap
, BMA_HEIGHT
));
160 hook
.maskBitMap
.Planes
[--src_depth
] = bltMask
;
162 /* Blit onto the Rastport */
163 DoHookClipRects(&hook
.hook
, destRP
, &rect
);
167 BltMaskBitMapRastPort(srcBitMap
, xSrc
, ySrc
, destRP
, xDest
, yDest
,
168 xSize
, ySize
, minterm
, bltMask
);
175 static Object
*LoadPicture(CONST_STRPTR filename
, struct Screen
*scr
)
179 struct Process
*myproc
= (struct Process
*)FindTask(NULL
);
180 APTR oldwindowptr
= myproc
->pr_WindowPtr
;
181 myproc
->pr_WindowPtr
= (APTR
) - 1;
183 o
= NewDTObject((APTR
) filename
,
184 DTA_GroupID
, GID_PICTURE
,
185 OBP_Precision
, PRECISION_EXACT
,
186 PDTA_Screen
, (IPTR
) scr
,
187 PDTA_DestMode
, PMODE_V43
, PDTA_UseFriendBitMap
, TRUE
, TAG_DONE
);
189 myproc
->pr_WindowPtr
= oldwindowptr
;
190 D(bug("... picture=%lx\n", o
));
194 struct BitMapHeader
*bmhd
;
196 GetDTAttrs(o
, PDTA_BitMapHeader
, (IPTR
) & bmhd
, TAG_DONE
);
197 if (bmhd
->bmh_Masking
== mskHasAlpha
)
199 if (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_DEPTH
) >= 15)
201 SetAttrs(o
, PDTA_FreeSourceBitMap
, FALSE
,
202 PDTA_Remap
, FALSE
, TAG_DONE
);
206 struct FrameInfo fri
= { 0 };
208 D(bug("DTM_FRAMEBOX\n", o
));
209 DoMethod(o
, DTM_FRAMEBOX
, NULL
, (IPTR
) & fri
, (IPTR
) & fri
,
210 sizeof(struct FrameInfo
), 0);
212 if (fri
.fri_Dimensions
.Depth
> 0)
214 D(bug("DTM_PROCLAYOUT\n", o
));
215 if (DoMethod(o
, DTM_PROCLAYOUT
, NULL
, 1))
230 void dt_cleanup(void)
235 char *allocPath(const char *str
)
247 for (l
= 0; s0
!= s1
; s0
++, l
++);
248 s
= AllocVec(l
+ 1, MEMF_CLEAR
);
255 void freeString(char *str
)
261 char *SkipChars(char *v
)
276 BOOL
GetBool(char *v
, char *id
)
284 void GetIntegers(char *v
, int *v1
, int *v2
)
287 char va1
[32], va2
[32];
292 cnt
= sscanf(c
, "%s %s", va1
, va2
);
306 /* Function: Create a new Image with the specified dimensions
308 * width and height ofthe wished Image
310 * Pointer to the Created image or NULL
311 * Bugs: Not known yet
312 * NOTES: Function will only return non-NULL if all allocations could be done
313 * so you have not to check something inside the NewImage structure
315 struct NewImage
*NewImageContainer(UWORD w
, UWORD h
)
320 ni
= AllocVec(sizeof(struct NewImage
), MEMF_ANY
| MEMF_CLEAR
);
325 ni
->data
= AllocVec(w
* h
* 4, MEMF_ANY
| MEMF_CLEAR
);
326 if (ni
->data
== NULL
)
335 /* Function: Remove all Memory used by an Image
336 * Input: NewImage ni:
337 * Pointer to an Image to be deallocated
340 void DisposeImageContainer(struct NewImage
*ni
)
350 DisposeDTObject(ni
->o
);
355 /* Function: Load an Image from a file
357 * Filename of the Image to load
359 * Pointer to the Created image or NULL
360 * Bugs: Not known yet
361 * NOTES: Function will only return non-NULL if all allocations could be done
362 * so you have not to check something inside the NewImage struct.
363 * This function uses DataTypes for loading images, so be sure to have
364 * the specific DataTypes installed
366 struct NewImage
*GetImageFromFile(char *name
, struct Screen
*scr
)
369 struct BitMapHeader
*bmhd
= NULL
;
372 struct pdtBlitPixelArray pa
;
379 pic
= NewDTObject(name
, DTA_SourceType
, DTST_FILE
,
380 DTA_GroupID
, GID_PICTURE
,
381 PDTA_Remap
, FALSE
, PDTA_DestMode
, PMODE_V43
, TAG_DONE
);
384 get(pic
, PDTA_BitMapHeader
, &bmhd
);
388 h
= bmhd
->bmh_Height
;
389 mask
= bmhd
->bmh_Masking
;
390 ni
= NewImageContainer(w
, h
);
393 pa
.MethodID
= PDTM_READPIXELARRAY
;
394 pa
.pbpa_PixelData
= (APTR
) ni
->data
;
395 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
396 pa
.pbpa_PixelArrayMod
= w
* 4;
401 DoMethodA(pic
, (Msg
) & pa
);
402 if (mask
!= mskHasAlpha
)
405 for (a
= 0; a
< (w
* h
); a
++)
406 ni
->data
[a
] |= 0x000000ff;
408 for (a
= 0; a
< (w
* h
); a
++)
409 ni
->data
[a
] |= 0xff000000;
414 depth
= (ULONG
) GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_DEPTH
);
417 ni
->o
= LoadPicture(name
, scr
);
420 GetDTAttrs(ni
->o
, PDTA_DestBitMap
,
421 (IPTR
) & ni
->bitmap
, TAG_DONE
);
422 if (ni
->bitmap
== NULL
)
423 GetDTAttrs(ni
->o
, PDTA_BitMap
,
424 (IPTR
) & ni
->bitmap
, TAG_DONE
);
427 GetDTAttrs(ni
->o
, PDTA_MaskPlane
,
428 (IPTR
) & ni
->mask
, TAG_DONE
);
433 DisposeDTObject(pic
);
440 BOOL
ReadPropConfig(struct dt_node
* data
, struct Screen
* scr
)
447 file
= Open(data
->filename
, MODE_OLDFILE
);
452 line
= FGets(file
, buffer
, 256);
455 if ((v
= strstr(line
, "ContainerTop ")) == line
)
457 GetIntegers(v
, &data
->ContainerTop_o
,
458 &data
->ContainerTop_s
);
460 else if ((v
= strstr(line
, "ContainerVertTile ")) == line
)
462 GetIntegers(v
, &data
->ContainerVertTile_o
,
463 &data
->ContainerVertTile_s
);
465 else if ((v
= strstr(line
, "KnobTop ")) == line
)
467 GetIntegers(v
, &data
->KnobTop_o
, &data
->KnobTop_s
);
469 else if ((v
= strstr(line
, "KnobTileTop ")) == line
)
471 GetIntegers(v
, &data
->KnobTileTop_o
,
472 &data
->KnobTileTop_s
);
474 else if ((v
= strstr(line
, "KnobVertGripper ")) == line
)
476 GetIntegers(v
, &data
->KnobVertGripper_o
,
477 &data
->KnobVertGripper_s
);
479 else if ((v
= strstr(line
, "KnobTileBottom ")) == line
)
481 GetIntegers(v
, &data
->KnobTileBottom_o
,
482 &data
->KnobTileBottom_s
);
484 else if ((v
= strstr(line
, "KnobBottom ")) == line
)
486 GetIntegers(v
, &data
->KnobBottom_o
,
487 &data
->KnobBottom_s
);
489 else if ((v
= strstr(line
, "ContainerBottom ")) == line
)
491 GetIntegers(v
, &data
->ContainerBottom_o
,
492 &data
->ContainerBottom_s
);
494 else if ((v
= strstr(line
, "ContainerLeft ")) == line
)
496 GetIntegers(v
, &data
->ContainerLeft_o
,
497 &data
->ContainerLeft_s
);
499 else if ((v
= strstr(line
, "ContainerHorTile ")) == line
)
501 GetIntegers(v
, &data
->ContainerHorTile_o
,
502 &data
->ContainerHorTile_s
);
504 else if ((v
= strstr(line
, "KnobLeft ")) == line
)
506 GetIntegers(v
, &data
->KnobLeft_o
, &data
->KnobLeft_s
);
508 else if ((v
= strstr(line
, "KnobTileLeft ")) == line
)
510 GetIntegers(v
, &data
->KnobTileLeft_o
,
511 &data
->KnobTileLeft_s
);
513 else if ((v
= strstr(line
, "KnobHorGripper ")) == line
)
515 GetIntegers(v
, &data
->KnobHorGripper_o
,
516 &data
->KnobHorGripper_s
);
518 else if ((v
= strstr(line
, "KnobTileRight ")) == line
)
520 GetIntegers(v
, &data
->KnobTileRight_o
,
521 &data
->KnobTileRight_s
);
523 else if ((v
= strstr(line
, "KnobRight ")) == line
)
525 GetIntegers(v
, &data
->KnobRight_o
, &data
->KnobRight_s
);
527 else if ((v
= strstr(line
, "ContainerRight ")) == line
)
529 GetIntegers(v
, &data
->ContainerRight_o
,
530 &data
->ContainerRight_s
);
537 STRPTR path
= allocPath(data
->filename
);
540 BPTR lock
= Lock(path
, ACCESS_READ
);
543 BPTR oldcd
= CurrentDir(lock
);
544 data
->img_verticalcontainer
=
545 GetImageFromFile("Container/Vertical", scr
);
546 data
->img_verticalknob
= GetImageFromFile("Knob/Vertical", scr
);
547 data
->img_horizontalcontainer
=
548 GetImageFromFile("Container/Horizontal", scr
);
549 data
->img_horizontalknob
=
550 GetImageFromFile("Knob/Horizontal", scr
);
551 data
->img_up
= GetImageFromFile("ArrowUp/default", scr
);
552 data
->img_down
= GetImageFromFile("ArrowDown/default", scr
);
553 data
->img_left
= GetImageFromFile("ArrowLeft/default", scr
);
554 data
->img_right
= GetImageFromFile("ArrowRight/default", scr
);
563 if (data
->img_horizontalcontainer
&& data
->img_horizontalknob
564 && data
->img_verticalcontainer
&& data
->img_verticalknob
565 && data
->img_up
&& data
->img_down
&& data
->img_left
571 void FreePropConfig(struct dt_node
*data
)
573 DisposeImageContainer(data
->img_verticalcontainer
);
574 DisposeImageContainer(data
->img_verticalknob
);
575 DisposeImageContainer(data
->img_horizontalcontainer
);
576 DisposeImageContainer(data
->img_horizontalknob
);
577 DisposeImageContainer(data
->img_up
);
578 DisposeImageContainer(data
->img_down
);
579 DisposeImageContainer(data
->img_left
);
580 DisposeImageContainer(data
->img_right
);
584 BOOL
ReadFrameConfig(CONST_STRPTR filename
, struct dt_frame_image
*fi
,
594 file
= Open(filename
, MODE_OLDFILE
);
599 line
= FGets(file
, buffer
, 256);
602 if ((v
= strstr(line
, "TileLeft ")) == line
)
604 fi
->tile_left
= GetInt(v
);
606 else if ((v
= strstr(line
, "TileTop ")) == line
)
608 fi
->tile_top
= GetInt(v
);
610 else if ((v
= strstr(line
, "TileRight ")) == line
)
612 fi
->tile_right
= GetInt(v
);
614 else if ((v
= strstr(line
, "TileBottom ")) == line
)
616 fi
->tile_bottom
= GetInt(v
);
618 else if ((v
= strstr(line
, "InnerLeft ")) == line
)
620 fi
->inner_left
= GetInt(v
);
622 else if ((v
= strstr(line
, "InnerTop ")) == line
)
624 fi
->inner_top
= GetInt(v
);
626 else if ((v
= strstr(line
, "InnerRight ")) == line
)
628 fi
->inner_right
= GetInt(v
);
630 else if ((v
= strstr(line
, "InnerBottom ")) == line
)
632 fi
->inner_bottom
= GetInt(v
);
634 else if ((v
= strstr(line
, "NoAlpha ")) == line
)
636 fi
->noalpha
= GetBool(v
, "Yes");
644 STRPTR path
= allocPath(filename
);
647 BPTR lock
= Lock(path
, ACCESS_READ
);
650 BPTR oldcd
= CurrentDir(lock
);
651 fi
->img_up
= GetImageFromFile("up/default", scr
);
652 fi
->img_down
= GetImageFromFile("down/default", scr
);
660 if (fi
->img_up
&& fi
->img_down
)
665 void FreeFrameConfig(struct dt_frame_image
*fi
)
669 DisposeImageContainer(fi
->img_up
);
670 DisposeImageContainer(fi
->img_down
);
674 void dispose_custom_frame(struct dt_frame_image
*fi
)
683 struct dt_frame_image
*load_custom_frame(CONST_STRPTR filename
,
686 struct dt_frame_image
*fi
=
687 AllocVec(sizeof(struct dt_frame_image
), MEMF_ANY
);
691 /* special configuration image for prop gadgets */
692 if (Stricmp(FilePart(filename
), "frame.config") == 0)
694 if (ReadFrameConfig(filename
, fi
, scr
))
710 struct dt_node
*dt_load_picture(CONST_STRPTR filename
, struct Screen
*scr
)
712 struct dt_node
*node
;
713 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
720 node
= List_First(&dt_list
);
723 if (!Stricmp(filename
, node
->filename
) && scr
== node
->scr
)
726 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
729 node
= Node_Next(node
);
733 (struct dt_node
*)AllocVec(sizeof(struct dt_node
), MEMF_CLEAR
)))
736 if ((node
->filename
= StrDup(filename
)))
738 /* create the datatypes object */
739 D(bug("loading %s\n", filename
));
741 /* special configuration image for prop gadgets */
742 if ((Stricmp(FilePart(filename
), "prop.config") == 0)
743 || (Stricmp(FilePart(filename
), "config") == 0))
745 if (ReadPropConfig(node
, scr
))
748 node
->mode
= MODE_PROP
;
751 AddTail((struct List
*)&dt_list
, (struct Node
*)node
);
752 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
757 FreePropConfig(node
);
762 if ((node
->o
= LoadPicture(filename
, scr
)))
764 struct BitMapHeader
*bmhd
;
765 GetDTAttrs(node
->o
, PDTA_BitMapHeader
, (IPTR
) & bmhd
,
767 D(bug("picture %lx\n", node
->o
));
771 node
->width
= bmhd
->bmh_Width
;
772 node
->height
= bmhd
->bmh_Height
;
773 node
->mask
= bmhd
->bmh_Masking
;
774 D(bug("picture %lx = %ldx%ld\n", node
->o
,
775 node
->width
, node
->height
));
779 AddTail((struct List
*)&dt_list
, (struct Node
*)node
);
780 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
784 FreeVec(node
->filename
);
788 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
792 void dt_dispose_picture(struct dt_node
*node
)
794 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
795 if (node
&& node
->count
)
800 Remove((struct Node
*)node
);
801 if (node
->bfi
!= NULL
)
803 if (node
->bfi
->BitMap
!= NULL
)
804 FreeBitMap(node
->bfi
->BitMap
);
807 if (node
->mode
== MODE_PROP
)
808 FreePropConfig(node
);
810 DisposeDTObject(node
->o
);
811 FreeVec(node
->filename
);
815 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
818 int dt_width(struct dt_node
*node
)
826 int dt_height(struct dt_node
*node
)
834 void dt_put_on_rastport(struct dt_node
*node
, struct RastPort
*rp
, int x
,
837 struct BitMap
*bitmap
= NULL
;
838 struct pdtBlitPixelArray pa
;
848 /* WritePixelArrayAlpha is insanely expensive on slow
849 * m68k machines in planar graphics modes
851 doAlpha
= GetBitMapAttr(rp
->BitMap
, BMA_DEPTH
) > 8;
854 if (doAlpha
&& node
->mask
== mskHasAlpha
)
857 (ULONG
*) AllocVec(dt_width(node
) * dt_height(node
) * 4,
861 pa
.MethodID
= PDTM_READPIXELARRAY
;
862 pa
.pbpa_PixelData
= (UBYTE
*) img
;
863 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
864 pa
.pbpa_PixelArrayMod
= dt_width(node
) * 4;
867 pa
.pbpa_Width
= dt_width(node
);
868 pa
.pbpa_Height
= dt_height(node
);
869 DoMethodA(o
, (Msg
) & pa
);
870 WritePixelArrayAlpha(img
, 0, 0, dt_width(node
) * 4, rp
, x
, y
,
871 dt_width(node
), dt_height(node
), 0xffffffff);
877 GetDTAttrs(o
, PDTA_DestBitMap
, (IPTR
) & bitmap
, TAG_DONE
);
879 GetDTAttrs(o
, PDTA_BitMap
, (IPTR
) & bitmap
, TAG_DONE
);
885 GetDTAttrs(o
, PDTA_MaskPlane
, (IPTR
) & mask
, TAG_DONE
);
889 MyBltMaskBitMapRastPort(bitmap
, 0, 0, rp
, x
, y
,
890 dt_width(node
), dt_height(node
), 0xe0, (PLANEPTR
) mask
);
892 BltMaskBitMapRastPort(bitmap
, 0, 0, rp
, x
, y
,
893 dt_width(node
), dt_height(node
), 0xe0, (PLANEPTR
) mask
);
897 BltBitMapRastPort(bitmap
, 0, 0, rp
, x
, y
,
898 dt_width(node
), dt_height(node
), 0xc0);
903 void dt_put_mim_on_rastport(struct dt_node
*node
, struct RastPort
*rp
,
904 int x
, int y
, int state
)
906 struct BitMap
*bitmap
= NULL
;
907 struct pdtBlitPixelArray pa
;
915 int width
= dt_width(node
) >> 1;
916 if (node
->mask
== mskHasAlpha
)
919 (ULONG
*) AllocVec(dt_width(node
) * dt_height(node
) * 4,
924 int height
= dt_height(node
);
925 pa
.MethodID
= PDTM_READPIXELARRAY
;
926 pa
.pbpa_PixelData
= (UBYTE
*) img
;
927 pa
.pbpa_PixelFormat
= PBPAFMT_ARGB
;
928 pa
.pbpa_PixelArrayMod
= width
* 4;
929 pa
.pbpa_Left
= state
* width
;
931 pa
.pbpa_Width
= width
;
932 pa
.pbpa_Height
= height
;
933 DoMethodA(o
, (Msg
) & pa
);
934 WritePixelArrayAlpha(img
, 0, 0, width
* 4, rp
, x
, y
, width
,
941 GetDTAttrs(o
, PDTA_DestBitMap
, (IPTR
) & bitmap
, TAG_DONE
);
943 GetDTAttrs(o
, PDTA_BitMap
, (IPTR
) & bitmap
, TAG_DONE
);
950 GetDTAttrs(o
, PDTA_MaskPlane
, (IPTR
) & mask
, TAG_DONE
);
954 MyBltMaskBitMapRastPort(bitmap
, width
* state
, 0, rp
, x
, y
,
955 width
, dt_height(node
), 0xe0, (PLANEPTR
) mask
);
957 BltMaskBitMapRastPort(bitmap
, width
* state
, 0, rp
, x
, y
,
958 width
, dt_height(node
), 0xe0, (PLANEPTR
) mask
);
962 BltBitMapRastPort(bitmap
, width
* state
, 0, rp
, x
, y
,
963 width
, dt_height(node
), 0xc0);
970 static void CopyTiledBitMap(struct BitMap
*Src
, WORD SrcOffsetX
,
971 WORD SrcOffsetY
, WORD SrcSizeX
, WORD SrcSizeY
, struct BitMap
*Dst
,
972 struct Rectangle
*DstBounds
)
974 WORD FirstSizeX
; // the width of the rectangle to blit as the first column
975 WORD FirstSizeY
; // the height of the rectangle to blit as the first row
976 WORD SecondMinX
; // the left edge of the second column
977 WORD SecondMinY
; // the top edge of the second column
978 WORD SecondSizeX
; // the width of the second column
979 WORD SecondSizeY
; // the height of the second column
980 WORD Pos
; // used as starting position in the "exponential" blit
981 WORD Size
; // used as bitmap size in the "exponential" blit
983 // the width of the first tile, this is either the rest of the tile right
984 // to SrcOffsetX or the width of the dest rect, if the rect is narrow
985 FirstSizeX
= MIN(SrcSizeX
- SrcOffsetX
, RECTSIZEX(DstBounds
));
987 // the start for the second tile (if used)
988 SecondMinX
= DstBounds
->MinX
+ FirstSizeX
;
990 // the width of the second tile (we want the whole tile to be SrcSizeX
991 // pixels wide, if we use SrcSizeX-SrcOffsetX pixels for the left part
992 // we'll use SrcOffsetX for the right part)
993 SecondSizeX
= MIN(SrcOffsetX
, DstBounds
->MaxX
- SecondMinX
+ 1);
995 // the same values are calculated for y direction
996 FirstSizeY
= MIN(SrcSizeY
- SrcOffsetY
, RECTSIZEY(DstBounds
));
997 SecondMinY
= DstBounds
->MinY
+ FirstSizeY
;
998 SecondSizeY
= MIN(SrcOffsetY
, DstBounds
->MaxY
- SecondMinY
+ 1);
1000 // blit the first piece of the tile
1001 BltBitMap(Src
, SrcOffsetX
, SrcOffsetY
, Dst
, DstBounds
->MinX
,
1002 DstBounds
->MinY
, FirstSizeX
, FirstSizeY
, 0xC0, -1, NULL
);
1004 // if SrcOffset was 0 or the dest rect was to narrow, we won't need a
1006 if (SecondSizeX
> 0)
1007 BltBitMap(Src
, 0, SrcOffsetY
, Dst
, SecondMinX
, DstBounds
->MinY
,
1008 SecondSizeX
, FirstSizeY
, 0xC0, -1, NULL
);
1010 // is a second row necessary?
1011 if (SecondSizeY
> 0)
1013 BltBitMap(Src
, SrcOffsetX
, 0, Dst
, DstBounds
->MinX
, SecondMinY
,
1014 FirstSizeX
, SecondSizeY
, 0xC0, -1, NULL
);
1015 if (SecondSizeX
> 0)
1016 BltBitMap(Src
, 0, 0, Dst
, SecondMinX
, SecondMinY
, SecondSizeX
,
1017 SecondSizeY
, 0xC0, -1, NULL
);
1020 // this loop generates the first row of the tiles
1021 for (Pos
= DstBounds
->MinX
+ SrcSizeX
, Size
=
1022 MIN(SrcSizeX
, DstBounds
->MaxX
- Pos
+ 1); Pos
<= DstBounds
->MaxX
;)
1024 BltBitMap(Dst
, DstBounds
->MinX
, DstBounds
->MinY
, Dst
, Pos
,
1025 DstBounds
->MinY
, Size
, MIN(SrcSizeY
, RECTSIZEY(DstBounds
)),
1028 Size
= MIN(Size
<< 1, DstBounds
->MaxX
- Pos
+ 1);
1031 // this loop blit the first row down several times to fill the whole
1033 for (Pos
= DstBounds
->MinY
+ SrcSizeY
, Size
=
1034 MIN(SrcSizeY
, DstBounds
->MaxY
- Pos
+ 1); Pos
<= DstBounds
->MaxY
;)
1036 BltBitMap(Dst
, DstBounds
->MinX
, DstBounds
->MinY
, Dst
,
1037 DstBounds
->MinX
, Pos
, RECTSIZEX(DstBounds
), Size
, 0xC0, -1,
1040 Size
= MIN(Size
<< 1, DstBounds
->MaxY
- Pos
+ 1);
1044 AROS_UFH3S(void, WindowPatternBackFillFunc
,
1045 AROS_UFHA(struct Hook
*, Hook
, A0
),
1046 AROS_UFHA(struct RastPort
*, RP
, A2
),
1047 AROS_UFHA(struct BackFillMsg
*, BFM
, A1
))
1051 WORD OffsetX
; // the offset within the tile in x direction
1052 WORD OffsetY
; // the offset within the tile in y direction
1054 // get the data for our backfillhook
1055 struct BackFillInfo
*BFI
= (struct BackFillInfo
*)Hook
;
1058 putreg(12, (long)Hook
->h_Data
);
1061 // The first tile normally isn't totally visible => calculate the offset
1062 // (offset 0 would mean that the left edge of the damage rectangle
1063 // coincides with the left edge of a tile)
1064 OffsetX
= BFM
->Bounds
.MinX
- BFI
->Options
.OffsetX
;
1065 // if (BFI->Options.CenterX) // horizontal centering?
1066 // OffsetX -= (BFI->Screen->Width-BFI->Width)/2;
1068 // The same values are calculated for y direction
1069 OffsetY
= BFM
->Bounds
.MinY
- BFI
->Options
.OffsetY
;
1072 if (BFI->Options.OffsetTitleY) // shift the tiles down?
1073 OffsetY -= BFI->Screen->BarHeight+1;
1076 // if (BFI->Options.CenterY) // horizontal centering?
1077 // OffsetY -= (BFI->Screen->Height - BFI->Height)/2;
1079 CopyTiledBitMap(BFI
->BitMap
, MOD(OffsetX
+ BFI
->OffsetX
, BFI
->Width
),
1080 MOD(OffsetY
+ BFI
->OffsetY
, BFI
->Height
), BFI
->CopyWidth
,
1081 BFI
->CopyHeight
, RP
->BitMap
, &BFM
->Bounds
);
1086 static void CalculateCopySizes(struct BackFillInfo
*BFI
)
1090 BFI
->Options
.MaxCopyWidth
) ? BFI
->Width
: BFI
->Options
.
1091 MaxCopyWidth
- BFI
->Options
.MaxCopyWidth
% BFI
->Width
;
1094 BFI
->Options
.MaxCopyHeight
) ? BFI
->Height
: BFI
->Options
.
1095 MaxCopyHeight
- BFI
->Options
.MaxCopyHeight
% BFI
->Height
;
1099 **********************************************************/
1100 void dt_put_on_rastport_tiled(struct dt_node
*node
, struct RastPort
*rp
,
1101 int x1
, int y1
, int x2
, int y2
, int xoffset
, int yoffset
)
1103 struct Screen
*scr
= node
->scr
;
1104 struct BitMap
*bitmap
;
1111 GetDTAttrs(o
, PDTA_DestBitMap
, (IPTR
) & bitmap
, TAG_DONE
);
1113 GetDTAttrs(o
, PDTA_BitMap
, (IPTR
) & bitmap
, TAG_DONE
);
1117 ObtainSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);
1121 struct BackFillInfo
*bfi
=
1122 (struct BackFillInfo
*)AllocVec(sizeof(struct BackFillInfo
),
1126 LONG depth
= GetBitMapAttr(bitmap
, BMA_DEPTH
);
1127 bfi
->Hook
.h_Entry
= (HOOKFUNC
) WindowPatternBackFillFunc
;
1129 bfi
->Hook
.h_Data
= (APTR
) getreg(12); /* register A4 */
1132 bfi
->Options
.MaxCopyWidth
= 256;
1133 bfi
->Options
.MaxCopyHeight
= 256;
1134 // bfi->Options.CenterX = FALSE; /* center the tiles horizontally? */
1135 // bfi->Options.CenterY = FALSE; /* center the tiles vertically? */
1136 bfi
->Options
.OffsetX
= 0; /* offset to add */
1137 bfi
->Options
.OffsetY
= 0; /* offset to add */
1139 /* add the screen titlebar height to the vertical offset? */
1140 bfi
->Options
.OffsetTitleY
= TRUE
;
1141 bfi
->Width
= dt_width(node
);
1142 bfi
->Height
= dt_height(node
);
1144 CalculateCopySizes(bfi
);
1147 AllocBitMap(bfi
->CopyWidth
, bfi
->CopyHeight
, depth
,
1148 BMF_INTERLEAVED
| BMF_MINPLANES
,
1149 scr
->RastPort
.BitMap
)))
1151 struct Rectangle CopyBounds
;
1152 CopyBounds
.MinX
= 0;
1153 CopyBounds
.MinY
= 0;
1154 CopyBounds
.MaxX
= bfi
->CopyWidth
- 1;
1155 CopyBounds
.MaxY
= bfi
->CopyHeight
- 1;
1157 CopyTiledBitMap(bitmap
, 0, 0, bfi
->Width
, bfi
->Height
,
1158 bfi
->BitMap
, &CopyBounds
);
1166 struct BackFillInfo
*bfi
= node
->bfi
;
1167 struct Rectangle rect
;
1176 LockLayer(0, rp
->Layer
);
1177 xoffset
-= rp
->Layer
->bounds
.MinX
;
1178 yoffset
-= rp
->Layer
->bounds
.MinY
;
1181 bfi
->OffsetX
= xoffset
;
1182 bfi
->OffsetY
= yoffset
;
1184 DoHookClipRects((struct Hook
*)bfi
, rp
, &rect
);
1188 UnlockLayer(rp
->Layer
);
1191 ReleaseSemaphore(&MUIMB(MUIMasterBase
)->ZuneSemaphore
);