2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Graphics bitmap class implementation.
9 /****************************************************************************************/
14 #include <proto/exec.h>
15 #include <proto/utility.h>
16 #include <proto/oop.h>
18 #include <exec/memory.h>
19 #include <utility/tagitem.h>
21 #include <oop/static_mid.h>
22 #include <graphics/text.h>
23 #include <graphics/scale.h>
25 #include <hidd/graphics.h>
27 #include "graphics_intern.h"
33 #include <aros/debug.h>
35 /****************************************************************************************/
37 #define POINT_OUTSIDE_CLIP(gc, x, y) \
38 ( (x) < GC_CLIPX1(gc) \
39 || (x) > GC_CLIPX2(gc) \
40 || (y) < GC_CLIPY1(gc) \
41 || (y) > GC_CLIPY2(gc) )
43 /*****************************************************************************************
52 Every display driver should implement at least one bitmap class for displayable
55 Normally this class doesn't need to have public ID. In order to use it the driver
56 should pass class pointer as aoHidd_BitMap_ClassPtr value to the graphics base class
57 in its moHidd_Gfx_NewBitMap implementation.
59 BitMap base class is in C++ terminology a pure virtual
60 baseclass. It will not allocate any bitmap data at all;
61 that is up to the subclass to do.
63 The main task of the BitMap baseclass is to store some information about the bitmap
64 like its size and pixelformat. A pixelformat is an object of private class which
65 stores the actual information about the format.
67 There are two ways that we can find out the pixfmt in our moHidd_Gfx_NewBitMap
71 The tags will contain a modeid.
72 One can use this modeid to get a pointer to an
73 already registered pixfmt.
75 Non-displayable bitmap -
76 The aoHidd_BitMap_StdPixFmt or aoHidd_BitMap_Friend attribute will always be
79 *****************************************************************************************/
81 #define GOT_BM_ATTR(code) GOT_ATTR(code, aoHidd_BitMap, bitmap)
82 #define AO(x) aoHidd_BitMap_ ## x
84 #define BMAF(x) (1L << aoHidd_BitMap_ ## x)
86 #define BM_NONDISP_AF ( BMAF(Width) | BMAF(Height) | BMAF(PixFmt) )
89 #define PIXBUFBYTES (50000*4)
91 #define PIXBUF_DECLARE_VARS \
97 #define PIXBUF_ALLOC(buf,bytesperline,height) \
99 __buflines = PIXBUFBYTES / (bytesperline); \
100 if (__buflines == 0) \
104 else if (__buflines > __height) \
106 __buflines = __height; \
108 buf = AllocVec((bytesperline) * __buflines, MEMF_PUBLIC); \
109 if (!buf && (__buflines > 1)) \
112 buf = AllocVec((bytesperline), MEMF_PUBLIC); \
115 #define PIXBUF_TIME_TO_START_PROCESS (__bufy == __worky)
117 #define PIXBUF_LINES_TO_PROCESS (((__height - __bufy) > __buflines) ? \
118 __buflines : __height - __bufy )
120 #define PIXBUF_TIME_TO_END_PROCESS (((__worky - __bufy + 1) == __buflines) || \
121 (__worky == __height - 1))
123 #define PIXBUF_NEXT_LINE \
125 if ((__worky - __bufy) == __buflines) __bufy = __worky;
128 #define PIXBUF_FREE(buf) \
129 if (buf) FreeVec(buf);
131 /*****************************************************************************************
143 Specifies bitmap width in pixels.
145 Setting this attribute does not cause actual bitmap resize, just updates the information
146 about it. Use this only from within subclasses only if you know what you do. For example
147 SDL hosted driver sets it when framebufer changes the resolution.
160 *****************************************************************************************/
162 /*****************************************************************************************
174 Specifies bitmap height in pixels.
176 Setting this attribute does not cause actual bitmap resize, just updates the information
177 about it. Use this only from within subclasses only if you know what you do. For example
178 SDL hosted driver sets it when framebufer changes the resolution.
191 *****************************************************************************************/
193 /*****************************************************************************************
196 aoHidd_BitMap_Displayable
205 The bitmap is displayable. A displayable bitmap is always managed by a display
206 driver and must have valid display mode ID specification.
208 If this attribute is not supplied during bitmap creation, its value defaults
222 *****************************************************************************************/
224 /*****************************************************************************************
227 aoHidd_BitMap_Visible
236 Check if the bitmap is currently visible on screen
243 Not all display drivers implement this attribute. No AROS components currently rely
249 Some drivers may choose to have this attribute internally setable. Do not rely on it
250 in any way and do not attempt to set it manually from within applications, this will
251 not do any nice things.
253 *****************************************************************************************/
255 /*****************************************************************************************
258 aoHidd_BitMap_IsLinearMem
267 Check if the bitmap provides linear memory access. This means that bitmap's
268 pixelbuffer is directly addressable by the CPU.
270 Bitmaps with no linear memory may implement moHidd_BitMap_ObtainDirectAccess,
271 but this means that this method will rely on mirrored buffer. In such a case
272 the user must call moHidd_BitMap_UpdateRect after modifying bitmap's contents.
275 Used by cybergraphics.library/GetCyberMapAttr() for providing CYBRMATTR_ISLINEARMEM
281 Currently no display drivers implement this attribute despite many native mode
282 drivers actually provide linear memory.
285 moHidd_BitMap_ObtainDirectAccess, moHidd_BitMap_ReleaseDirectAccess,
286 moHidd_BitMap_UpdateRect
290 *****************************************************************************************/
292 /*****************************************************************************************
295 aoHidd_BitMap_BytesPerRow
304 Query number of bytes per row in the bitmap storage buffer
307 The returned value includes possible padding needed for alignment.
317 *****************************************************************************************/
319 /*****************************************************************************************
322 aoHidd_BitMap_ColorMap
331 Return associated colormap (palette) object.
333 By default only displayable bitmaps have colormaps. However a colormap can be attached
334 to any bitmap using moHidd_BitMap_SetColors or moHidd_BitMap_SetColorMap.
336 Note that manual attaching of a colormap to a nondisplayable bitmap may cause undesired
337 side-effects on graphics.library behavior. It's better not to do this at all. The system
338 knows what it does better than you.
347 moHidd_BitMap_SetColorMap, moHidd_BitMap_SetColors.
351 *****************************************************************************************/
353 /*****************************************************************************************
365 Specify a friend bitmap. The bitmap will be allocated so that it
366 is optimized for blitting to this bitmap.
368 Display drivers may query this attribute and then query friend bitmap
369 for anything they want (like pixelformat, mode ID, etc).
371 Note that explicit specification of mode ID and/or standard pixelformat
372 should override defaults provided by friend bitmap (i.e. actually breaking
385 *****************************************************************************************/
387 /*****************************************************************************************
390 aoHidd_BitMap_GfxHidd
399 Specify display driver object this bitmap was created with.
401 Normally the user doesn't have to supply this attribute. Instead you should use
402 driver's moHidd_Gfx_NewBitMap method in order to create bitmaps. In this case
403 aoHidd_BitMap_GfxHidd attribute will be provided by graphics driver base class
404 with the correct value.
406 It is illegal to manually create bitmap objects with no driver associated.
407 graphics.library maintains at least a memory driver for nondisplayable
408 bitmaps in system RAM without any acceleration.
417 CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
421 *****************************************************************************************/
423 /*****************************************************************************************
426 aoHidd_BitMap_StdPixFmt
429 [I..], HIDDT_StdPixFmt
435 Specify standard pixelformat code (one of vHidd_StdPixFmt_... values) for the
438 Values less than num_Hidd_PseudoStdPixFmt are illegal for this attribute.
440 Actually the bitmap class itself ignores this attribute. It is processed by
441 CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap method in order to look up a corresponding
442 pixelformat object in the system's database.
445 Bitmaps with this attribute set should be created as RAM bitmaps with direct CPU
446 access. It is not recommended to replace them with, for example, virtual surfaces on
447 hosted AROS. Such bitmaps are expected to be directly addressable and breaking
448 this may cause undesired side effects.
455 aoHidd_BitMap_PixFmt, CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
458 Currently all display drivers omit specifying own bitmap class for bitmaps with this
459 attribute set, letting base class (actually memory driver) to select an appropriate
460 class for it. This way it ends up in a bitmap of CLID_Hidd_ChunkyBM or CLID_Hidd_PlanarBM
461 class. It is recommended to follow this rule. It's not prohibited, however, to do some
462 adjustments to the bitmap (like alignment) in order to optimize blitting to/from it.
463 In fact if the display driver was asked to create such a bitmap, this means that
464 the standard bitmap is being created as a friend of some bitmap which was allocated
465 using this driver. This way the bitmap is expected to be friendly to this driver.
467 *****************************************************************************************/
469 /*****************************************************************************************
481 Returns pixelformat descriptor object associated with the bitmap.
483 Every bitmap has some associated pixelformat object. Pixelformat objects are
484 shared data storages, so many bitmaps may refer to the same pixelformat objects.
496 *****************************************************************************************/
498 /*****************************************************************************************
510 Specify display mode ID for displayable bitmap.
512 A displayable bitmap must have this attribute supplied with valid value. A nondisplayable
513 one may miss it, however it may remember it if it was created as a friend of displayable
514 one. This way you may create another displayable bitmap as a friend of nondisplayable
515 one which in turn is a friend of displayable one.
527 *****************************************************************************************/
529 /*****************************************************************************************
532 aoHidd_BitMap_ClassPtr
541 Explicitly specify bitmap's class pointer.
543 This attribute is simply remembered by bitmap base class. Its main purpose is to let
544 graphics driver base class to select a class on which to call OOP_NewObject() in
545 its moHidd_Gfx_NewBitMap implementation.
547 If neither this attribute nor aoHidd_BitMap_ClassID attribute is provided for
548 moHidd_Gfx_NewBitMap, graphics base class will do its best in order to find out the
549 correct class based on aoHidd_StdPixFmt attribute value or aoHidd_BitMap_ClassPtr value
559 aoHidd_BitMap_ClassID, CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
563 *****************************************************************************************/
565 /*****************************************************************************************
568 aoHidd_BitMap_ClassID
577 Explicitly specify bitmap's class ID.
579 The purpose of this attribute is to let graphics driver base class to select a class
580 on which to call OOP_NewObject() in its moHidd_Gfx_NewBitMap implementation.
582 If neither this attribute nor aoHidd_BitMap_ClassPtr attribute is provided for
583 moHidd_Gfx_NewBitMap, graphics base class will do its best in order to find out the
584 correct class based on aoHidd_StdPixFmt attribute value or aoHidd_BitMap_ClassPtr value
592 The pointer to a given class will not be remembered as aoHidd_BitMap_ClassPtr value.
595 aoHidd_BitMap_ClassPtr, CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
599 *****************************************************************************************/
601 /*****************************************************************************************
604 aoHidd_BitMap_PixFmtTags
613 Only used by subclasses of BitMap class.
625 *****************************************************************************************/
627 /*****************************************************************************************
630 aoHidd_BitMap_FrameBuffer
639 Specifies that the bitmap is a framebuffer bitmap.
641 A detailed description of a framebuffer is given in CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
642 and in CLID_Hidd_Gfx/moHidd_Gfx_Show documentation.
644 Specifying this attribute to moHidd_Gfx_NewBitMap method causes also implicit setting
645 of aoHidd_BitMap_Displayable to TRUE.
657 *****************************************************************************************/
659 /*****************************************************************************************
662 aoHidd_BitMap_LeftEdge
671 Controls horizontal position of a scrollable screen bitmap.
673 Size of displayable bitmaps may differ from actual screen size. In this case the
674 bitmap can be scrolled around the whole display area. If the bitmap is larger than
675 the display, only its part can be visible.
677 Setting this attribute causes changing left origin point of the bitmap. The value
678 of this attribute represents an offset from the physical edge of the display to the
679 logical edge of the bitmap. This means that if a large bitmap scrolls to the left in
680 order to reveal its right part, the offset will be negative. If the bitmap scrolls
681 to the left (possibly revealing another bitmap behind it), the offset will be positive.
683 It's up to the display driver to set scroll limits. If the value of the attribute
684 becomes unacceptable for any reason, the driver should adjust it and provide the real
685 resulting value back.
688 Implementing screen scrolling does not enforce to implement screen composition, despite
689 the composition is really based on scrolling (in case of composition scrolling a bitmap
690 off-display is expected to reveal another bitmap behing it instead of empty space).
697 aoHidd_BitMap_TopEdge
700 Base class will always provide zero value for this attribute and ignore all attempts
701 to set it. This means that by default bitmaps don't scroll and this needs explicit
702 implementation in the display driver.
704 *****************************************************************************************/
706 /*****************************************************************************************
709 aoHidd_BitMap_TopEdge
718 Controls vertical position of a scrollable screen bitmap.
720 Size of displayable bitmaps may differ from actual screen size. In this case the
721 bitmap can be scrolled around the whole display area. If the bitmap is larger than
722 the display, only its part can be visible.
724 Setting this attribute causes changing top origin point of the bitmap. The value
725 of this attribute represents an offset from the physical edge of the display to the
726 logical edge of the bitmap. This means that if a large bitmap scrolls upwards in
727 order to reveal its bottom part, the offset will be negative. If the bitmap scrolls
728 downdards (possibly revealing another bitmap behind it), the offset will be positive.
730 It's up to the display driver to set scroll limits. If the value of the attribute
731 becomes unacceptable for any reason, the driver should adjust it and provide the real
732 resulting value back.
735 Implementing screen scrolling does not enforce to implement screen composition, despite
736 the composition is really based on scrolling (in case of composition scrolling a bitmap
737 off-display is expected to reveal another bitmap behing it instead of empty space).
747 *****************************************************************************************/
749 /*****************************************************************************************
761 Specify number of pixels to align bitmap data width to.
763 This attribute can be added in CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap implementation
764 in order to enforce alignment needed for example by blitting hardware.
776 *****************************************************************************************/
778 /****************************************************************************************/
780 OOP_Object
*BM__Root__New(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_New
*msg
)
782 EnterFunc(bug("BitMap::New()\n"));
784 obj
= (OOP_Object
*) OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
) msg
);
788 struct TagItem colmap_tags
[] =
790 { aHidd_ColorMap_NumEntries
, 16 },
793 struct HIDDBitMapData
*data
;
796 DECLARE_ATTRCHECK(bitmap
);
797 IPTR attrs
[num_Total_BitMap_Attrs
] = {0};
799 data
= OOP_INST_DATA(cl
, obj
);
801 /* clear all data and set some default values */
802 memset(data
, 0, sizeof(struct HIDDBitMapData
));
804 attrs
[AO(Align
)] = 16;
809 data
->displayable
= FALSE
;
810 data
->pf_registered
= FALSE
;
811 data
->modeid
= vHidd_ModeID_Invalid
;
813 if (0 != OOP_ParseAttrs(msg
->attrList
, attrs
, num_Total_BitMap_Attrs
,
814 &ATTRCHECK(bitmap
), HiddBitMapAttrBase
))
816 D(bug("!!! ERROR PARSING ATTRS IN BitMap::New() !!!\n"));
817 D(bug("!!! NUMBER OF ATTRS IN IF: %d !!!\n", num_Total_BitMap_Attrs
));
823 if (!GOT_BM_ATTR(GfxHidd
))
825 D(bug("!!!! BM CLASS DID NOT GET GFX HIDD !!!\n"));
826 D(bug("!!!! The reason for this is that the gfxhidd subclass NewBitmap() method\n"));
827 D(bug("!!!! has not left it to the baseclass to actually create the object,\n"));
828 D(bug("!!!! but rather done it itself. This MUST be corrected in the gfxhidd subclass\n"));
829 D(bug("!!!! ATTRCHECK: %p !!!!\n", ATTRCHECK(bitmap
)));
835 data
->gfxhidd
= (OOP_Object
*)attrs
[AO(GfxHidd
)];
839 /* Save pointer to friend bitmap */
840 if (GOT_BM_ATTR(Friend
))
841 data
->friend = (OOP_Object
*)attrs
[AO(Friend
)];
845 if ( attrs
[AO(Displayable
)] )
847 /* We should allways get modeid, but we check anyway */
848 if (!GOT_BM_ATTR(ModeID
))
850 D(bug("!!! BitMap:New() DID NOT GET MODEID FOR DISPLAYABLE BITMAP !!!\n"));
856 OOP_Object
*sync
, *pf
;
858 modeid
= (HIDDT_ModeID
)attrs
[AO(ModeID
)];
860 if (!HIDD_Gfx_GetMode(data
->gfxhidd
, modeid
, &sync
, &pf
))
862 D(bug("!!! BitMap::New() RECEIVED INVALID MODEID %p\n", modeid
));
869 /* Update the bitmap with data from the modeid */
870 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &width
);
871 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &height
);
874 data
->height
= height
;
875 data
->displayable
= TRUE
;
877 /* The PixFmt is allready registered and locked in the PixFmt database */
878 data
->prot
.pixfmt
= pf
;
884 if (BM_NONDISP_AF
!= (BM_NONDISP_AF
& ATTRCHECK(bitmap
)))
887 * One of Width, Height and PixFmt is not set.
888 * This is either a mailformed call, or empty planar BitMap object
889 * for late initialization.
890 * In the latter case we'll specify aHidd_PlanarBM_AllocPlanes, FALSE.
892 BOOL planes_alloced
= GetTagData(aHidd_PlanarBM_AllocPlanes
, TRUE
, msg
->attrList
);
896 D(bug("!!! BitMap:New(): NO PIXFMT FOR NONDISPLAYABLE BITMAP !!!\n"));
902 data
->prot
.pixfmt
= (OOP_Object
*)attrs
[AO(PixFmt
)];
906 if (GOT_BM_ATTR(Width
))
907 data
->width
= attrs
[AO(Width
)];
908 if (GOT_BM_ATTR(Height
))
909 data
->height
= attrs
[AO(Height
)];
910 if (GOT_BM_ATTR(Depth
))
911 data
->reqdepth
= attrs
[AO(Depth
)];
917 * Calculate suggested bytes per row value based on requested alignment and
918 * pixelformat's bytes per pixel value.
919 * PixFmt will be NULL in case of late initialization.
921 if (data
->prot
.pixfmt
)
923 ULONG align
= attrs
[AO(Align
)] - 1;
924 ULONG width
= (data
->width
+ align
) & ~align
;
925 IPTR bytesperpixel
, stdpf
;
927 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_BytesPerPixel
, &bytesperpixel
);
928 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_StdPixFmt
, &stdpf
);
930 if (stdpf
== vHidd_StdPixFmt_Plane
)
933 * Planar format actually have 8 pixels per one byte.
934 * However bytesperpixel == 1 for them. Perhaps this should
937 data
->bytesPerRow
= width
>> 3;
941 data
->bytesPerRow
= width
* bytesperpixel
;
945 /* initialize the direct method calling */
947 if (GOT_BM_ATTR(ModeID
))
948 data
->modeid
= attrs
[AO(ModeID
)];
949 data
->classptr
= (OOP_Class
*)attrs
[AO(ClassPtr
)];
951 #if USE_FAST_PUTPIXEL
952 data
->putpixel
= (IPTR (*)(OOP_Class
*, OOP_Object
*, struct pHidd_BitMap_PutPixel
*))
953 OOP_GetMethod(obj
, CSD(cl
)->putpixel_mid
);
954 if (NULL
== data
->putpixel
)
958 #if USE_FAST_GETPIXEL
959 data
->getpixel
= (IPTR (*)(OOP_Class
*, OOP_Object
*, struct pHidd_BitMap_GetPixel
*))
960 OOP_GetMethod(obj
, CSD(cl
)->getpixel_mid
);
961 if (NULL
== data
->getpixel
)
965 #if USE_FAST_DRAWPIXEL
966 data
->drawpixel
= (IPTR (*)(OOP_Class
*, OOP_Object
*, struct pHidd_BitMap_DrawPixel
*))
967 OOP_GetMethod(obj
, CSD(cl
)->drawpixel_mid
);
968 if (NULL
== data
->drawpixel
)
972 /* Try to create the colormap */
974 /* stegerg: Only add a ColorMap for a visible bitmap (screen). This
975 is important because one can create for example a bitmap
976 in PIXFMT_LUT8 without friend bitmap and then copy this
977 bitmap to a 16 bit screen. During copy the screen bitmap
978 CLUT must be used, which would not happen if our PIXFMT_LUT8
979 also had a colormap itself because then bltbitmap would use the
980 colormap of the PIXFMT_LUT8 bitmap as lookup, which in this
981 case would just cause everything to become black in the
982 destination (screen) bitmap, because noone ever sets up the
983 colormap of the PIXFMT_LUT8 bitmap */
985 if (data
->displayable
)
987 data
->colmap
= OOP_NewObject(NULL
, CLID_Hidd_ColorMap
, colmap_tags
);
988 if (NULL
== data
->colmap
)
998 dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
1000 OOP_CoerceMethod(cl
, obj
, (OOP_Msg
)&dispose_mid
);
1006 } /* if (NULL != obj) */
1008 ReturnPtr("BitMap::New", OOP_Object
*, obj
);
1011 /****************************************************************************************/
1013 void BM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*obj
, OOP_Msg
*msg
)
1015 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
1017 EnterFunc(bug("BitMap::Dispose()\n"));
1019 if (NULL
!= data
->colmap
)
1020 OOP_DisposeObject(data
->colmap
);
1022 D(bug("Calling super\n"));
1024 /* Release the previously registered pixel format */
1025 if (data
->pf_registered
)
1026 HIDD_Gfx_ReleasePixFmt(data
->gfxhidd
, data
->prot
.pixfmt
);
1028 OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
) msg
);
1030 ReturnVoid("BitMap::Dispose");
1033 /****************************************************************************************/
1035 VOID
BM__Root__Get(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_Get
*msg
)
1037 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
1040 EnterFunc(bug("BitMap::Get() attrID: %i storage: %p\n", msg
->attrID
, msg
->storage
));
1042 if(IS_BITMAP_ATTR(msg
->attrID
, idx
))
1046 case aoHidd_BitMap_Width
:
1047 *msg
->storage
= data
->width
;
1048 D(bug(" width: %i\n", data
->width
));
1051 case aoHidd_BitMap_Height
:
1052 *msg
->storage
= data
->height
;
1055 case aoHidd_BitMap_Depth
:
1056 *msg
->storage
= data
->reqdepth
;
1059 case aoHidd_BitMap_Displayable
:
1060 *msg
->storage
= (IPTR
) data
->displayable
;
1063 case aoHidd_BitMap_PixFmt
:
1064 *msg
->storage
= (IPTR
)data
->prot
.pixfmt
;
1067 case aoHidd_BitMap_Friend
:
1068 *msg
->storage
= (IPTR
)data
->friend;
1071 case aoHidd_BitMap_ColorMap
:
1072 *msg
->storage
= (IPTR
)data
->colmap
;
1076 case aoHidd_BitMap_Depth
:
1077 if (NULL
!= data
->prot
.pixfmt
)
1079 *msg
->storage
= ((HIDDT_PixelFormat
*)data
->prot
.pixfmt
)->depth
;
1083 *msg
->storage
= data
->reqdepth
;
1089 case aoHidd_BitMap_GfxHidd
:
1090 *msg
->storage
= (IPTR
)data
->gfxhidd
;
1093 case aoHidd_BitMap_ModeID
:
1094 *msg
->storage
= data
->modeid
;
1097 case aoHidd_BitMap_BytesPerRow
:
1098 *msg
->storage
= data
->bytesPerRow
;
1101 /* Generic bitmaps don't scroll. This has to be implemented
1103 case aoHidd_BitMap_LeftEdge
:
1104 case aoHidd_BitMap_TopEdge
:
1108 case aoHidd_BitMap_ClassPtr
:
1109 *msg
->storage
= (IPTR
)data
->classptr
;
1113 D(bug("UNKNOWN ATTR IN BITMAP BASECLASS: %d\n", idx
));
1114 OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
) msg
);
1120 OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
) msg
);
1123 ReturnVoid("BitMap::Get");
1126 /****************************************************************************************/
1128 #define UB(x) ((UBYTE *)x)
1130 /*****************************************************************************************
1133 moHidd_BitMap_SetColors
1136 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetColors *msg);
1138 BOOL HIDD_BM_SetColors (OOP_Object *obj, HIDDT_Color *colors,
1139 ULONG firstColor, ULONG numColors);
1142 hidd.graphics.bitmap
1145 Sets values for one or more colors in the colormap object associated with the
1148 The colormap will be created if it does not exist.
1150 Only ARGB values from the source array are taken into account. pixval member is
1151 updated with the real pixel value for every color.
1154 obj - A bitmap object whose colormap needs to be set
1155 colors - A pointer to source data array
1156 firstColor - Number of the first color to set
1157 numColors - Number of subsequent colors to set
1160 TRUE on success, FALSE in case of some error (like out of memory)
1169 CLID_Hidd_ColorMap/moHidd_ColorMap_SetColors
1173 *****************************************************************************************/
1175 BOOL
BM__Hidd_BitMap__SetColors(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_SetColors
*msg
)
1177 /* Copy the colors into the internal buffer */
1178 struct HIDDBitMapData
*data
;
1180 data
= OOP_INST_DATA(cl
, o
);
1182 /* Subclass has initialized HIDDT_Color->pixelVal field and such.
1183 Just copy it into the colortab.
1186 if (NULL
== data
->colmap
)
1188 struct TagItem colmap_tags
[] =
1190 { aHidd_ColorMap_NumEntries
, 0 },
1194 colmap_tags
[0].ti_Data
= msg
->firstColor
+ msg
->numColors
;
1195 data
->colmap
= OOP_NewObject(NULL
, CLID_Hidd_ColorMap
, colmap_tags
);
1198 if (NULL
== data
->colmap
)
1203 /* Use the colormap class to set the colors */
1204 return HIDD_CM_SetColors(data
->colmap
, msg
->colors
,
1205 msg
->firstColor
, msg
->numColors
,
1210 /*****************************************************************************************
1213 moHidd_BitMap_DrawPixel
1216 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPixel *msg);
1218 ULONG HIDD_BM_DrawPixel(OOP_Object *obj, OOP_Object *gc, WORD x, WORD y);
1221 hidd.graphics.bitmap
1224 Changes the pixel at (x,y). The color of the pixel depends on the
1225 attributes of gc, eg. colors, drawmode, colormask etc.
1226 This function does not check the coordinates.
1229 obj - A bitmap to draw on
1230 gc - A GC (graphics context) object to use for drawing
1231 x, y - Coordinates of the pixel to draw
1234 Undefined. Many drivers declare this method as void.
1247 - Support for shapeplane.
1250 *****************************************************************************************/
1252 ULONG
BM__Hidd_BitMap__DrawPixel(OOP_Class
*cl
, OOP_Object
*obj
,
1253 struct pHidd_BitMap_DrawPixel
*msg
)
1255 HIDDT_Pixel src
, dest
, val
;
1256 HIDDT_DrawMode mode
;
1257 HIDDT_Pixel writeMask
;
1259 #if USE_FAST_PUTPIXEL
1260 struct pHidd_BitMap_PutPixel p
;
1263 /* EnterFunc(bug("BitMap::DrawPixel() x: %i, y: %i\n", msg->x, msg->y));
1266 Example: Pixels which bits are set to 0 in the colMask must be
1269 data->colMask = 001111
1273 writeMask = ~data->colMask & dest
1277 dest = data->fg && dest = 010100
1280 dest = dest & (writeMask | data->ColMask)
1281 = 010100 & (100000 | 001111)
1286 dest = dest | writeMask;
1297 #if OPTIMIZE_DRAWPIXEL_FOR_COPY
1298 if (vHidd_GC_DrawMode_Copy
== mode
&& GC_COLMASK(gc
) == ~0)
1306 dest
= HIDD_BM_GetPixel(obj
, msg
->x
, msg
->y
);
1307 writeMask
= ~GC_COLMASK(gc
) & dest
;
1311 if(mode
& 1) val
= ( src
& dest
);
1312 if(mode
& 2) val
= ( src
& ~dest
) | val
;
1313 if(mode
& 4) val
= (~src
& dest
) | val
;
1314 if(mode
& 8) val
= (~src
& ~dest
) | val
;
1316 val
= (val
& (writeMask
| GC_COLMASK(gc
) )) | writeMask
;
1318 #if OPTIMIZE_DRAWPIXEL_FOR_COPY
1322 #if USE_FAST_PUTPIXEL
1323 p
.mID
= CSD(cl
)->putpixel_mid
;
1330 HIDD_BM_PutPixel(obj
, msg
->x
, msg
->y
, val
);
1333 /* ReturnInt("BitMap::DrawPixel ", ULONG, 1); */ /* in quickmode return always 1 */
1338 /*****************************************************************************************
1341 moHidd_BitMap_DrawLine
1344 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPixel *msg);
1346 VOID HIDD_BM_DrawLine(OOP_Object *obj, OOP_Object *gc, WORD x1, WORD y1,
1350 hidd.graphics.bitmap
1353 Draws a line from (x1,y1) to (x2,y2) in the specified gc.
1354 The function does not clip the line against the drawing area.
1357 obj - A bitmap to draw on
1358 gc - A graphics context object to use
1359 x1,y1 - start point of the line in pixels
1360 x2,y2 - end point of the line in pixels
1374 Uses midpoint line ("Bresenham") algorithm([FOL90] 3.2.2)
1376 TODO Support for line pattern
1377 Optimize remove if t == 1 ...
1378 Implement better clipping: Should be no reason to calculate
1379 more than the part of the line that is inside the cliprect
1381 *****************************************************************************************/
1383 VOID BM__Hidd_BitMap__DrawLine
1385 OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawLine
*msg
1388 WORD dx
, dy
, incrE
, incrNE
, d
, x
, y
, s1
, s2
, t
, i
;
1389 LONG x1
, y1
, x2
, y2
;
1390 UWORD maskLine
; /* for line pattern */
1391 ULONG fg
; /* foreground pen */
1397 /* bug("BitMap::DrawLine()\n");
1398 */ EnterFunc(bug("BitMap::DrawLine() x1: %i, y1: %i x2: %i, y2: %i\n", msg
->x1
, msg
->y1
, msg
->x2
, msg
->y2
));
1401 doclip
= GC_DOCLIP(gc
);
1402 opaque
= (GC_COLEXP(gc
) & vHidd_GC_ColExp_Opaque
) ? TRUE
: FALSE
;
1405 maskLine
= 1 << GC_LINEPATCNT(gc
);
1409 /* If line is not inside cliprect, then just return */
1410 /* Normalize coords */
1411 if (msg
->x1
> msg
->x2
)
1413 x1
= msg
->x2
; x2
= msg
->x1
;
1417 x1
= msg
->x1
; x2
= msg
->x2
;
1420 if (msg
->y1
> msg
->y2
)
1422 y1
= msg
->y2
; y2
= msg
->y1
;
1426 y1
= msg
->y1
; y2
= msg
->y2
;
1429 if ( x1
> GC_CLIPX2(gc
)
1430 || x2
< GC_CLIPX1(gc
)
1431 || y1
> GC_CLIPY2(gc
)
1432 || y2
< GC_CLIPY1(gc
) )
1435 /* Line is not inside cliprect, so just return */
1449 Horizontal line drawing code.
1453 /* Don't swap coordinates if x2 < x1! Because of linepattern! */
1466 for(i
= x1
; i
!= x2
; i
+= dx
)
1468 /* Pixel inside ? */
1470 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, i
, y
))
1472 if(GC_LINEPAT(gc
) & maskLine
)
1474 HIDD_BM_DrawPixel(obj
, gc
, i
, y
);
1478 GC_FG(gc
) = GC_BG(gc
);
1479 HIDD_BM_DrawPixel(obj
, gc
, i
, y
);
1484 maskLine
= maskLine
>> 1;
1485 if (!maskLine
) maskLine
= 1L << 15;
1491 Vertical line drawing code.
1495 /* Don't swap coordinates if y2 < y1! Because of linepattern! */
1508 for(i
= y1
; i
!= y2
; i
+= dy
)
1510 /* Pixel inside ? */
1511 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, x
, i
))
1513 if(GC_LINEPAT(gc
) & maskLine
)
1515 HIDD_BM_DrawPixel(obj
, gc
, x
, i
);
1519 GC_FG(gc
) = GC_BG(gc
);
1520 HIDD_BM_DrawPixel(obj
, gc
, x
, i
);
1525 maskLine
= maskLine
>> 1;
1526 if (!maskLine
) maskLine
= 1L << 15;
1533 Generic line drawing code.
1535 /* Calculate slope */
1539 /* which direction? */
1540 if((x2
- x1
) > 0) s1
= 1; else s1
= - 1;
1541 if((y2
- y1
) > 0) s2
= 1; else s2
= - 1;
1543 /* change axes if dx < dy */
1556 d
= 2 * dy
- dx
; /* initial value of d */
1558 incrE
= 2 * dy
; /* Increment use for move to E */
1559 incrNE
= 2 * (dy
- dx
); /* Increment use for move to NE */
1563 for(i
= 0; i
<= dx
; i
++)
1565 /* Pixel inside ? */
1566 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, x
, y
))
1568 if(GC_LINEPAT(gc
) & maskLine
)
1570 HIDD_BM_DrawPixel(obj
, gc
, x
, y
);
1574 GC_FG(gc
) = GC_BG(gc
);
1575 HIDD_BM_DrawPixel(obj
, gc
, x
, y
);
1600 maskLine
= maskLine
>> 1;
1601 if (!maskLine
) maskLine
= 1L << 15;
1606 ReturnVoid("BitMap::DrawLine ");
1609 /*****************************************************************************************
1612 moHidd_BitMap_DrawRect
1615 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawRect *msg);
1617 VOID HIDD_BM_DrawRect (OOP_Object *obj, OOP_Object *gc, WORD minX, WORD minY,
1618 WORD maxX, WORD maxY);
1621 hidd.graphics.bitmap
1624 Draws a hollow rectangle. minX and minY specifies the upper
1625 left corner of the rectangle. minY and maxY specifies the lower
1626 right corner of the rectangle.
1627 The function does not clip the rectangle against the drawing area.
1630 obj - A bitmap to draw on
1631 gc - A GC object to use for drawing
1632 minX, minY - upper left corner of the rectangle in pixels
1633 maxX, maxY - lower right corner of the rectangle in pixels
1639 This method is not used by the system and considered reserved.
1651 *****************************************************************************************/
1653 VOID
BM__Hidd_BitMap__DrawRect(OOP_Class
*cl
, OOP_Object
*obj
,
1654 struct pHidd_BitMap_DrawRect
*msg
)
1657 OOP_Object
*gc
= msg
->gc
;
1660 EnterFunc(bug("BitMap::DrawRect()"));
1662 if(msg
->minX
== msg
->maxX
) addX
= 0; else addX
= 1;
1663 if(msg
->minY
== msg
->maxY
) addY
= 0; else addY
= 1;
1665 HIDD_BM_DrawLine(obj
, gc
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->minY
);
1666 HIDD_BM_DrawLine(obj
, gc
, msg
->maxX
, msg
->minY
+ addY
, msg
->maxX
, msg
->maxY
);
1667 HIDD_BM_DrawLine(obj
, gc
, msg
->maxX
- addX
, msg
->maxY
, msg
->minX
, msg
->maxY
);
1668 HIDD_BM_DrawLine(obj
, gc
, msg
->minX
, msg
->maxY
- addY
, msg
->minX
, msg
->minY
+ addY
);
1671 ReturnVoid("BitMap::DrawRect");
1674 /*****************************************************************************************
1677 moHidd_BitMap_FillRect
1680 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawRect *msg);
1682 VOID HIDD_BM_FillRect (OOP_Object *obj, OOP_Object *gc, WORD minX, WORD minY,
1683 WORD maxX, WORD maxY);
1686 hidd.graphics.bitmap
1690 Draws a solid rectangle. minX and minY specifies the upper
1691 left corner of the rectangle. minY and maxY specifies the lower
1692 right corner of the rectangle.
1693 The function does not clip the rectangle against the drawing area.
1696 obj - A bitmap to draw on
1697 gc - A GC object to use for drawing
1698 minX, minY - upper left corner of the rectangle in pixels
1699 maxX, maxY - lower right corner of the rectangle in pixels
1717 *****************************************************************************************/
1719 VOID
BM__Hidd_BitMap__FillRect(OOP_Class
*cl
, OOP_Object
*obj
,
1720 struct pHidd_BitMap_DrawRect
*msg
)
1722 OOP_Object
*gc
= msg
->gc
;
1726 EnterFunc(bug("BitMap::FillRect()"));
1728 linepat
= GC_LINEPAT(gc
);
1729 GC_LINEPAT(gc
) = ~0;
1731 for(; y
<= msg
->maxY
; y
++)
1733 HIDD_BM_DrawLine(obj
, gc
, msg
->minX
, y
, msg
->maxX
, y
);
1736 GC_LINEPAT(gc
) = linepat
;
1738 ReturnVoid("BitMap::FillRect");
1741 /*****************************************************************************************
1744 moHidd_BitMap_DrawEllipse
1747 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawEllipse *msg);
1749 VOID HIDD_BM_DrawEllipse (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
1753 hidd.graphics.bitmap
1756 Draws a hollow ellipse from the center point (x,y) with the radii
1757 rx and ry in the specified bitmap.
1758 The function does not clip the ellipse against the drawing area.
1761 obj - A bitmap to draw on
1762 gc - A GC object to use for drawing
1763 x,y - Coordinates of center point in pixels
1764 rx,ry - ry and ry radius in pixels
1774 Because of overflow the current code do not work with big
1775 values of rx and ry.
1784 *****************************************************************************************/
1786 /* TODO: Try to opimize clipping here */
1788 VOID
BM__Hidd_BitMap__DrawEllipse(OOP_Class
*cl
, OOP_Object
*obj
,
1789 struct pHidd_BitMap_DrawEllipse
*msg
)
1791 OOP_Object
*gc
= msg
->gc
;
1792 WORD x
= msg
->rx
, y
= 0; /* ellipse points */
1794 /* intermediate terms to speed up loop */
1795 LONG t1
= msg
->rx
* msg
->rx
, t2
= t1
<< 1, t3
= t2
<< 1;
1796 LONG t4
= msg
->ry
* msg
->ry
, t5
= t4
<< 1, t6
= t5
<< 1;
1797 LONG t7
= msg
->rx
* t5
, t8
= t7
<< 1, t9
= 0L;
1798 LONG d1
= t2
- t7
+ (t4
>> 1); /* error terms */
1799 LONG d2
= (t1
>> 1) - t8
+ t5
;
1801 BOOL doclip
= GC_DOCLIP(gc
);
1804 EnterFunc(bug("BitMap::DrawEllipse()"));
1806 while (d2
< 0) /* til slope = -1 */
1808 /* draw 4 points using symmetry */
1813 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
+ y
))
1814 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1816 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
- y
))
1817 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1819 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
+ y
))
1820 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1822 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
- y
))
1823 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1828 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1829 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1830 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1831 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1834 y
++; /* always move up here */
1836 if (d1
< 0) /* move straight up */
1841 else /* move up and left */
1845 d1
= d1
+ t9
+ t2
- t8
;
1846 d2
= d2
+ t9
+ t5
- t8
;
1850 do /* rest of top right quadrant */
1852 /* draw 4 points using symmetry */
1857 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
+ y
))
1858 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1860 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
- y
))
1861 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1863 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
+ y
))
1864 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1866 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
- y
))
1867 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1873 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1874 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1875 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1876 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1880 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1881 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1882 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1883 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1885 x
--; /* always move left here */
1887 if (d2
< 0) /* move up and left */
1891 d2
= d2
+ t9
+ t5
- t8
;
1893 else /* move straight left */
1901 ReturnVoid("BitMap::DrawEllipse");
1904 /*****************************************************************************************
1907 moHidd_BitMap_FillEllipse
1910 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawEllipse *msg);
1912 VOID HIDD_BM_FillEllipse (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
1916 hidd.graphics.bitmap
1919 Draws a solid ellipse from the center point (x,y) with the radii
1920 rx and ry in the specified bitmap.
1921 The function does not clip the ellipse against the drawing area.
1924 obj - A bitmap to draw on
1925 gc - A GC object to use for drawing
1926 x,y - Coordinates of center point in pixels
1927 rx,ry - ry and ry radius in pixels
1933 This method is not used by the system and considered reserved.
1937 Because of overflow the current code do not work with big
1938 values of rx and ry.
1947 *****************************************************************************************/
1949 VOID
BM__Hidd_BitMap__FillEllipse(OOP_Class
*cl
, OOP_Object
*obj
,
1950 struct pHidd_BitMap_DrawEllipse
*msg
)
1953 OOP_Object
*gc
= msg
->gc
;
1954 WORD x
= msg
->rx
, y
= 0; /* ellipse points */
1956 /* intermediate terms to speed up loop */
1957 LONG t1
= msg
->rx
* msg
->rx
, t2
= t1
<< 1, t3
= t2
<< 1;
1958 LONG t4
= msg
->ry
* msg
->ry
, t5
= t4
<< 1, t6
= t5
<< 1;
1959 LONG t7
= msg
->rx
* t5
, t8
= t7
<< 1, t9
= 0L;
1960 LONG d1
= t2
- t7
+ (t4
>> 1); /* error terms */
1961 LONG d2
= (t1
>> 1) - t8
+ t5
;
1963 EnterFunc(bug("BitMap::FillEllipse()"));
1965 while (d2
< 0) /* til slope = -1 */
1967 /* draw 4 points using symmetry */
1968 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
+ y
, msg
->x
+ x
, msg
->y
+ y
);
1969 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
- y
, msg
->x
+ x
, msg
->y
- y
);
1971 y
++; /* always move up here */
1973 if (d1
< 0) /* move straight up */
1978 else /* move up and left */
1982 d1
= d1
+ t9
+ t2
- t8
;
1983 d2
= d2
+ t9
+ t5
- t8
;
1987 do /* rest of top right quadrant */
1989 /* draw 4 points using symmetry */
1990 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
+ y
, msg
->x
+ x
, msg
->y
+ y
);
1991 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
- y
, msg
->x
+ x
, msg
->y
- y
);
1993 x
--; /* always move left here */
1995 if (d2
< 0) /* move up and left */
1999 d2
= d2
+ t9
+ t5
- t8
;
2001 else /* move straight left */
2009 ReturnVoid("BitMap::FillEllipse");
2012 /*****************************************************************************************
2015 moHidd_BitMap_DrawPolygon
2018 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg);
2020 VOID HIDD_BM_DrawPolygon (OOP_Object *obj, OOP_Object *gc, UWORD n, WORD *coords);
2023 hidd.graphics.bitmap
2026 Draws a hollow polygon from the list of coordinates in coords[].
2027 The function does not clip the polygon against the drawing area.
2030 obj - A bitmap to draw on
2031 gc - A GC object to use for drawing
2032 n - number of coordinate pairs
2033 coords - array of n (x, y) coordinates in pixels
2039 This method is not used by the system and considered reserved.
2051 *****************************************************************************************/
2053 VOID
BM__Hidd_BitMap__DrawPolygon(OOP_Class
*cl
, OOP_Object
*obj
,
2054 struct pHidd_BitMap_DrawPolygon
*msg
)
2057 OOP_Object
*gc
= msg
->gc
;
2060 EnterFunc(bug("BitMap::DrawPolygon()"));
2062 for(i
= 2; i
< (2 * msg
->n
); i
= i
+ 2)
2064 HIDD_BM_DrawLine(obj
, gc
, msg
->coords
[i
- 2], msg
->coords
[i
- 1],
2065 msg
->coords
[i
], msg
->coords
[i
+ 1]);
2069 ReturnVoid("BitMap::DrawPolygon");
2072 /*****************************************************************************************
2075 moHidd_BitMap_FillPolygon
2078 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg);
2080 VOID HIDD_BM_FillPolygon (OOP_Object *obj, OOP_Object *gc, UWORD n, WORD *coords);
2083 hidd.graphics.bitmap
2086 This method was initially designed for drawing solid polygons, however it was never
2087 used and implemented. At the moment it is considered reserved, its synopsis and
2088 semantics may change in future.
2091 obj - A bitmap to draw on
2092 gc - A GC object to use for drawing
2093 n - number of coordinate pairs
2094 coords - array of n (x, y) coordinates in pixels
2104 Never used and implemented
2112 *****************************************************************************************/
2114 VOID
BM__Hidd_BitMap__FillPolygon(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawPolygon
*msg
)
2116 D(bug("Sorry, FillPolygon() not implemented yet in bitmap baseclass\n"));
2119 /*****************************************************************************************
2122 moHidd_BitMap_DrawText
2125 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2127 VOID HIDD_BM_DrawText (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2128 STRPTR text, UWORD length);
2131 hidd.graphics.bitmap
2134 Draws the first length characters of text at (x, y).
2135 The function does not clip the text against the drawing area.
2138 obj - A bitmap to draw on
2139 gc - A GC object to use for drawing and font specification
2140 x, y - Position to start drawing in pixels. The x
2141 coordinate is relativ to the left side of the
2143 The y coordinate is relative to the baseline of the font.
2144 text - Pointer to a Latin 1 string
2145 length - Number of characters to draw
2151 At the moment text drawing is processed entirely by graphics.library
2152 using BltTemplate(), which in turn uses moHodd_BitMap_PutTemplate.
2153 This method is considered obsolete.
2158 The default implementation in the base class does not process styles,
2159 color and alpha-blended fonts.
2167 *****************************************************************************************/
2169 VOID
BM__Hidd_BitMap__DrawText(OOP_Class
*cl
, OOP_Object
*obj
,
2170 struct pHidd_BitMap_DrawText
*msg
)
2172 OOP_Object
*gc
= msg
->gc
;
2173 struct TextFont
*font
= GC_FONT(gc
);
2174 UBYTE
*charPatternPtr
= font
->tf_CharData
;
2175 UWORD modulo
= font
->tf_Modulo
;
2177 UBYTE ch
; /* current character to print */
2178 WORD fx
, fx2
, fy
, fw
; /* position and length of character in the */
2179 /* character bitmap */
2180 WORD xMem
= msg
->x
; /* position in bitmap */
2181 WORD yMem
= msg
->y
- font
->tf_Baseline
;
2185 EnterFunc(bug("BitMap::DrawText()"));
2187 for(i
= 0; i
< msg
->length
; i
++)
2191 if((ch
< font
->tf_LoChar
) || (ch
> font
->tf_HiChar
))
2193 ch
= font
->tf_HiChar
- font
->tf_LoChar
+ 1;
2197 ch
= ch
- font
->tf_LoChar
;
2200 if(font
->tf_Flags
& FPF_PROPORTIONAL
)
2202 xMem
= xMem
+ ((UWORD
*) font
->tf_CharKern
)[ch
];
2205 charLog
= ((ULONG
*) font
->tf_CharLoc
)[ch
];
2206 fx2
= charLog
>> 16; /* x position of character pattern in character bitmap */
2207 fw
= (UWORD
) charLog
; /* width of character pattern in character bitmap */
2211 for(fy
= 0; fy
< font
->tf_YSize
; fy
++)
2215 for(fx
= fx2
; fx
< fw
+ fx2
; fx
++)
2217 if(*(charPatternPtr
+ fx
/ 8 + fy
* modulo
) & (128 >> (fx
% 8)))
2219 HIDD_BM_DrawPixel(obj
, msg
->gc
, x
, y
);
2227 if(font
->tf_Flags
& FPF_PROPORTIONAL
)
2229 xMem
= xMem
+ ((UWORD
*) font
->tf_CharSpace
)[ch
];
2233 xMem
= xMem
+ font
->tf_XSize
;
2237 ReturnVoid("BitMap::DrawText");
2240 /*****************************************************************************************
2243 moHidd_BitMap_FillText
2246 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2248 VOID HIDD_BM_FillText (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2249 STRPTR text, UWORD length);
2252 hidd.graphics.bitmap
2255 Historically this method was designed to draw a text with background.
2256 It was never implemented.
2258 Currently this method is considered reserved. Its synopsis and semantics
2259 may change in future.
2262 obj - A bitmap to draw on
2263 gc - A GC object to use for drawing
2264 x, y - Position to start drawing in pixels. The x
2265 coordinate is relative to the left side of the
2267 The y coordinate is relative to the baseline of the font.
2268 text - Pointer to a Latin 1 string
2269 length - Number of characters to draw
2285 *****************************************************************************************/
2287 VOID
BM__Hidd_BitMap__FillText(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawText
*msg
)
2289 D(bug("Sorry, FillText() not implemented yet in bitmap baseclass\n"));
2292 /*****************************************************************************************
2295 moHidd_BitMap_FillSpan
2298 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2301 hidd.graphics.bitmap
2304 Reserved, never implemented method. The definition will change in future.
2323 *****************************************************************************************/
2325 VOID
BM__Hidd_BitMap__FillSpan(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawText
*msg
)
2327 D(bug("Sorry, FillSpan() not implemented yet\n"));
2330 /*****************************************************************************************
2336 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_Clear *msg);
2338 VOID HIDD_BM_Clear (OOP_Object *obj, OOP_Object *gc);
2341 hidd.graphics.bitmap
2344 Sets all pixels of the drawing area to the background color.
2347 obj - A bitmap to clear.
2348 gc - A GC object, specifies background color value
2353 This method is not used by the system and considered reserved. However it can
2354 be useful for display driver's own needs.
2359 Default implementation in the base class sets all pixels to zero color instead of
2360 the background color from GC
2368 *****************************************************************************************/
2370 VOID
BM__Hidd_BitMap__Clear(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_Clear
*msg
)
2375 EnterFunc(bug("BitMap::Clear()\n"));
2377 OOP_GetAttr(obj
, aHidd_BitMap_Width
, &width
);
2378 OOP_GetAttr(obj
, aHidd_BitMap_Height
, &height
);
2380 for(y
= 0; y
< height
; y
++)
2382 for(x
= 0; x
< width
; x
++)
2384 HIDD_BM_PutPixel(obj
, x
, y
, 0);
2388 ReturnVoid("BitMap::Clear");
2391 /****************************************************************************************/
2393 static LONG
inline getpixfmtbpp(OOP_Class
*cl
, OOP_Object
*o
, HIDDT_StdPixFmt stdpf
)
2396 struct HIDDBitMapData
*data
;
2399 data
= OOP_INST_DATA(cl
, o
);
2403 case vHidd_StdPixFmt_Native
:
2404 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_BytesPerPixel
, &bpp
);
2407 case vHidd_StdPixFmt_Native32
:
2408 bpp
= sizeof (HIDDT_Pixel
);
2412 pf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, stdpf
);
2416 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", stdpf
));
2420 OOP_GetAttr(pf
, aHidd_PixFmt_BytesPerPixel
, &bpp
);
2428 /*****************************************************************************************
2431 moHidd_BitMap_GetImage
2434 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_GetImage *msg);
2436 VOID HIDD_BM_GetImage (OOP_Object *obj, UBYTE *pixels, ULONG modulo, WORD x, WORD y,
2437 WORD width, WORD height, HIDDT_StdPixFmt pixFmt);
2440 hidd.graphics.bitmap
2465 *****************************************************************************************/
2467 VOID
BM__Hidd_BitMap__GetImage(OOP_Class
*cl
, OOP_Object
*o
,
2468 struct pHidd_BitMap_GetImage
*msg
)
2471 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
2472 APTR ppixarray
= &pixarray
;
2474 struct HIDDBitMapData
*data
;
2476 data
= OOP_INST_DATA(cl
, o
);
2478 EnterFunc(bug("BitMap::GetImage(x=%d, y=%d, width=%d, height=%d)\n"
2479 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
2482 bpp
= getpixfmtbpp(cl
, o
, msg
->pixFmt
);
2485 D(bug("!!! INVALID PIXFMT IN BitMap::GetImage(): %d !!!\n", msg
->pixFmt
));
2492 case vHidd_StdPixFmt_Native
:
2493 case vHidd_StdPixFmt_Native32
:
2494 for (y
= 0; y
< msg
->height
; y
++)
2496 for (x
= 0; x
< msg
->width
; x
++)
2498 register HIDDT_Pixel pix
;
2500 pix
= HIDD_BM_GetPixel(o
, x
+ msg
->x
, y
+ msg
->y
);
2509 *((UWORD
*)pixarray
) = pix
;
2515 pixarray
[0] = (pix
>> 16) & 0xFF;
2516 pixarray
[1] = (pix
>> 8) & 0xFF;
2517 pixarray
[2] = pix
& 0xFF;
2519 pixarray
[0] = pix
& 0xFF;
2520 pixarray
[1] = (pix
>> 8) & 0xFF;
2521 pixarray
[2] = (pix
>> 16) & 0xFF;
2527 *(ULONG
*)pixarray
= pix
;
2534 pixarray
+= (msg
->modulo
- msg
->width
* bpp
);
2542 APTR buf
, srcPixels
;
2544 dstpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
2546 buf
= srcPixels
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
2549 for(y
= 0; y
< msg
->height
; y
++)
2558 vHidd_StdPixFmt_Native
);
2560 HIDD_BM_ConvertPixels(o
,
2562 (HIDDT_PixelFormat
*)data
->prot
.pixfmt
,
2565 (HIDDT_PixelFormat
*)dstpf
,
2577 } /* switch(msg->pixFmt) */
2579 ReturnVoid("BitMap::GetImage");
2582 /*****************************************************************************************
2585 moHidd_BitMap_PutImage
2588 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutImage *msg);
2590 VOID HIDD_BM_PutImage (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
2591 WORD x, WORD y, WORD width, WORD height, HIDDT_StdPixFmt pixFmt);
2594 hidd.graphics.bitmap
2620 *****************************************************************************************/
2622 VOID
BM__Hidd_BitMap__PutImage(OOP_Class
*cl
, OOP_Object
*o
,
2623 struct pHidd_BitMap_PutImage
*msg
)
2626 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
2627 APTR ppixarray
= &pixarray
;
2630 struct HIDDBitMapData
*data
;
2631 OOP_Object
*gc
= msg
->gc
;
2633 data
= OOP_INST_DATA(cl
, o
);
2635 EnterFunc(bug("BitMap::PutImage(x=%d, y=%d, width=%d, height=%d)\n"
2636 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
2638 if (msg
->width
<= 0 || msg
->height
<= 0)
2641 bpp
= getpixfmtbpp(cl
, o
, msg
->pixFmt
);
2644 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", msg
->pixFmt
));
2650 case vHidd_StdPixFmt_Native
:
2651 case vHidd_StdPixFmt_Native32
:
2653 /* Preserve old fg pen */
2656 for (y
= 0; y
< msg
->height
; y
++)
2658 for (x
= 0; x
< msg
->width
; x
++)
2660 register HIDDT_Pixel pix
= 0;
2665 pix
= *((UBYTE
*)pixarray
);
2670 pix
= *((UWORD
*)pixarray
);
2676 pix
= ((UBYTE
*)pixarray
)[0] << 16;
2677 pix
|= ((UBYTE
*)pixarray
)[1] << 8;
2678 pix
|= ((UBYTE
*)pixarray
)[2];
2680 pix
= ((UBYTE
*)pixarray
)[2] << 16;
2681 pix
|= ((UBYTE
*)pixarray
)[1] << 8;
2682 pix
|= ((UBYTE
*)pixarray
)[0];
2688 pix
= *((ULONG
*)pixarray
); pixarray
+= 4;
2695 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->x
, y
+ msg
->y
);
2697 pixarray
+= (msg
->modulo
- msg
->width
* bpp
);
2706 APTR buf
, destPixels
;
2708 srcpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
2710 buf
= destPixels
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
2713 for(y
= 0; y
< msg
->height
; y
++)
2715 HIDD_BM_ConvertPixels(o
,
2717 (HIDDT_PixelFormat
*)srcpf
,
2720 (HIDDT_PixelFormat
*)data
->prot
.pixfmt
,
2734 vHidd_StdPixFmt_Native
);
2741 } /* switch(msg->pixFmt) */
2743 ReturnVoid("BitMap::PutImage");
2746 /****************************************************************************************/
2749 __attribute__((always_inline
, const)) do_alpha(int a
, int v
)
2752 return ((tmp
<<8) + tmp
+ 32768)>>16;
2755 /*****************************************************************************************
2758 moHidd_BitMap_PutAlphaImage
2761 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutAlphaImage *msg);
2763 VOID HIDD_BM_PutAlphaImage (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
2764 WORD x, WORD y, WORD width, WORD height);
2767 hidd.graphics.bitmap
2792 *****************************************************************************************/
2794 VOID
BM__Hidd_BitMap__PutAlphaImage(OOP_Class
*cl
, OOP_Object
*o
,
2795 struct pHidd_BitMap_PutAlphaImage
*msg
)
2798 ULONG
*pixarray
= (ULONG
*)msg
->pixels
;
2802 EnterFunc(bug("BitMap::PutAlphaImage(x=%d, y=%d, width=%d, height=%d)\n"
2803 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
2805 if (msg
->width
<= 0 || msg
->height
<= 0)
2808 PIXBUF_ALLOC(buf
, msg
->width
* sizeof(ULONG
), msg
->height
);
2812 HIDDT_DrawMode old_drmd
= GC_DRMD(msg
->gc
);
2813 GC_DRMD(msg
->gc
) = vHidd_GC_DrawMode_Copy
;
2817 for(y
= msg
->y
; y
< msg
->y
+ msg
->height
; y
++)
2819 if (PIXBUF_TIME_TO_START_PROCESS
)
2821 WORD height
= PIXBUF_LINES_TO_PROCESS
;
2825 msg
->width
* sizeof(ULONG
),
2830 vHidd_StdPixFmt_ARGB32
);
2833 for(x
= 0; x
< msg
->width
; x
++)
2837 LONG src_red
, src_green
, src_blue
, src_alpha
;
2838 LONG dst_red
, dst_green
, dst_blue
;
2840 srcpix
= *pixarray
++;
2843 if ((srcpix
& 0xFF000000) == 0xFF000000)
2845 else if ((srcpix
& 0xFF000000) != 0)
2847 if ((srcpix
& 0xFF) == 0xFF)
2849 else if ((srcpix
& 0xFF) != 0)
2853 src_red
= (srcpix
& 0x00FF0000) >> 16;
2854 src_green
= (srcpix
& 0x0000FF00) >> 8;
2855 src_blue
= (srcpix
& 0x000000FF);
2856 src_alpha
= (srcpix
& 0xFF000000) >> 24;
2858 src_red
= (srcpix
& 0x0000FF00) >> 8;
2859 src_green
= (srcpix
& 0x00FF0000) >> 16;
2860 src_blue
= (srcpix
& 0xFF000000) >> 24;
2861 src_alpha
= (srcpix
& 0x000000FF);
2866 dst_red
= (destpix
& 0x00FF0000) >> 16;
2867 dst_green
= (destpix
& 0x0000FF00) >> 8;
2868 dst_blue
= (destpix
& 0x000000FF);
2870 dst_red
= (destpix
& 0x0000FF00) >> 8;
2871 dst_green
= (destpix
& 0x00FF0000) >> 16;
2872 dst_blue
= (destpix
& 0xFF000000) >> 24;
2875 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
2876 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
2877 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
2880 destpix
&= 0xFF000000;
2881 destpix
|= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
2883 destpix
&= 0x000000FF;
2884 destpix
|= (dst_blue
<< 24) + (dst_green
<< 16) + (dst_red
<< 8);
2889 } /* for(x = 0; x < msg->width; x++) */
2891 if (PIXBUF_TIME_TO_END_PROCESS
)
2893 LONG height
= PIXBUF_LINES_TO_PROCESS
;
2898 msg
->width
* sizeof(ULONG
),
2903 vHidd_StdPixFmt_ARGB32
);
2911 pixarray
= (ULONG
*)((UBYTE
*)pixarray
+ msg
->modulo
- msg
->width
* 4);
2916 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
2918 GC_DRMD(msg
->gc
) = old_drmd
;
2925 for(y
= msg
->y
; y
< msg
->y
+ msg
->height
; y
++)
2927 for(x
= msg
->x
; x
< msg
->x
+ msg
->width
; x
++)
2929 HIDDT_Pixel destpix
;
2932 LONG src_red
, src_green
, src_blue
, src_alpha
;
2933 LONG dst_red
, dst_green
, dst_blue
;
2935 destpix
= HIDD_BM_GetPixel(o
, x
, y
);
2936 HIDD_BM_UnmapPixel(o
, destpix
, &col
);
2938 srcpix
= *pixarray
++;
2940 src_red
= (srcpix
& 0x00FF0000) >> 16;
2941 src_green
= (srcpix
& 0x0000FF00) >> 8;
2942 src_blue
= (srcpix
& 0x000000FF);
2943 src_alpha
= (srcpix
& 0xFF000000) >> 24;
2945 src_red
= (srcpix
& 0x0000FF00) >> 8;
2946 src_green
= (srcpix
& 0x00FF0000) >> 16;
2947 src_blue
= (srcpix
& 0xFF000000) >> 24;
2948 src_alpha
= (srcpix
& 0x000000FF);
2951 dst_red
= col
.red
>> 8;
2952 dst_green
= col
.green
>> 8;
2953 dst_blue
= col
.blue
>> 8;
2955 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
2956 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
2957 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
2959 col
.red
= dst_red
<< 8;
2960 col
.green
= dst_green
<< 8;
2961 col
.blue
= dst_blue
<< 8;
2963 HIDD_BM_PutPixel(o
, x
, y
, HIDD_BM_MapColor(o
, &col
));
2965 } /* for(x = msg->x; x < msg->x + msg->width; x++) */
2967 pixarray
= (ULONG
*)((UBYTE
*)pixarray
+ msg
->modulo
- msg
->width
* 4);
2969 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
2973 ReturnVoid("BitMap::PutAlphaImage");
2976 /*****************************************************************************************
2979 moHidd_BitMap_PutTemplate
2982 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutTemplate *msg);
2984 VOID HIDD_BM_PutTemplate (OOP_Object *obj, OOP_Object *gc, UBYTE *template, ULONG modulo,
2985 WORD srcx, WORD x, WORD y, WORD width, WORD height, BOOL inverttemplate);
2988 hidd.graphics.bitmap
3015 *****************************************************************************************/
3017 VOID
BM__Hidd_BitMap__PutTemplate(OOP_Class
*cl
, OOP_Object
*o
,
3018 struct pHidd_BitMap_PutTemplate
*msg
)
3022 HIDDT_Pixel
*buf
, *xbuf
, bitmask
;
3023 OOP_Object
*gc
= msg
->gc
;
3027 EnterFunc(bug("BitMap::PutTemplate(x=%d, y=%d, width=%d, height=%d)\n"
3028 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3030 if (msg
->width
<= 0 || msg
->height
<= 0)
3033 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
3037 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
3046 if (msg
->inverttemplate
) type
++;
3048 bitarray
= msg
->template + ((msg
->srcx
/ 16) * 2);
3049 bitmask
= 0x8000 >> (msg
->srcx
& 0xF);
3051 PIXBUF_ALLOC(buf
, msg
->width
* sizeof(HIDDT_Pixel
), msg
->height
);
3055 HIDDT_DrawMode old_drmd
= GC_DRMD(msg
->gc
);
3056 HIDDT_Pixel fg
= GC_FG(msg
->gc
);
3057 HIDDT_Pixel bg
= GC_BG(msg
->gc
);
3059 GC_DRMD(msg
->gc
) = vHidd_GC_DrawMode_Copy
;
3063 for(y
= msg
->y
; y
< msg
->y
+ msg
->height
; y
++)
3065 ULONG mask
= bitmask
;
3066 UWORD
*array
= (UWORD
*)bitarray
;
3067 UWORD bitword
= AROS_BE2WORD(*array
);
3069 if ((type
< 4) && PIXBUF_TIME_TO_START_PROCESS
)
3071 WORD height
= PIXBUF_LINES_TO_PROCESS
;
3075 msg
->width
* sizeof(HIDDT_Pixel
),
3080 vHidd_StdPixFmt_Native32
);
3087 for(x
= 0; x
< msg
->width
; x
++)
3089 if (bitword
& mask
) xbuf
[x
] = fg
;
3096 bitword
= AROS_BE2WORD(*array
);
3099 } /* for(x = 0; x < msg->width; x++) */
3102 case 1: /* JAM1 | INVERSVID */
3103 for(x
= 0; x
< msg
->width
; x
++)
3105 if (!(bitword
& mask
)) xbuf
[x
] = fg
;
3112 bitword
= AROS_BE2WORD(*array
);
3115 } /* for(x = 0; x < msg->width; x++) */
3118 case 2: /* COMPLEMENT */
3119 for(x
= 0; x
< msg
->width
; x
++)
3121 if (bitword
& mask
) xbuf
[x
] = ~xbuf
[x
];
3128 bitword
= AROS_BE2WORD(*array
);
3130 } /* for(x = 0; x < msg->width; x++) */
3133 case 3: /* COMPLEMENT | INVERSVID*/
3134 for(x
= 0; x
< msg
->width
; x
++)
3136 if (!(bitword
& mask
)) xbuf
[x
] = ~xbuf
[x
];
3143 bitword
= AROS_BE2WORD(*array
);
3145 } /* for(x = 0; x < msg->width; x++) */
3149 for(x
= 0; x
< msg
->width
; x
++)
3151 xbuf
[x
] = (bitword
& mask
) ? fg
: bg
;
3158 bitword
= AROS_BE2WORD(*array
);
3161 } /* for(x = 0; x < msg->width; x++) */
3164 case 5: /* JAM2 | INVERSVID */
3165 for(x
= 0; x
< msg
->width
; x
++)
3167 xbuf
[x
] = (bitword
& mask
) ? bg
: fg
;
3174 bitword
= AROS_BE2WORD(*array
);
3176 } /* for(x = 0; x < msg->width; x++) */
3179 } /* switch(type) */
3181 if (PIXBUF_TIME_TO_END_PROCESS
)
3183 LONG height
= PIXBUF_LINES_TO_PROCESS
;
3185 //kprintf(" PutImage at %d height %d __height %d __bufy %d __worky %d\n",
3186 // y - height + 1 - msg->y, height, __height, __bufy, __worky);
3191 msg
->width
* sizeof(HIDDT_Pixel
),
3196 vHidd_StdPixFmt_Native32
);
3204 bitarray
+= msg
->modulo
;
3208 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
3210 GC_DRMD(msg
->gc
) = old_drmd
;
3220 ReturnVoid("BitMap::PutTemplate");
3223 /*****************************************************************************************
3226 moHidd_BitMap_PutAlphaTemplate
3229 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutAlphaTemplate *msg);
3231 VOID HIDD_BM_PutAlphaTemplate (OOP_Object *obj, OOP_Object *gc, UBYTE *alpha, ULONG modulo,
3232 WORD x, WORD y, WORD width, WORD height, BOOL invertalpha);
3235 hidd.graphics.bitmap
3261 *****************************************************************************************/
3263 VOID
BM__Hidd_BitMap__PutAlphaTemplate(OOP_Class
*cl
, OOP_Object
*o
,
3264 struct pHidd_BitMap_PutAlphaTemplate
*msg
)
3267 UBYTE
*pixarray
= msg
->alpha
;
3269 OOP_Object
*gc
= msg
->gc
;
3271 LONG a_red
, a_green
, a_blue
;
3278 EnterFunc(bug("BitMap::PutAlphaTemplate(x=%d, y=%d, width=%d, height=%d)\n"
3279 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3281 if (msg
->width
<= 0 || msg
->height
<= 0)
3284 HIDD_BM_UnmapPixel(o
, GC_FG(gc
), &color
);
3286 a_red
= color
.red
>> 8;
3287 a_green
= color
.green
>> 8;
3288 a_blue
= color
.blue
>> 8;
3290 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
3294 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
3302 HIDD_BM_UnmapPixel(o
, GC_BG(gc
), &color
);
3303 b_red
= color
.red
>> 8;
3304 b_green
= color
.green
>> 8;
3305 b_blue
= color
.blue
>> 8;
3308 if (msg
->invertalpha
) type
++;
3310 PIXBUF_ALLOC(buf
, msg
->width
* sizeof(ULONG
), msg
->height
);
3314 HIDDT_DrawMode old_drmd
= GC_DRMD(msg
->gc
);
3315 GC_DRMD(msg
->gc
) = vHidd_GC_DrawMode_Copy
;
3319 for(y
= msg
->y
; y
< msg
->y
+ msg
->height
; y
++)
3321 if ((type
< 4) && PIXBUF_TIME_TO_START_PROCESS
)
3323 WORD height
= PIXBUF_LINES_TO_PROCESS
;
3327 msg
->width
* sizeof(ULONG
),
3332 vHidd_StdPixFmt_ARGB32
);
3338 for(x
= 0; x
< msg
->width
; x
++)
3341 LONG dst_red
, dst_green
, dst_blue
, alpha
;
3343 alpha
= *pixarray
++;
3348 dst_red
= (destpix
& 0x00FF0000) >> 16;
3349 dst_green
= (destpix
& 0x0000FF00) >> 8;
3350 dst_blue
= (destpix
& 0x000000FF);
3352 dst_red
= (destpix
& 0x0000FF00) >> 8;
3353 dst_green
= (destpix
& 0x00FF0000) >> 16;
3354 dst_blue
= (destpix
& 0xFF000000) >> 24;
3357 dst_red
+= do_alpha(alpha
, a_red
- dst_red
);
3358 dst_green
+= do_alpha(alpha
, a_green
- dst_green
);
3359 dst_blue
+= do_alpha(alpha
, a_blue
- dst_blue
);
3362 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
3364 destpix
= (dst_blue
<< 24) + (dst_green
<< 16) + (dst_red
<< 8);
3369 } /* for(x = 0; x < msg->width; x++) */
3372 case 1: /* JAM1 | INVERSVID */
3373 for(x
= 0; x
< msg
->width
; x
++)
3376 LONG dst_red
, dst_green
, dst_blue
, alpha
;
3378 alpha
= (*pixarray
++) ^ 255;
3383 dst_red
= (destpix
& 0x00FF0000) >> 16;
3384 dst_green
= (destpix
& 0x0000FF00) >> 8;
3385 dst_blue
= (destpix
& 0x000000FF);
3387 dst_red
= (destpix
& 0x0000FF00) >> 8;
3388 dst_green
= (destpix
& 0x00FF0000) >> 16;
3389 dst_blue
= (destpix
& 0xFF000000) >> 24;
3392 dst_red
+= do_alpha(alpha
, a_red
- dst_red
);
3393 dst_green
+= do_alpha(alpha
, a_green
- dst_green
);
3394 dst_blue
+= do_alpha(alpha
, a_blue
- dst_blue
);
3397 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
3399 destpix
= (dst_blue
<< 24) + (dst_green
<< 16) + (dst_red
<< 8);
3404 } /* for(x = 0; x < msg->width; x++) */
3407 case 2: /* COMPLEMENT */
3408 for(x
= 0; x
< msg
->width
; x
++)
3413 alpha
= *pixarray
++;
3416 if (alpha
>= 0x80) destpix
= ~destpix
;
3419 } /* for(x = 0; x < msg->width; x++) */
3422 case 3: /* COMPLEMENT | INVERSVID*/
3423 for(x
= 0; x
< msg
->width
; x
++)
3428 alpha
= *pixarray
++;
3431 if (alpha
< 0x80) destpix
= ~destpix
;
3434 } /* for(x = 0; x < msg->width; x++) */
3438 for(x
= 0; x
< msg
->width
; x
++)
3441 LONG dst_red
, dst_green
, dst_blue
, alpha
;
3443 alpha
= *pixarray
++;
3445 dst_red
= b_red
+ ((a_red
- b_red
) * alpha
) / 256;
3446 dst_green
= b_green
+ ((a_green
- b_green
) * alpha
) / 256;
3447 dst_blue
= b_blue
+ ((a_blue
- b_blue
) * alpha
) / 256;
3450 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
3452 destpix
= (dst_blue
<< 24) + (dst_green
<< 16) + (dst_red
<< 8);
3457 } /* for(x = 0; x < msg->width; x++) */
3460 case 5: /* JAM2 | INVERSVID */
3461 for(x
= 0; x
< msg
->width
; x
++)
3464 LONG dst_red
, dst_green
, dst_blue
, alpha
;
3466 alpha
= (*pixarray
++) ^ 255;
3468 dst_red
= b_red
+ ((a_red
- b_red
) * alpha
) / 256;
3469 dst_green
= b_green
+ ((a_green
- b_green
) * alpha
) / 256;
3470 dst_blue
= b_blue
+ ((a_blue
- b_blue
) * alpha
) / 256;
3473 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
3475 destpix
= (dst_blue
<< 24) + (dst_green
<< 16) + (dst_red
<< 8);
3480 } /* for(x = 0; x < msg->width; x++) */
3483 } /* switch(type) */
3485 if (PIXBUF_TIME_TO_END_PROCESS
)
3487 LONG height
= PIXBUF_LINES_TO_PROCESS
;
3492 msg
->width
* sizeof(ULONG
),
3497 vHidd_StdPixFmt_ARGB32
);
3506 pixarray
+= msg
->modulo
- msg
->width
;
3510 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
3512 GC_DRMD(msg
->gc
) = old_drmd
;
3522 ReturnVoid("BitMap::PutAlphaTemplate");
3525 /*****************************************************************************************
3528 moHidd_BitMap_PutPattern
3531 VOID OOP_DoMethod(OOP_Object *o, struct pHidd_BitMap_PutPattern *msg);
3533 VOID HIDD_BM_PutPattern(OOP_Object *obj, OOP_Object *gc, UBYTE *pattern,
3534 WORD patternsrcx, WORD patternsrcy, WORD patternheight, WORD patterndepth,
3535 HIDDT_PixelLUT *patternlut, BOOL invertpattern, UBYTE *mask,
3536 ULONG maskmodulo, WORD masksrcx, WORD x, WORD y,
3537 WORD width, WORD height);
3540 hidd.graphics.bitmap
3545 obj - A bitmap to draw on
3546 gc - A GC object to use for drawing
3574 *****************************************************************************************/
3576 VOID
BM__Hidd_BitMap__PutPattern(OOP_Class
*cl
, OOP_Object
*o
,
3577 struct pHidd_BitMap_PutPattern
*msg
)
3581 UBYTE
*maskarray
= 0;
3583 ULONG
*buf
, *xbuf
, patmask
;
3584 OOP_Object
*gc
= msg
->gc
;
3588 EnterFunc(bug("BitMap::PutPattern(x=%d, y=%d, width=%d, height=%d)\n"
3589 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3591 if (msg
->width
<= 0 || msg
->height
<= 0)
3594 if (msg
->patterndepth
> 1)
3600 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
3604 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
3613 if (msg
->invertpattern
) type
++;
3616 patarray
= msg
->pattern
;
3617 patmask
= 0x8000 >> (msg
->patternsrcx
& 0xF);
3619 if ((maskarray
= msg
->mask
))
3621 maskarray
+= (msg
->masksrcx
/ 16) * 2;
3622 maskmask
= 0x8000 >> (msg
->masksrcx
& 0xF);
3625 PIXBUF_ALLOC(buf
, msg
->width
* sizeof(ULONG
), msg
->height
);
3629 HIDDT_DrawMode old_drmd
= GC_DRMD(msg
->gc
);
3630 ULONG fg
= GC_FG(msg
->gc
);
3631 ULONG bg
= GC_BG(msg
->gc
);
3633 GC_DRMD(msg
->gc
) = vHidd_GC_DrawMode_Copy
;
3637 for(y
= msg
->y
; y
< msg
->y
+ msg
->height
; y
++)
3639 ULONG pmask
= patmask
;
3640 ULONG mmask
= maskmask
;
3641 UWORD
*parray
= ((UWORD
*)patarray
) + ((y
+ msg
->patternsrcy
- msg
->y
) % msg
->patternheight
);
3642 UWORD patword
= AROS_BE2WORD(*parray
);
3643 UWORD
*marray
= NULL
;
3648 marray
= (UWORD
*)maskarray
;
3649 maskword
= AROS_BE2WORD(*marray
);
3652 if (((type
< 4) || maskarray
) && PIXBUF_TIME_TO_START_PROCESS
)
3654 WORD height
= PIXBUF_LINES_TO_PROCESS
;
3656 //kprintf(" GetImage at %d height %d\n", y - msg->y, height);
3660 msg
->width
* sizeof(ULONG
),
3665 vHidd_StdPixFmt_Native32
);
3672 for(x
= 0; x
< msg
->width
; x
++)
3674 if (!maskarray
|| (maskword
& mmask
))
3676 if (patword
& pmask
) xbuf
[x
] = fg
;
3686 maskword
= AROS_BE2WORD(*marray
);
3691 if (!pmask
) pmask
= 0x8000;
3693 } /* for(x = 0; x < msg->width; x++) */
3696 case 1: /* JAM1 | INVERSVID */
3697 for(x
= 0; x
< msg
->width
; x
++)
3699 if (!maskarray
|| (maskword
& mmask
))
3701 if (!(patword
& pmask
)) xbuf
[x
] = fg
;
3711 maskword
= AROS_BE2WORD(*marray
);
3716 if (!pmask
) pmask
= 0x8000;
3718 } /* for(x = 0; x < msg->width; x++) */
3721 case 2: /* COMPLEMENT */
3722 for(x
= 0; x
< msg
->width
; x
++)
3724 if (!maskarray
|| (maskword
& mmask
))
3726 if (patword
& pmask
) xbuf
[x
] = ~xbuf
[x
];
3736 maskword
= AROS_BE2WORD(*marray
);
3741 if (!pmask
) pmask
= 0x8000;
3743 } /* for(x = 0; x < msg->width; x++) */
3746 case 3: /* COMPLEMENT | INVERSVID*/
3747 for(x
= 0; x
< msg
->width
; x
++)
3749 if (!maskarray
|| (maskword
& mmask
))
3751 if (!(patword
& pmask
)) xbuf
[x
] = ~xbuf
[x
];
3761 maskword
= AROS_BE2WORD(*marray
);
3766 if (!pmask
) pmask
= 0x8000;
3768 } /* for(x = 0; x < msg->width; x++) */
3772 for(x
= 0; x
< msg
->width
; x
++)
3774 if (!maskarray
|| (maskword
& mmask
))
3776 xbuf
[x
] = (patword
& pmask
) ? fg
: bg
;
3786 maskword
= AROS_BE2WORD(*marray
);
3791 if (!pmask
) pmask
= 0x8000;
3793 } /* for(x = 0; x < msg->width; x++) */
3796 case 5: /* JAM2 | INVERSVID */
3797 for(x
= 0; x
< msg
->width
; x
++)
3799 if (!maskarray
|| (maskword
& mmask
))
3801 xbuf
[x
] = (patword
& pmask
) ? bg
: fg
;
3811 maskword
= AROS_BE2WORD(*marray
);
3816 if (!pmask
) pmask
= 0x8000;
3818 } /* for(x = 0; x < msg->width; x++) */
3821 case 6: /* multi color pattern */
3822 for(x
= 0; x
< msg
->width
; x
++)
3824 if (!maskarray
|| (maskword
& mmask
))
3827 ULONG pixel
= (patword
& pmask
) ? 1 : 0;
3829 for(plane
= 1; plane
< msg
->patterndepth
; plane
++)
3831 UWORD
*_parray
= parray
+ plane
* msg
->patternheight
;
3832 UWORD _patword
= AROS_BE2WORD(*_parray
);
3834 if (_patword
& pmask
) pixel
|= 1L << plane
;
3837 if (msg
->patternlut
) pixel
= msg
->patternlut
->pixels
[pixel
];
3849 maskword
= AROS_BE2WORD(*marray
);
3854 if (!pmask
) pmask
= 0x8000;
3856 } /* for(x = 0; x < msg->width; x++) */
3859 } /* switch(type) */
3861 if (PIXBUF_TIME_TO_END_PROCESS
)
3863 LONG height
= PIXBUF_LINES_TO_PROCESS
;
3865 //kprintf(" PutImage at %d height %d __height %d __bufy %d __worky %d\n",
3866 // y - height + 1 - msg->y, height, __height, __bufy, __worky);
3871 msg
->width
* sizeof(ULONG
),
3876 vHidd_StdPixFmt_Native32
);
3884 if (maskarray
) maskarray
+= msg
->maskmodulo
;
3888 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
3890 GC_DRMD(msg
->gc
) = old_drmd
;
3900 ReturnVoid("BitMap::PutPattern");
3903 /*****************************************************************************************
3906 moHidd_BitMap_PutImageLUT
3909 VOID OOP_DoMethod(OOP_Object *o, struct pHidd_BitMap_PutImageLUT *msg);
3911 VOID HIDD_BM_PutImageLUT (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
3912 WORD x, WORD y, WORD width, WORD height, HIDDT_PixelLUT *pixlut);
3915 hidd.graphics.bitmap
3941 *****************************************************************************************/
3943 VOID
BM__Hidd_BitMap__PutImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
3944 struct pHidd_BitMap_PutImageLUT
*msg
)
3947 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
3948 HIDDT_PixelLUT
*pixlut
= msg
->pixlut
;
3949 HIDDT_Pixel
*lut
= pixlut
? pixlut
->pixels
: NULL
;
3950 HIDDT_Pixel
*linebuf
;
3951 OOP_Object
*gc
= msg
->gc
;
3953 EnterFunc(bug("BitMap::PutImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
3954 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3956 if (msg
->width
<= 0 || msg
->height
<= 0)
3959 linebuf
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
3961 for(y
= 0; y
< msg
->height
; y
++)
3967 for(x
= 0; x
< msg
->width
; x
++)
3969 linebuf
[x
] = lut
[pixarray
[x
]];
3974 for(x
= 0; x
< msg
->width
; x
++)
3976 linebuf
[x
] = pixarray
[x
];
3979 pixarray
+= msg
->modulo
;
3989 vHidd_StdPixFmt_Native32
);
3991 } /* if (linebuf) */
3996 /* Preserve old fg pen */
4001 for(x
= 0; x
< msg
->width
; x
++)
4003 GC_FG(gc
) = lut
[pixarray
[x
]];
4004 HIDD_BM_DrawPixel(o
, gc
, msg
->x
+ x
, msg
->y
+ y
);
4009 for(x
= 0; x
< msg
->width
; x
++)
4011 GC_FG(gc
) = pixarray
[x
];
4012 HIDD_BM_DrawPixel(o
, gc
, msg
->x
+ x
, msg
->y
+ y
);
4017 pixarray
+= msg
->modulo
;
4019 } /* if (linebuf) else ... */
4021 } /* for(y = 0; y < msg->height; y++) */
4025 ReturnVoid("BitMap::PutImageLUT");
4027 /*****************************************************************************************
4030 moHidd_BitMap_PutTranspImageLUT
4033 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutTranspImageLUT *msg);
4035 VOID HIDD_BM_PutTranspImageLUT (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels,
4036 ULONG modulo, WORD x, WORD y, WORD width, WORD height,
4037 HIDDT_PixelLUT *pixlut, UBYTE transparent);
4040 hidd.graphics.bitmap
4043 Copy an array of 8-bit LUT pixels to the bitmap at the specified position making
4044 one of colors transparent.
4046 Pixels are converted to bitmap's native format using either user-supplied LUT (if
4047 given) or bitmap's own colormap.
4049 Draw mode of the supplied GC is ignored, the operation is always bulk copy.
4052 obj - A bitmap to draw image on
4053 gc - A GC used for drawing
4054 pixels - A pointer to source pixel array
4055 modulo - Total number of bytes per line in the source array
4056 x, y - Top-left corner of the destination rectangle
4057 width - Width of the image to draw
4058 height - Height of the image to draw
4059 pixlut - An optional pointer to a LUT to use. NULL means using bitmap's
4060 own colormap (if available)
4061 transparent - Value of pixels in the source array which will be made
4077 *****************************************************************************************/
4079 VOID
BM__Hidd_BitMap__PutTranspImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
4080 struct pHidd_BitMap_PutTranspImageLUT
*msg
)
4083 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
4084 UBYTE transparent
= msg
->transparent
;
4085 HIDDT_PixelLUT
*pixlut
= msg
->pixlut
;
4086 HIDDT_Pixel
*lut
= pixlut
? pixlut
->pixels
: NULL
;
4087 HIDDT_Pixel
*buf
, *xbuf
;
4088 struct HIDDBitMapData
*data
;
4091 data
= OOP_INST_DATA(cl
, o
);
4093 EnterFunc(bug("BitMap::PutTranspImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
4094 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
4096 if (msg
->width
<= 0 || msg
->height
<= 0)
4099 PIXBUF_ALLOC(buf
, msg
->width
* sizeof(HIDDT_Pixel
), msg
->height
);
4103 HIDDT_DrawMode old_drmd
= GC_DRMD(msg
->gc
);
4105 GC_DRMD(msg
->gc
) = vHidd_GC_DrawMode_Copy
;
4108 for(y
= msg
->y
; y
< msg
->y
+ msg
->height
; y
++)
4110 if (PIXBUF_TIME_TO_START_PROCESS
)
4112 WORD height
= PIXBUF_LINES_TO_PROCESS
;
4116 msg
->width
* sizeof(HIDDT_Pixel
),
4121 vHidd_StdPixFmt_Native32
);
4126 for(x
= 0; x
< msg
->width
; x
++)
4128 UBYTE pix
= *pixarray
++;
4130 if (pix
!= transparent
)
4135 } /* for(x = 0; x < msg->width; x++) */
4139 for(x
= 0; x
< msg
->width
; x
++)
4141 UBYTE pix
= *pixarray
++;
4143 if (pix
!= transparent
)
4146 pix
= HIDD_CM_GetPixel(data
->colmap
, pix
);
4150 } /* for(x = 0; x < msg->width; x++) */
4154 if (PIXBUF_TIME_TO_END_PROCESS
)
4156 LONG height
= PIXBUF_LINES_TO_PROCESS
;
4161 msg
->width
* sizeof(HIDDT_Pixel
),
4166 vHidd_StdPixFmt_Native32
);
4174 pixarray
= ((UBYTE
*)pixarray
+ msg
->modulo
- msg
->width
);
4179 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
4181 GC_DRMD(msg
->gc
) = old_drmd
;
4187 ReturnVoid("BitMap::PutTranspImageLUT");
4190 /*****************************************************************************************
4193 moHidd_BitMap_GetImageLUT
4196 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_GetImageLUT *msg);
4198 VOID HIDD_BM_GetImageLUT (OOP_Object *obj, UBYTE *pixels, ULONG modulo, WORD x, WORD y,
4199 WORD width, WORD height, HIDDT_PixelLUT *pixlut);
4202 hidd.graphics.bitmap
4227 *****************************************************************************************/
4229 VOID
BM__Hidd_BitMap__GetImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
4230 struct pHidd_BitMap_GetImageLUT
*msg
)
4233 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
4234 HIDDT_PixelLUT
*pixlut
= msg
->pixlut
;
4235 HIDDT_Pixel
*lut
= pixlut
? pixlut
->pixels
: NULL
;
4236 HIDDT_Pixel
*linebuf
;
4238 EnterFunc(bug("BitMap::GetImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
4239 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
4241 linebuf
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
4243 for(y
= 0; y
< msg
->height
; y
++)
4254 vHidd_StdPixFmt_Native32
);
4257 /* FIXME: This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway */
4258 for(x
= 0; x
< msg
->width
; x
++)
4260 pixarray
[x
] = (UBYTE
)linebuf
[x
];
4265 for(x
= 0; x
< msg
->width
; x
++)
4267 pixarray
[x
] = (UBYTE
)linebuf
[x
];
4270 pixarray
+= msg
->modulo
;
4272 } /* if (linebuf) */
4277 /* FIXME: This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway */
4278 for(x
= 0; x
< msg
->width
; x
++)
4280 pixarray
[x
] = (UBYTE
)HIDD_BM_GetPixel(o
, msg
->x
+ x
, msg
->y
+ y
);
4285 for(x
= 0; x
< msg
->width
; x
++)
4287 pixarray
[x
] = (UBYTE
)HIDD_BM_GetPixel(o
, msg
->x
+ x
, msg
->y
+ y
);
4291 pixarray
+= msg
->modulo
;
4293 } /* if (linebuf) else ... */
4295 } /* for(y = 0; y < msg->height; y++) */
4297 if (linebuf
) FreeVec(linebuf
);
4299 ReturnVoid("BitMap::GetImageLUT");
4302 /*****************************************************************************************
4305 moHidd_BitMap_BlitColorExpansion
4308 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BlitColorExpansion *msg);
4310 VOID HIDD_BM_BlitColorExpansion (OOP_Object *obj, OOP_Object *gc, OOP_Object *srcBitMap,
4311 WORD srcX, WORD srcY, WORD destX, WORD destY,
4312 UWORD width, UWORD height);
4315 hidd.graphics.bitmap
4318 Perform a color expansion of the mask in srcBitMap according to foreground and background
4319 colors and expansion mode specified by the supplied GC. Pixels which are set to zero in
4320 the mask bitmap will be either painted by background (in opaque mode) or left without
4321 change (in transparent mode). Pixels which are set to nonzero in the mask will be painted
4322 by foreground color.
4324 The result of expansion is blitted onto the destination bitmap accorging to GC's draw mode.
4327 obj - A bitmap to draw on
4328 gc - A GC object to use for drawing
4329 srcBitMap - A bitmap object containing mask image.
4330 srcX, srcY - A top-left coordinate of the used rectangle in the source bitmap
4331 destX, destY - A top-left coordinate of the destination rectangle to draw in
4332 width, height - A size of the rectangle to blit
4338 This method was previously used by graphics.library/Text() to draw fonts with no
4339 styles specified. Currently graphics.library always uses BltTemplate() and this
4340 method is considered obsolete.
4350 *****************************************************************************************/
4352 VOID
BM__Hidd_BitMap__BlitColorExpansion(OOP_Class
*cl
, OOP_Object
*o
,
4353 struct pHidd_BitMap_BlitColorExpansion
*msg
)
4360 OOP_Object
*gc
= msg
->gc
;
4362 EnterFunc(bug("BitMap::BlitColorExpansion(srcBM=%p, srcX=%d, srcY=%d, destX=%d, destY=%d, width=%d, height=%d)\n",
4363 msg
->srcBitMap
, msg
->srcX
, msg
->srcY
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
));
4365 cemd
= GC_COLEXP(gc
);
4369 /* bug("------------- Blit_ColExp: (%d, %d, %d, %d, %d, %d) cemd=%d, fg=%p, bg=%p -------------\n"
4370 , msg->srcX, msg->srcY, msg->destX, msg->destY, msg->width, msg->height
4373 for (y
= 0; y
< msg
->height
; y
++)
4375 for (x
= 0; x
< msg
->width
; x
++)
4379 /* Pixel value is either 0 or 1 for BM of depth 1 */
4380 is_set
= HIDD_BM_GetPixel(msg
->srcBitMap
, x
+ msg
->srcX
, y
+ msg
->srcY
);
4390 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->destX
, y
+ msg
->destY
);
4394 if (cemd
& vHidd_GC_ColExp_Opaque
)
4396 /* Write bixel with BG pen */
4398 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->destX
, y
+ msg
->destY
);
4399 /* Reset to FG pen */
4405 } /* for (each x) */
4409 } /* for ( each y ) */
4412 ReturnVoid("BitMap::BlitColorExpansion");
4415 /*****************************************************************************************
4418 moHidd_BitMap_BytesPerLine
4421 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BytesPerLine *msg);
4423 ULONG HIDD_BM_BytesPerLine(OOP_Object *obj, HIDDT_StdPixFmt pixFmt, ULONG width);
4426 hidd.graphics.bitmap
4429 This method is currently not used and reserved.
4448 *****************************************************************************************/
4450 ULONG
BM__Hidd_BitMap__BytesPerLine(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_BytesPerLine
*msg
)
4455 switch (msg
->pixFmt
)
4457 case vHidd_StdPixFmt_Native32
:
4458 bpl
= sizeof (HIDDT_Pixel
) * msg
->width
;
4461 case vHidd_StdPixFmt_Native
:
4463 struct HIDDBitMapData
*data
;
4465 data
= OOP_INST_DATA(cl
, o
);
4467 bpl
= ((HIDDT_PixelFormat
*)data
->prot
.pixfmt
)->bytes_per_pixel
* msg
->width
;
4474 struct HIDDBitMapData
*data
;
4476 data
= OOP_INST_DATA(cl
, o
);
4478 pf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
4482 D(bug("!!! COULD NOT GET STD PIXFMT IN BitMap::BytesPerLine() !!!\n"));
4486 bpl
= ((HIDDT_PixelFormat
*)pf
)->bytes_per_pixel
* msg
->width
;
4498 /****************************************************************************************/
4501 This makes it easier to create a subclass of the graphics hidd.
4502 It is only allowed to use this method in the p_RootNew method of a
4506 /****************************************************************************************/
4508 VOID
BM__Root__Set(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_Set
*msg
)
4510 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
4511 struct TagItem
*tag
;
4512 const struct TagItem
*tstate
;
4515 /* EnterFunc(bug("BitMap::Set()\n"));
4517 tstate
= msg
->attrList
;
4518 while((tag
= NextTagItem(&tstate
)))
4520 if(IS_BITMAP_ATTR(tag
->ti_Tag
, idx
))
4524 case aoHidd_BitMap_Width
:
4525 data
->width
= tag
->ti_Data
;
4528 case aoHidd_BitMap_Height
:
4529 data
->height
= tag
->ti_Data
;
4532 case aoHidd_BitMap_Depth
:
4533 data
->reqdepth
= tag
->ti_Data
;
4537 case aoHidd_BitMap_ColorTab
:
4538 data
->colorTab
= (APTR
)tag
->ti_Data
;
4543 D(bug("!!! TRYING TO SET NONSETTABLE BITMAP ATTR %d !!!\n", idx
));
4553 /*****************************************************************************************
4556 moHidd_BitMap_SetColorMap
4559 OOP_Object * OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetColorMap *msg);
4561 OOP_Object * HIDD_BM_SetColorMap(OOP_Object *obj, OOP_Object *colorMap);
4564 hidd.graphics.bitmap
4584 *****************************************************************************************/
4586 OOP_Object
*BM__Hidd_BitMap__SetColorMap(OOP_Class
*cl
, OOP_Object
*o
,
4587 struct pHidd_BitMap_SetColorMap
*msg
)
4589 struct HIDDBitMapData
*data
;
4592 data
= OOP_INST_DATA(cl
, o
);
4595 data
->colmap
= msg
->colorMap
;
4600 /*****************************************************************************************
4603 moHidd_BitMap_MapColor
4606 HIDDT_Pixel OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_MapColor *msg);
4608 HIDDT_Pixel HIDD_BM_MapColor(OOP_Object *obj, HIDDT_Color *color);
4611 hidd.graphics.bitmap
4631 *****************************************************************************************/
4633 /* We only care about magnitudes here, so we don't
4634 * have to perform the square root operation to get
4635 * the real distance.
4637 static ULONG
colorDistance(HIDDT_Color
*a
, HIDDT_Color
*b
)
4639 #define SQR(x) ((x) * (x))
4640 return SQR((int)a
->red
- (int)b
->red
) +
4641 SQR((int)a
->blue
- (int)b
->blue
) +
4642 SQR((int)a
->green
- (int)b
->green
) +
4643 SQR((int)a
->alpha
- (int)b
->alpha
);
4647 HIDDT_Pixel
BM__Hidd_BitMap__MapColor(OOP_Class
*cl
, OOP_Object
*o
,
4648 struct pHidd_BitMap_MapColor
*msg
)
4650 HIDDT_PixelFormat
*pf
= BM_PIXFMT(o
);
4652 HIDDT_Pixel red
= msg
->color
->red
;
4653 HIDDT_Pixel green
= msg
->color
->green
;
4654 HIDDT_Pixel blue
= msg
->color
->blue
;
4655 HIDDT_Pixel alpha
= msg
->color
->alpha
;
4657 /* This code assumes that sizeof(HIDDT_Pixel) is a multiple of sizeof(col->#?),
4658 which should be true for most (all?) systems. I have never heard
4659 of any system with for example 3 byte types.
4662 if (IS_TRUECOLOR(pf
))
4664 if (HIDD_PF_SWAPPIXELBYTES(pf
))
4666 /* FIXME: BM__Hidd_BitMap__MapColor assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats */
4668 HIDDT_Pixel pixel
= MAP_RGBA(red
, green
, blue
, alpha
, pf
);
4670 msg
->color
->pixval
= SWAPBYTES_WORD(pixel
);
4674 msg
->color
->pixval
= MAP_RGBA(red
, green
, blue
, alpha
, pf
);
4679 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
4681 HIDDT_ColorLUT
*cmap
;
4683 ULONG best_ndx
= ~0, best_dist
= ~0;
4685 cmap
= (HIDDT_ColorLUT
*)data
->colmap
;
4686 ctab
= cmap
->colors
;
4687 /* Search for the best match in the color table */
4688 for (i
= 0; i
< cmap
->entries
; i
++) {
4691 dist
= colorDistance(&ctab
[i
], msg
->color
);
4692 if (dist
< best_dist
) {
4698 if (best_dist
!= ~0)
4699 msg
->color
->pixval
= ctab
[best_ndx
].pixval
;
4702 return msg
->color
->pixval
;
4705 /*****************************************************************************************
4708 moHidd_BitMap_UnmapPixel
4711 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_UnmapPixel *msg);
4713 VOID HIDD_BM_UnmapPixel(OOP_Object *obj, HIDDT_Pixel pixel, HIDDT_Color *color);
4716 hidd.graphics.bitmap
4737 *****************************************************************************************/
4739 VOID
BM__Hidd_BitMap__UnmapPixel(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_UnmapPixel
*msg
)
4742 HIDDT_PixelFormat
*pf
= BM_PIXFMT(o
);
4744 if (IS_TRUECOLOR(pf
))
4746 HIDDT_Pixel pixel
= msg
->pixel
;
4748 if (HIDD_PF_SWAPPIXELBYTES(pf
))
4750 /* FIXME: bitmap_unmappixel assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats */
4751 pixel
= SWAPBYTES_WORD(pixel
);
4754 msg
->color
->red
= RED_COMP (pixel
, pf
);
4755 msg
->color
->green
= GREEN_COMP (pixel
, pf
);
4756 msg
->color
->blue
= BLUE_COMP (pixel
, pf
);
4757 msg
->color
->alpha
= ALPHA_COMP (pixel
, pf
);
4761 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
4762 HIDDT_ColorLUT
*clut
;
4764 clut
= (HIDDT_ColorLUT
*)data
->colmap
;
4768 /* FIXME: Use CLUT shift and CLUT mask here */
4769 if (msg
->pixel
< 0 || msg
->pixel
>= clut
->entries
)
4772 *msg
->color
= clut
->colors
[msg
->pixel
];
4776 /* Unnecessary, but... */
4777 msg
->color
->pixval
= msg
->pixel
;
4780 /*****************************************************************************************
4783 moHidd_BitMap_ObtainDirectAccess
4786 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_ObtainDirectAccess *msg);
4788 BOOL HIDD_BM_ObtainDirectAccess(OOP_Object *obj, UBYTE **addressReturn,
4789 ULONG *widthReturn, ULONG *heightReturn,
4790 ULONG *bankSizeReturn, ULONG *memSizeReturn);
4793 hidd.graphics.bitmap
4818 *****************************************************************************************/
4820 BOOL
BM__Hidd_BitMap__ObtainDirectAccess(OOP_Class
*cl
, OOP_Object
*o
,
4821 struct pHidd_BitMap_ObtainDirectAccess
*msg
)
4823 /* Default implementation of direct access funcs. Just return FALSE */
4827 /*****************************************************************************************
4830 moHidd_BitMap_ReleaseDirectAccess
4833 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_ReleaseDirectAccess *msg);
4835 VOID HIDD_BM_ReleaseDirectAccess(OOP_Object *obj);
4838 hidd.graphics.bitmap
4857 *****************************************************************************************/
4859 VOID
BM__Hidd_BitMap__ReleaseDirectAccess(OOP_Class
*cl
, OOP_Object
*o
,
4860 struct pHidd_BitMap_ReleaseDirectAccess
*msg
)
4862 D(bug("!!! BitMap BaseClasse ReleaseDirectAccess() called !!!\n"));
4863 D(bug("!!! This should never happen and is probably due to a buggy implementation in the subclass !!!\n"));
4868 /*****************************************************************************************
4871 moHidd_BitMap_BitMapScale
4874 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BitMapScale * msg);
4876 VOID HIDD_BM_BitMapScale(OOP_Object *obj, OOP_Object *src, OOP_Object *dest,
4877 struct BitScaleArgs * bsa, OOP_Object *gc);
4880 hidd.graphics.bitmap
4903 *****************************************************************************************/
4905 VOID
BM__Hidd_BitMap__BitMapScale(OOP_Class
* cl
, OOP_Object
*o
,
4906 struct pHidd_BitMap_BitMapScale
* msg
)
4908 struct BitScaleArgs
*bsa
= msg
->bsa
;
4909 ULONG
*srcbuf
, *dstbuf
;
4913 UWORD ys
= bsa
->bsa_SrcY
;
4914 ULONG xs
= bsa
->bsa_SrcX
;
4915 ULONG dyd
= bsa
->bsa_DestHeight
;
4916 ULONG dxd
= bsa
->bsa_DestWidth
;
4919 ULONG dxs
= bsa
->bsa_SrcWidth
;
4920 ULONG dys
= bsa
->bsa_SrcHeight
;
4921 LONG accuyd
= - (dys
>> 1);
4922 LONG accuxd
= - (dxs
>> 1);
4925 if ((srcbuf
= AllocVec(bsa
->bsa_SrcWidth
* sizeof(ULONG
), 0)) == NULL
)
4928 if ((dstbuf
= AllocVec(bsa
->bsa_DestWidth
* sizeof(ULONG
), 0)) == NULL
) {
4933 if ((linepattern
= (UWORD
*) AllocVec(bsa
->bsa_DestWidth
* sizeof(UWORD
), 0)) == NULL
) {
4940 while (count
< bsa
->bsa_DestWidth
) {
4942 while (accuxd
> accuxs
) {
4947 linepattern
[count
] = xs
;
4952 count
= bsa
->bsa_DestY
;
4953 while (count
< bsa
->bsa_DestHeight
+ bsa
->bsa_DestY
) {
4955 while (accuyd
> accuys
) {
4960 if (srcline
!= ys
) {
4961 HIDD_BM_GetImage(msg
->src
, (UBYTE
*) srcbuf
, bsa
->bsa_SrcWidth
* sizeof(ULONG
), bsa
->bsa_SrcX
, bsa
->bsa_SrcY
+ ys
, bsa
->bsa_SrcWidth
, 1, vHidd_StdPixFmt_Native32
);
4964 for (x
= 0; x
< bsa
->bsa_DestWidth
; x
++)
4965 dstbuf
[x
] = srcbuf
[linepattern
[x
]];
4968 HIDD_BM_PutImage(msg
->dst
, msg
->gc
, (UBYTE
*) dstbuf
, bsa
->bsa_DestWidth
* sizeof(ULONG
), bsa
->bsa_DestX
, bsa
->bsa_DestY
+ count
, bsa
->bsa_DestWidth
, 1, vHidd_StdPixFmt_Native32
);
4973 FreeVec(linepattern
);
4979 /*****************************************************************************************
4982 moHidd_BitMap_SetRGBConversionFunction
4985 HIDDT_RGBConversionFunction
4986 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetRGBConversionFunction *msg);
4988 HIDDT_RGBConversionFunction
4989 HIDD_BM_SetRGBConversionFunction(OOP_Object *obj, HIDDT_StdPixFmt srcPixFmt,
4990 HIDDT_StdPixFmt dstPixFmt,
4991 HIDDT_RGBConversionFunction function);
4994 hidd.graphics.bitmap
5012 *****************************************************************************************/
5014 HIDDT_RGBConversionFunction
BM__Hidd_BitMap__SetRGBConversionFunction(OOP_Class
* cl
, OOP_Object
*o
,
5015 struct pHidd_BitMap_SetRGBConversionFunction
* msg
)
5017 HIDDT_RGBConversionFunction old
;
5019 if ((msg
->srcPixFmt
< FIRST_RGB_STDPIXFMT
) ||
5020 (msg
->dstPixFmt
< FIRST_RGB_STDPIXFMT
) ||
5021 (msg
->srcPixFmt
> LAST_RGB_STDPIXFMT
) ||
5022 (msg
->dstPixFmt
> LAST_RGB_STDPIXFMT
))
5024 return (HIDDT_RGBConversionFunction
)-1;
5028 ObtainSemaphore(&CSD(cl
)->rgbconvertfuncs_sem
);
5029 old
= CSD(cl
)->rgbconvertfuncs
[msg
->srcPixFmt
- FIRST_RGB_STDPIXFMT
][msg
->dstPixFmt
- FIRST_RGB_STDPIXFMT
];
5030 CSD(cl
)->rgbconvertfuncs
[msg
->srcPixFmt
- FIRST_RGB_STDPIXFMT
][msg
->dstPixFmt
- FIRST_RGB_STDPIXFMT
] = msg
->function
;
5031 ReleaseSemaphore(&CSD(cl
)->rgbconvertfuncs_sem
);
5037 /*****************************************************************************************
5040 moHidd_BitMap_UpdateRect
5043 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_UpdateRect *msg);
5045 VOID HIDD_BM_UpdateRect(OOP_Object *obj, WORD x, WORD y, WORD width, WORD height);
5048 hidd.graphics.bitmap
5051 Update displayed image of the given rectangle.
5053 Some drivers (like VGA and VESA) may work not with VRAM directly, but with a mirrored
5054 copy of it. Usually it is done in case if VRAM reading is slow. This method is called
5055 by the system after it completes any drawing operation, in order to make sure that
5056 changes made are visible on the actual screen. If your driver uses mirroring, this method
5057 should copy the given rectangle (at least) from the mirror buffer to the actual VRAM.
5059 This method is also called after changing currently visible bitmap (after moHidd_Gfx_Show
5060 method call) in order to allow the mirroring driver to refresh the screen after current bitmap
5061 changed. Note that moHidd_Gfx_ShowViewPorts is very different and moHidd_BitMap_UpdateRect
5062 will not be called if it succeeded!
5065 obj - an object whose image to refresh
5066 x, y - A top-left edge of the rectangle to refresh
5067 width - Width of the rectangle to refresh
5068 height - Height of the rectangle to refresh
5074 This method is called also on offscreen bitmaps. You should track visible state of your bitmap
5075 and ignore these calls if it's not currently visible on the screen.
5085 *****************************************************************************************/
5087 VOID
BM__Hidd_BitMap__UpdateRect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_UpdateRect
*msg
) {
5088 /* baseclass version does nothing */
5092 /****************************************************************************************/
5096 /****************************************************************************************/
5098 BOOL
BM__Hidd_BitMap__SetBitMapTags(OOP_Class
*cl
, OOP_Object
*o
,
5099 struct pHidd_BitMap_SetBitMapTags
*msg
)
5101 struct HIDDBitMapData
*data
;
5103 IPTR attrs
[num_Hidd_BitMap_Attrs
];
5104 DECLARE_ATTRCHECK(bitmap
);
5106 data
= OOP_INST_DATA(cl
, o
);
5108 if (0 != OOP_ParseAttrs(msg
->bitMapTags
5109 , attrs
, num_Hidd_BitMap_Attrs
5110 , &ATTRCHECK(bitmap
), HiddBitMapAttrBase
))
5112 D(bug("!!! FAILED PARSING IN BitMap::SetBitMapTags !!!\n"));
5116 if (GOT_BM_ATTR(PixFmtTags
))
5118 /* Already a pixfmt registered? */
5120 pf
= HIDD_Gfx_RegisterPixFmt(data
->gfxhidd
, (struct TagItem
*)attrs
[AO(PixFmtTags
)]);
5124 if (data
->pf_registered
)
5125 HIDD_Gfx_ReleasePixFmt(data
->gfxhidd
, data
->prot
.pixfmt
);
5127 data
->prot
.pixfmt
= pf
;
5131 if (GOT_BM_ATTR(Width
))
5132 data
->width
= attrs
[AO(Width
)];
5134 if (GOT_BM_ATTR(Height
))
5135 data
->height
= attrs
[AO(Height
)];
5137 if (GOT_BM_ATTR(BytesPerRow
))
5138 data
->bytesPerRow
= attrs
[AO(BytesPerRow
)];
5143 /****************************************************************************************/
5145 BOOL
HIDD_BitMap_SetBitMapTags(OOP_Object
*o
, struct TagItem
*bitMapTags
)
5148 struct pHidd_BitMap_SetBitMapTags p
, *msg
= &p
;
5150 if (!static_mid
) static_mid
= OOP_GetMethodID(IID_Hidd_BitMap
, moHidd_BitMap_SetBitMapTags
);
5154 p
.bitMapTags
= bitMapTags
;
5156 return (BOOL
)OOP_DoMethod(o
, (OOP_Msg
)msg
);
5159 /****************************************************************************************/