2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
5 Desc: Graphics bitmap class implementation.
9 /****************************************************************************************/
13 #define DPUTPATTERN(x)
15 #include <aros/debug.h>
16 #include <proto/exec.h>
17 #include <proto/utility.h>
18 #include <proto/oop.h>
19 #include <exec/memory.h>
20 #include <utility/tagitem.h>
22 #include <oop/static_mid.h>
23 #include <graphics/text.h>
24 #include <graphics/scale.h>
25 #include <hidd/graphics.h>
31 #include "graphics_intern.h"
33 /****************************************************************************************/
35 #define POINT_OUTSIDE_CLIP(gc, x, y) \
36 ( (x) < GC_CLIPX1(gc) \
37 || (x) > GC_CLIPX2(gc) \
38 || (y) < GC_CLIPY1(gc) \
39 || (y) > GC_CLIPY2(gc) )
41 /*****************************************************************************************
50 Every display driver should implement at least one bitmap class for displayable
53 Normally this class doesn't need to have public ID. In order to use it the driver
54 should pass class pointer as aoHidd_BitMap_ClassPtr value to the graphics base class
55 in its moHidd_Gfx_NewBitMap implementation.
57 BitMap base class is in C++ terminology a pure virtual
58 baseclass. It will not allocate any bitmap data at all;
59 that is up to the subclass to do.
61 The main task of the BitMap baseclass is to store some information about the bitmap
62 like its size and pixelformat. A pixelformat is an object of private class which
63 stores the actual information about the format.
65 There are two ways that we can find out the pixfmt in our moHidd_Gfx_NewBitMap
69 The tags will contain a modeid.
70 One can use this modeid to get a pointer to an
71 already registered pixfmt.
73 Non-displayable bitmap -
74 The aoHidd_BitMap_StdPixFmt or aoHidd_BitMap_Friend attribute will always be
77 *****************************************************************************************/
79 #define PIXBUFBYTES 16384
81 static BOOL
DoBufferedOperation(OOP_Class
*cl
, OOP_Object
*o
, UWORD startx
, UWORD starty
, UWORD width
, UWORD height
,
82 BOOL getimage
, HIDDT_StdPixFmt stdpf
, VOID_FUNC operation
, void *userdata
)
84 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
85 ULONG bytesperline
= width
* sizeof(ULONG
);
86 UWORD buflines
= PIXBUFBYTES
/ 4; /* Remove slow division */
88 UWORD endy
= starty
+ height
;
94 else if (buflines
> height
)
97 bufsize
= buflines
* bytesperline
;
98 buf
= AllocMem(bufsize
, MEMF_PUBLIC
);
99 if (!buf
&& (buflines
> 1))
101 /* Try to allocate single-line buffer */
103 bufsize
= bytesperline
;
104 buf
= AllocMem(bufsize
, MEMF_PUBLIC
);
109 for (y
= starty
; y
< endy
; y
+= buflines
)
111 if (y
+ buflines
> endy
)
113 /* This prevents overflow on last pass, buffer may be used only partially */
119 /* For some operations this can be optimized away */
120 HIDD_BM_GetImage(o
, buf
, bytesperline
, startx
, y
, width
, buflines
, stdpf
);
123 operation(buf
, y
, width
, buflines
, userdata
);
125 HIDD_BM_PutImage(o
, data
->gc
, buf
, bytesperline
, startx
, y
, width
, buflines
, stdpf
);
128 FreeMem(buf
, bufsize
);
132 /*****************************************************************************************
144 Specifies bitmap width in pixels.
146 Setting this attribute does not cause actual bitmap resize, just updates the information
147 about it. Use this only from within subclasses only if you know what you do. For example
148 SDL hosted driver sets it when framebufer changes the resolution.
161 *****************************************************************************************/
163 /*****************************************************************************************
175 Specifies bitmap height in pixels.
177 Setting this attribute does not cause actual bitmap resize, just updates the information
178 about it. Use this only from within subclasses only if you know what you do. For example
179 SDL hosted driver sets it when framebufer changes the resolution.
192 *****************************************************************************************/
194 /*****************************************************************************************
197 aoHidd_BitMap_Displayable
206 The bitmap is displayable. A displayable bitmap is always managed by a display
207 driver and must have valid display mode ID specification.
209 If this attribute is not supplied during bitmap creation, its value defaults
223 *****************************************************************************************/
225 /*****************************************************************************************
228 aoHidd_BitMap_Visible
237 Check if the bitmap is currently visible on screen
244 Not all display drivers implement this attribute. No AROS components currently rely
250 Some drivers may choose to have this attribute internally setable. Do not rely on it
251 in any way and do not attempt to set it manually from within applications, this will
252 not do any nice things.
254 *****************************************************************************************/
256 /*****************************************************************************************
259 aoHidd_BitMap_IsLinearMem
268 Check if the bitmap provides linear memory access. This means that bitmap's
269 pixelbuffer is directly addressable by the CPU.
271 Bitmaps with no linear memory may implement moHidd_BitMap_ObtainDirectAccess,
272 but this means that this method will rely on mirrored buffer. In such a case
273 the user must call moHidd_BitMap_UpdateRect after modifying bitmap's contents.
276 Used by cybergraphics.library/GetCyberMapAttr() for providing CYBRMATTR_ISLINEARMEM
282 Currently no display drivers implement this attribute despite many native mode
283 drivers actually provide linear memory.
286 moHidd_BitMap_ObtainDirectAccess, moHidd_BitMap_ReleaseDirectAccess,
287 moHidd_BitMap_UpdateRect
291 *****************************************************************************************/
293 /*****************************************************************************************
296 aoHidd_BitMap_BytesPerRow
305 Specify or query number of bytes per row in the bitmap storage buffer.
307 Setting this attribute doesn't actually cause changing buffer layout, just updates
308 the information about it. Use this only from within subclasses and only if you
309 exactly know why you do this.
311 Specifying this attribute during object creation overrides the value calculated
312 based on aoHidd_BitMap_Width and aoHidd_BitMap_Align values. Useful for wrapping
313 own buffers into bitmap objects, for example, in conjunction with
314 aoHidd_ChunkyBM_Buffer.
317 The returned value includes possible padding needed for alignment.
328 *****************************************************************************************/
330 /*****************************************************************************************
333 aoHidd_BitMap_ColorMap
342 Return associated colormap (palette) object.
344 By default only displayable bitmaps have colormaps. However a colormap can be attached
345 to any bitmap using moHidd_BitMap_SetColors or moHidd_BitMap_SetColorMap.
347 Note that manual attaching of a colormap to a nondisplayable bitmap may cause undesired
348 side-effects on graphics.library behavior. It's better not to do this at all. The system
349 knows what it does better than you.
358 moHidd_BitMap_SetColorMap, moHidd_BitMap_SetColors.
362 *****************************************************************************************/
364 /*****************************************************************************************
376 Specify a friend bitmap. The bitmap will be allocated so that it
377 is optimized for blitting to this bitmap.
379 Display drivers may query this attribute and then query friend bitmap
380 for anything they want (like pixelformat, mode ID, etc).
382 Note that explicit specification of mode ID and/or standard pixelformat
383 should override defaults provided by friend bitmap (i.e. actually breaking
396 *****************************************************************************************/
398 /*****************************************************************************************
401 aoHidd_BitMap_GfxHidd
410 Specify display driver object this bitmap was created with.
412 Normally the user doesn't have to supply this attribute. Instead you should use
413 driver's moHidd_Gfx_NewBitMap method in order to create bitmaps. In this case
414 aoHidd_BitMap_GfxHidd attribute will be provided by graphics driver base class
415 with the correct value.
417 It is illegal to manually create bitmap objects with no driver associated.
418 graphics.library maintains at least a memory driver for nondisplayable
419 bitmaps in system RAM without any acceleration.
428 CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
432 *****************************************************************************************/
434 /*****************************************************************************************
437 aoHidd_BitMap_StdPixFmt
440 [I..], HIDDT_StdPixFmt
446 Specify standard pixelformat code (one of vHidd_StdPixFmt_... values) for the
449 Values less than num_Hidd_PseudoStdPixFmt are illegal for this attribute.
451 Actually the bitmap class itself ignores this attribute. It is processed by
452 CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap method in order to look up a corresponding
453 pixelformat object in the system's database.
456 Bitmaps with this attribute set should be created as RAM bitmaps with direct CPU
457 access. It is not recommended to replace them with, for example, virtual surfaces on
458 hosted AROS. Such bitmaps are expected to be directly addressable and breaking
459 this may cause undesired side effects.
466 aoHidd_BitMap_PixFmt, CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
469 Currently all display drivers omit specifying own bitmap class for bitmaps with this
470 attribute set, letting base class (actually memory driver) to select an appropriate
471 class for it. This way it ends up in a bitmap of CLID_Hidd_ChunkyBM or CLID_Hidd_PlanarBM
472 class. It is recommended to follow this rule. It's not prohibited, however, to do some
473 adjustments to the bitmap (like alignment) in order to optimize blitting to/from it.
474 In fact if the display driver was asked to create such a bitmap, this means that
475 the standard bitmap is being created as a friend of some bitmap which was allocated
476 using this driver. This way the bitmap is expected to be friendly to this driver.
478 *****************************************************************************************/
480 /*****************************************************************************************
492 Specify or query pixelformat descriptor object associated with the bitmap.
494 Every bitmap has some associated pixelformat object. Pixelformat objects are
495 shared data storages, so many bitmaps may refer to the same pixelformat objects.
498 This attribute is internally specified during bitmap creation, but it's illegal
499 to do this for the user. NewBitMap method of graphics driver performs an explicit
500 check against this. It's up to graphics base classes to figure out its value.
510 *****************************************************************************************/
512 /*****************************************************************************************
524 Specify display mode ID for displayable bitmap.
526 A displayable bitmap must have this attribute supplied with valid value. A nondisplayable
527 one may miss it, however it may remember it if it was created as a friend of displayable
528 one. This way you may create another displayable bitmap as a friend of nondisplayable
529 one which in turn is a friend of displayable one.
531 This attribute can be set on a framebuffer bitmap. Doing so means an explicit request
532 for the driver to change current display mode on the hardware. Dependent parameters
533 (width, height and pixelformat) will be automatically adjusted, if not explicitly
534 specified in the attributes list.
537 If the given ModeID is not supported, the operation causes an error. You can check
538 for this by checking return value of OOP_SetAttrs() function. It will be TRUE in
539 case of success and FALSE upon failure. In case of failure none of bitmap attributes
550 *****************************************************************************************/
552 /*****************************************************************************************
555 aoHidd_BitMap_ClassPtr
564 Explicitly specify bitmap's class pointer.
566 This attribute is not actually a bitmap's attribute. Your display driver class can
567 supply it to base class' moHidd_Gfx_NewBitMap method in order to select a class on
568 which to call OOP_NewObject().
570 If neither this attribute nor aoHidd_BitMap_ClassID attribute is provided for
571 moHidd_Gfx_NewBitMap, graphics base class will do its best in order to find out the
572 correct class based on aoHidd_StdPixFmt attribute value or friend bitmap.
575 If a friend bitmap is given, the new bitmap will have the same class, if your driver
576 doesn't override it by supplying explicit class specification (using either
577 aoHidd_BitMap_ClassPtr or aoHidd_BitMap_ClassID attribute).
584 aoHidd_BitMap_ClassID, CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
588 *****************************************************************************************/
590 /*****************************************************************************************
593 aoHidd_BitMap_ClassID
602 Explicitly specify bitmap's class ID.
604 The purpose of this attribute is to let graphics driver base class to select a class
605 on which to call OOP_NewObject() in its moHidd_Gfx_NewBitMap implementation.
607 If neither this attribute nor aoHidd_BitMap_ClassPtr attribute is provided for
608 moHidd_Gfx_NewBitMap, graphics base class will do its best in order to find out the
609 correct class based on aoHidd_StdPixFmt attribute value or aoHidd_BitMap_ClassPtr value
617 The pointer to a given class will not be remembered as aoHidd_BitMap_ClassPtr value.
620 aoHidd_BitMap_ClassPtr, CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
624 *****************************************************************************************/
626 /*****************************************************************************************
629 aoHidd_BitMap_PixFmtTags
638 Private, very obsolete and currently has no function. Considered reserved.
650 *****************************************************************************************/
652 /*****************************************************************************************
655 aoHidd_BitMap_FrameBuffer
664 Specifies that the bitmap is a framebuffer bitmap.
666 A detailed description of a framebuffer is given in CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
667 and in CLID_Hidd_Gfx/moHidd_Gfx_Show documentation.
669 Specifying this attribute causes also implicit setting of aoHidd_BitMap_Displayable
682 *****************************************************************************************/
684 /*****************************************************************************************
687 aoHidd_BitMap_LeftEdge
696 Controls horizontal position of a scrollable screen bitmap.
698 Size of displayable bitmaps may differ from actual screen size. In this case the
699 bitmap can be scrolled around the whole display area. If the bitmap is larger than
700 the display, only its part can be visible.
702 Setting this attribute causes changing left origin point of the bitmap. The value
703 of this attribute represents an offset from the physical edge of the display to the
704 logical edge of the bitmap. This means that if a large bitmap scrolls to the left in
705 order to reveal its right part, the offset will be negative. If the bitmap scrolls
706 to the left (possibly revealing another bitmap behind it), the offset will be positive.
708 It's up to the display driver to set scroll limits. If the value of the attribute
709 becomes unacceptable for any reason, the driver should adjust it and provide the real
710 resulting value back.
713 Implementing screen scrolling does not enforce to implement screen composition, despite
714 the composition is really based on scrolling (in case of composition scrolling a bitmap
715 off-display is expected to reveal another bitmap behing it instead of empty space).
722 aoHidd_BitMap_TopEdge
725 Base class will always provide zero value for this attribute and ignore all attempts
726 to set it. This means that by default bitmaps don't scroll and this needs explicit
727 implementation in the display driver.
729 *****************************************************************************************/
731 /*****************************************************************************************
734 aoHidd_BitMap_TopEdge
743 Controls vertical position of a scrollable screen bitmap.
745 Size of displayable bitmaps may differ from actual screen size. In this case the
746 bitmap can be scrolled around the whole display area. If the bitmap is larger than
747 the display, only its part can be visible.
749 Setting this attribute causes changing top origin point of the bitmap. The value
750 of this attribute represents an offset from the physical edge of the display to the
751 logical edge of the bitmap. This means that if a large bitmap scrolls upwards in
752 order to reveal its bottom part, the offset will be negative. If the bitmap scrolls
753 downdards (possibly revealing another bitmap behind it), the offset will be positive.
755 It's up to the display driver to set scroll limits. If the value of the attribute
756 becomes unacceptable for any reason, the driver should adjust it and provide the real
757 resulting value back.
760 Implementing screen scrolling does not enforce to implement screen composition, despite
761 the composition is really based on scrolling (in case of composition scrolling a bitmap
762 off-display is expected to reveal another bitmap behing it instead of empty space).
772 *****************************************************************************************/
774 /*****************************************************************************************
786 Specify number of pixels to align bitmap data width to.
788 This attribute can be added in order to enforce alignment needed for example by
789 blitting hardware. It will have an impact on default aoHidd_BitMap_BytesPerRow
792 Direct specification of aoHidd_BitMap_BytesPerRow attribute overrides any value
796 Default value of this attribute is 16. This alignment is required by graphics.library
797 for AmigaOS(tm) compatibility reasons.
804 aoHidd_BitMap_BytesPerRow
808 *****************************************************************************************/
810 /*****************************************************************************************
822 Specify or query the actual bitmap depth.
824 This a convenience attribute to simplify handling planar bitmaps, whose actual depth
825 may vary. Default implementation in base class simply returns depth of bitmap's
826 pixelformat, and is ignored during initialization. Planar bitmap class returns the
827 actual depth here. If your specific bitmap class also operates on bitmaps with variable
828 depths, you need to implement this attribute in it.
840 *****************************************************************************************/
842 /****************************************************************************************/
847 * Calculate suggested bytes per row value based on bitmap's default alignment
848 * and pixelformat's bytes per pixel value.
850 static ULONG
GetBytesPerRow(struct HIDDBitMapData
*data
, struct class_static_data
*csd
)
852 struct Library
*OOPBase
= csd
->cs_OOPBase
;
853 UWORD align
= data
->align
- 1;
854 UWORD width
= (data
->width
+ align
) & ~align
;
855 IPTR bytesperpixel
, stdpf
;
857 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_BytesPerPixel
, &bytesperpixel
);
858 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_StdPixFmt
, &stdpf
);
860 if (stdpf
== vHidd_StdPixFmt_Plane
)
863 * Planar format actually have 8 pixels per one byte.
864 * However bytesperpixel == 1 for them. Perhaps this should
871 return width
* bytesperpixel
;
877 OOP_Object
*BM__Root__New(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_New
*msg
)
879 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
880 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
882 EnterFunc(bug("BitMap::New()\n"));
884 obj
= (OOP_Object
*)OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
) msg
);
888 struct TagItem colmap_tags
[] =
890 { aHidd_ColorMap_NumEntries
, 16 },
893 struct TagItem
*tag
, *tstate
;
895 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
897 /* Set some default values */
898 data
->modeid
= vHidd_ModeID_Invalid
;
901 tstate
= msg
->attrList
;
902 while ((tag
= NextTagItem(&tstate
)))
906 if (IS_BITMAP_ATTR(tag
->ti_Tag
, idx
))
910 case aoHidd_BitMap_Width
:
911 data
->width
= tag
->ti_Data
;
914 case aoHidd_BitMap_Height
:
915 data
->height
= tag
->ti_Data
;
918 case aoHidd_BitMap_Align
:
919 data
->align
= tag
->ti_Data
;
922 case aoHidd_BitMap_BytesPerRow
:
923 data
->bytesPerRow
= tag
->ti_Data
;
926 case aoHidd_BitMap_GfxHidd
:
927 data
->gfxhidd
= (OOP_Object
*)tag
->ti_Data
;
930 case aoHidd_BitMap_Friend
:
931 data
->friend = (OOP_Object
*)tag
->ti_Data
;
934 case aoHidd_BitMap_Displayable
:
935 data
->displayable
= tag
->ti_Data
;
938 case aoHidd_BitMap_FrameBuffer
:
939 data
->framebuffer
= tag
->ti_Data
;
942 case aoHidd_BitMap_ModeID
:
943 data
->modeid
= tag
->ti_Data
;
946 case aoHidd_BitMap_PixFmt
:
947 data
->prot
.pixfmt
= (OOP_Object
*)tag
->ti_Data
;
953 /* aoHidd_BitMap_GfxHidd is mandatory */
956 D(bug("!!!! BM CLASS DID NOT GET GFX HIDD !!!\n"));
957 D(bug("!!!! The reason for this is that the gfxhidd subclass NewBitmap() method\n"));
958 D(bug("!!!! has not left it to the baseclass to actually create the object,\n"));
959 D(bug("!!!! but rather done it itself. This MUST be corrected in the gfxhidd subclass\n"));
964 /* FrameBuffer implies Displayable */
965 if (data
->framebuffer
)
966 data
->displayable
= TRUE
;
968 if (ok
&& data
->displayable
)
970 /* We should allways get modeid, but we check anyway */
971 if (data
->modeid
== vHidd_ModeID_Invalid
)
973 D(bug("!!! BitMap:New() DID NOT GET MODEID FOR DISPLAYABLE BITMAP !!!\n"));
978 OOP_Object
*sync
, *pf
;
980 if (!HIDD_Gfx_GetMode(data
->gfxhidd
, data
->modeid
, &sync
, &pf
))
982 D(bug("!!! BitMap::New() RECEIVED INVALID MODEID 0x%08X\n", data
->modeid
));
987 /* Update the missing bitmap data from the modeid */
992 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &width
);
1000 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &height
);
1001 data
->height
= height
;
1004 if (!data
->prot
.pixfmt
)
1006 /* The PixFmt is allready registered and locked in the PixFmt database */
1007 data
->prot
.pixfmt
= pf
;
1015 /* * PixFmt will be NULL in case of e. g. planarbm late initialization. */
1016 if (data
->prot
.pixfmt
)
1018 ULONG bytesPerRow
= GetBytesPerRow(data
, CSD(cl
));
1020 if (data
->bytesPerRow
)
1022 /* If we have user-supplied BytesPerRow value, make sure it's suitable */
1023 if (data
->bytesPerRow
< bytesPerRow
)
1028 /* Otherwise we have what we calculated */
1029 data
->bytesPerRow
= bytesPerRow
;
1036 /* Cache default GC */
1037 OOP_GetAttr(data
->gfxhidd
, aHidd_Gfx_DefaultGC
, (IPTR
*)&data
->gc
);
1040 * Initialize the direct method calling.
1041 * We don't check against errors because our base class contains all
1044 #if USE_FAST_PUTPIXEL
1045 data
->putpixel
= OOP_GetMethod(obj
, HiddBitMapBase
+ moHidd_BitMap_PutPixel
, &data
->putpixel_Class
);
1047 #if USE_FAST_GETPIXEL
1048 data
->getpixel
= OOP_GetMethod(obj
, HiddBitMapBase
+ moHidd_BitMap_GetPixel
, &data
->getpixel_Class
);
1050 #if USE_FAST_DRAWPIXEL
1051 data
->drawpixel
= OOP_GetMethod(obj
, HiddBitMapBase
+ moHidd_BitMap_DrawPixel
, &data
->drawpixel_Class
);
1055 * Try to create the colormap.
1057 * stegerg: Only add a ColorMap for a visible bitmap (screen). This
1058 * is important because one can create for example a bitmap
1059 * in PIXFMT_LUT8 without friend bitmap and then copy this
1060 * bitmap to a 16 bit screen. During copy the screen bitmap
1061 * CLUT must be used, which would not happen if our PIXFMT_LUT8
1062 * also had a colormap itself because then bltbitmap would use the
1063 * colormap of the PIXFMT_LUT8 bitmap as lookup, which in this
1064 * case would just cause everything to become black in the
1065 * destination (screen) bitmap, because noone ever sets up the
1066 * colormap of the PIXFMT_LUT8 bitmap
1068 * sonic: CHECKME: Why does the colormap always have 16 colors? May be calculate this
1069 * based on depth ? The colormap auto-enlarges itself if SetColors method requests
1070 * missing entries, but is it so good?
1073 if (data
->displayable
)
1075 data
->colmap
= OOP_NewObject(NULL
, CLID_Hidd_ColorMap
, colmap_tags
);
1076 if (NULL
== data
->colmap
)
1084 ULONG dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
1086 OOP_CoerceMethod(cl
, obj
, &dispose_mid
);
1091 } /* if (NULL != obj) */
1093 ReturnPtr("BitMap::New", OOP_Object
*, obj
);
1096 /****************************************************************************************/
1098 void BM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*obj
, OOP_Msg
*msg
)
1100 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
1101 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
1103 EnterFunc(bug("BitMap::Dispose()\n"));
1105 if (NULL
!= data
->colmap
)
1106 OOP_DisposeObject(data
->colmap
);
1108 D(bug("Calling super\n"));
1110 /* Release the previously registered pixel format */
1111 if (data
->pf_registered
)
1112 GFX__Hidd_Gfx__ReleasePixFmt(CSD(cl
)->gfxhiddclass
, data
->prot
.pixfmt
);
1114 OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
) msg
);
1116 ReturnVoid("BitMap::Dispose");
1119 /****************************************************************************************/
1121 VOID
BM__Root__Get(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_Get
*msg
)
1123 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
1126 EnterFunc(bug("BitMap::Get() attrID: %i storage: %p\n", msg
->attrID
, msg
->storage
));
1128 if (IS_BITMAP_ATTR(msg
->attrID
, idx
))
1132 case aoHidd_BitMap_Width
:
1133 *msg
->storage
= data
->width
;
1134 D(bug(" width: %i\n", data
->width
));
1137 case aoHidd_BitMap_Height
:
1138 *msg
->storage
= data
->height
;
1141 case aoHidd_BitMap_Depth
:
1143 * Generally our bitmaps have a fixed depth, which depends on pixelformat.
1144 * If this is not true for your bitmap, overload aoHidd_BitMap_Depth in your class.
1146 *msg
->storage
= ((HIDDT_PixelFormat
*)data
->prot
.pixfmt
)->depth
;
1149 case aoHidd_BitMap_Displayable
:
1150 *msg
->storage
= data
->displayable
;
1153 case aoHidd_BitMap_FrameBuffer
:
1154 *msg
->storage
= data
->framebuffer
;
1157 case aoHidd_BitMap_PixFmt
:
1158 *msg
->storage
= (IPTR
)data
->prot
.pixfmt
;
1161 case aoHidd_BitMap_Friend
:
1162 *msg
->storage
= (IPTR
)data
->friend;
1165 case aoHidd_BitMap_ColorMap
:
1166 *msg
->storage
= (IPTR
)data
->colmap
;
1169 case aoHidd_BitMap_GfxHidd
:
1170 *msg
->storage
= (IPTR
)data
->gfxhidd
;
1173 case aoHidd_BitMap_ModeID
:
1174 *msg
->storage
= data
->modeid
;
1177 case aoHidd_BitMap_Align
:
1178 *msg
->storage
= data
->align
;
1181 case aoHidd_BitMap_BytesPerRow
:
1182 *msg
->storage
= data
->bytesPerRow
;
1185 /* Generic bitmaps don't scroll. This has to be implemented in the subclass. */
1186 case aoHidd_BitMap_LeftEdge
:
1187 case aoHidd_BitMap_TopEdge
:
1191 D(default: bug("UNKNOWN ATTR IN BITMAP BASECLASS: %d\n", idx
);)
1195 OOP_DoSuperMethod(cl
, obj
, &msg
->mID
);
1196 ReturnVoid("BitMap::Get");
1199 /****************************************************************************************/
1201 #define UB(x) ((UBYTE *)x)
1203 /*****************************************************************************************
1206 moHidd_BitMap_SetColors
1209 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetColors *msg);
1211 BOOL HIDD_BM_SetColors (OOP_Object *obj, HIDDT_Color *colors,
1212 UWORD firstColor, UWORD numColors);
1215 hidd.graphics.bitmap
1218 Sets values for one or more colors in the colormap object associated with the
1221 The colormap will be created if it does not exist.
1223 Only ARGB values from the source array are taken into account. pixval member is
1224 updated with the real pixel value for every color.
1227 obj - A bitmap object whose colormap needs to be set
1228 colors - A pointer to source data array
1229 firstColor - Number of the first color to set
1230 numColors - Number of subsequent colors to set
1233 TRUE on success, FALSE in case of some error (like out of memory)
1242 CLID_Hidd_ColorMap/moHidd_ColorMap_SetColors
1246 *****************************************************************************************/
1248 BOOL
BM__Hidd_BitMap__SetColors(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_SetColors
*msg
)
1250 /* Copy the colors into the internal buffer */
1251 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
1252 struct HIDDBitMapData
*data
;
1254 data
= OOP_INST_DATA(cl
, o
);
1256 /* Subclass has initialized HIDDT_Color->pixelVal field and such.
1257 Just copy it into the colortab.
1260 if (NULL
== data
->colmap
)
1262 struct TagItem colmap_tags
[] =
1264 { aHidd_ColorMap_NumEntries
, 0 },
1268 colmap_tags
[0].ti_Data
= msg
->firstColor
+ msg
->numColors
;
1269 data
->colmap
= OOP_NewObject(NULL
, CLID_Hidd_ColorMap
, colmap_tags
);
1272 if (NULL
== data
->colmap
)
1277 /* Use the colormap class to set the colors */
1278 return HIDD_CM_SetColors(data
->colmap
, msg
->colors
,
1279 msg
->firstColor
, msg
->numColors
,
1284 /*****************************************************************************************
1287 moHidd_BitMap_DrawPixel
1290 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPixel *msg);
1292 ULONG HIDD_BM_DrawPixel(OOP_Object *obj, OOP_Object *gc, WORD x, WORD y);
1295 hidd.graphics.bitmap
1298 Changes the pixel at (x,y). The color of the pixel depends on the
1299 attributes of gc, eg. colors, drawmode, colormask etc.
1300 This function does not check the coordinates.
1303 obj - A bitmap to draw on
1304 gc - A GC (graphics context) object to use for drawing
1305 x, y - Coordinates of the pixel to draw
1308 Undefined. Many drivers declare this method as void.
1321 - Support for shapeplane.
1324 *****************************************************************************************/
1326 ULONG
BM__Hidd_BitMap__DrawPixel(OOP_Class
*cl
, OOP_Object
*obj
,
1327 struct pHidd_BitMap_DrawPixel
*msg
)
1329 HIDDT_Pixel src
, dest
, val
;
1330 HIDDT_DrawMode mode
;
1331 HIDDT_Pixel writeMask
;
1334 /* EnterFunc(bug("BitMap::DrawPixel() x: %i, y: %i\n", msg->x, msg->y));
1337 Example: Pixels which bits are set to 0 in the colMask must be
1340 data->colMask = 001111
1344 writeMask = ~data->colMask & dest
1348 dest = data->fg && dest = 010100
1351 dest = dest & (writeMask | data->ColMask)
1352 = 010100 & (100000 | 001111)
1357 dest = dest | writeMask;
1368 #if OPTIMIZE_DRAWPIXEL_FOR_COPY
1369 if (vHidd_GC_DrawMode_Copy
== mode
&& GC_COLMASK(gc
) == ~0)
1376 dest
= GETPIXEL(cl
, obj
, msg
->x
, msg
->y
);
1377 writeMask
= ~GC_COLMASK(gc
) & dest
;
1381 if(mode
& 1) val
= ( src
& dest
);
1382 if(mode
& 2) val
= ( src
& ~dest
) | val
;
1383 if(mode
& 4) val
= (~src
& dest
) | val
;
1384 if(mode
& 8) val
= (~src
& ~dest
) | val
;
1386 val
= (val
& (writeMask
| GC_COLMASK(gc
) )) | writeMask
;
1390 PUTPIXEL(cl
, obj
, msg
->x
, msg
->y
, val
);
1392 /* ReturnInt("BitMap::DrawPixel ", ULONG, 1); */ /* in quickmode return always 1 */
1397 /*****************************************************************************************
1400 moHidd_BitMap_DrawLine
1403 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPixel *msg);
1405 VOID HIDD_BM_DrawLine(OOP_Object *obj, OOP_Object *gc, WORD x1, WORD y1,
1409 hidd.graphics.bitmap
1412 Draws a line from (x1,y1) to (x2,y2) in the specified gc.
1413 The function does not clip the line against the drawing area.
1416 obj - A bitmap to draw on
1417 gc - A graphics context object to use
1418 x1,y1 - start point of the line in pixels
1419 x2,y2 - end point of the line in pixels
1433 Uses midpoint line ("Bresenham") algorithm([FOL90] 3.2.2)
1435 TODO Support for line pattern
1436 Optimize remove if t == 1 ...
1437 Implement better clipping: Should be no reason to calculate
1438 more than the part of the line that is inside the cliprect
1440 *****************************************************************************************/
1442 VOID BM__Hidd_BitMap__DrawLine
1444 OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawLine
*msg
1447 WORD dx
, dy
, incrE
, incrNE
, d
, x
, y
, s1
, s2
, t
, i
;
1448 WORD x1
, y1
, x2
, y2
;
1449 UWORD maskLine
; /* for line pattern */
1450 ULONG fg
; /* foreground pen */
1456 /* bug("BitMap::DrawLine()\n");
1457 */ EnterFunc(bug("BitMap::DrawLine() x1: %i, y1: %i x2: %i, y2: %i\n", msg
->x1
, msg
->y1
, msg
->x2
, msg
->y2
));
1460 doclip
= GC_DOCLIP(gc
);
1461 opaque
= (GC_COLEXP(gc
) & vHidd_GC_ColExp_Opaque
) ? TRUE
: FALSE
;
1464 maskLine
= 1 << GC_LINEPATCNT(gc
);
1468 /* If line is not inside cliprect, then just return */
1469 /* Normalize coords */
1470 if (msg
->x1
> msg
->x2
)
1472 x1
= msg
->x2
; x2
= msg
->x1
;
1476 x1
= msg
->x1
; x2
= msg
->x2
;
1479 if (msg
->y1
> msg
->y2
)
1481 y1
= msg
->y2
; y2
= msg
->y1
;
1485 y1
= msg
->y1
; y2
= msg
->y2
;
1488 if ( x1
> GC_CLIPX2(gc
)
1489 || x2
< GC_CLIPX1(gc
)
1490 || y1
> GC_CLIPY2(gc
)
1491 || y2
< GC_CLIPY1(gc
) )
1494 /* Line is not inside cliprect, so just return */
1508 Horizontal line drawing code.
1512 /* Don't swap coordinates if x2 < x1! Because of linepattern! */
1525 for(i
= x1
; i
!= x2
; i
+= dx
)
1527 /* Pixel inside ? */
1529 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, i
, y
))
1531 if(GC_LINEPAT(gc
) & maskLine
)
1533 HIDD_BM_DrawPixel(obj
, gc
, i
, y
);
1537 GC_FG(gc
) = GC_BG(gc
);
1538 HIDD_BM_DrawPixel(obj
, gc
, i
, y
);
1543 maskLine
= maskLine
>> 1;
1544 if (!maskLine
) maskLine
= 1L << 15;
1550 Vertical line drawing code.
1554 /* Don't swap coordinates if y2 < y1! Because of linepattern! */
1567 for(i
= y1
; i
!= y2
; i
+= dy
)
1569 /* Pixel inside ? */
1570 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, x
, i
))
1572 if(GC_LINEPAT(gc
) & maskLine
)
1574 HIDD_BM_DrawPixel(obj
, gc
, x
, i
);
1578 GC_FG(gc
) = GC_BG(gc
);
1579 HIDD_BM_DrawPixel(obj
, gc
, x
, i
);
1584 maskLine
= maskLine
>> 1;
1585 if (!maskLine
) maskLine
= 1L << 15;
1592 Generic line drawing code.
1594 /* Calculate slope */
1598 /* which direction? */
1599 if((x2
- x1
) > 0) s1
= 1; else s1
= - 1;
1600 if((y2
- y1
) > 0) s2
= 1; else s2
= - 1;
1602 /* change axes if dx < dy */
1615 d
= 2 * dy
- dx
; /* initial value of d */
1617 incrE
= 2 * dy
; /* Increment use for move to E */
1618 incrNE
= 2 * (dy
- dx
); /* Increment use for move to NE */
1622 for(i
= 0; i
<= dx
; i
++)
1624 /* Pixel inside ? */
1625 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, x
, y
))
1627 if(GC_LINEPAT(gc
) & maskLine
)
1629 HIDD_BM_DrawPixel(obj
, gc
, x
, y
);
1633 GC_FG(gc
) = GC_BG(gc
);
1634 HIDD_BM_DrawPixel(obj
, gc
, x
, y
);
1659 maskLine
= maskLine
>> 1;
1660 if (!maskLine
) maskLine
= 1L << 15;
1665 ReturnVoid("BitMap::DrawLine ");
1668 /*****************************************************************************************
1671 moHidd_BitMap_DrawRect
1674 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawRect *msg);
1676 VOID HIDD_BM_DrawRect (OOP_Object *obj, OOP_Object *gc, WORD minX, WORD minY,
1677 WORD maxX, WORD maxY);
1680 hidd.graphics.bitmap
1683 Draws a hollow rectangle. minX and minY specifies the upper
1684 left corner of the rectangle. minY and maxY specifies the lower
1685 right corner of the rectangle.
1686 The function does not clip the rectangle against the drawing area.
1689 obj - A bitmap to draw on
1690 gc - A GC object to use for drawing
1691 minX, minY - upper left corner of the rectangle in pixels
1692 maxX, maxY - lower right corner of the rectangle in pixels
1698 This method is not used by the system and considered reserved.
1710 *****************************************************************************************/
1712 VOID
BM__Hidd_BitMap__DrawRect(OOP_Class
*cl
, OOP_Object
*obj
,
1713 struct pHidd_BitMap_DrawRect
*msg
)
1716 OOP_Object
*gc
= msg
->gc
;
1719 EnterFunc(bug("BitMap::DrawRect()"));
1721 if(msg
->minX
== msg
->maxX
) addX
= 0; else addX
= 1;
1722 if(msg
->minY
== msg
->maxY
) addY
= 0; else addY
= 1;
1724 HIDD_BM_DrawLine(obj
, gc
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->minY
);
1725 HIDD_BM_DrawLine(obj
, gc
, msg
->maxX
, msg
->minY
+ addY
, msg
->maxX
, msg
->maxY
);
1726 HIDD_BM_DrawLine(obj
, gc
, msg
->maxX
- addX
, msg
->maxY
, msg
->minX
, msg
->maxY
);
1727 HIDD_BM_DrawLine(obj
, gc
, msg
->minX
, msg
->maxY
- addY
, msg
->minX
, msg
->minY
+ addY
);
1730 ReturnVoid("BitMap::DrawRect");
1733 /*****************************************************************************************
1736 moHidd_BitMap_FillRect
1739 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawRect *msg);
1741 VOID HIDD_BM_FillRect (OOP_Object *obj, OOP_Object *gc, WORD minX, WORD minY,
1742 WORD maxX, WORD maxY);
1745 hidd.graphics.bitmap
1749 Draws a solid rectangle. minX and minY specifies the upper
1750 left corner of the rectangle. minY and maxY specifies the lower
1751 right corner of the rectangle.
1752 The function does not clip the rectangle against the drawing area.
1755 obj - A bitmap to draw on
1756 gc - A GC object to use for drawing
1757 minX, minY - upper left corner of the rectangle in pixels
1758 maxX, maxY - lower right corner of the rectangle in pixels
1776 *****************************************************************************************/
1778 VOID
BM__Hidd_BitMap__FillRect(OOP_Class
*cl
, OOP_Object
*obj
,
1779 struct pHidd_BitMap_DrawRect
*msg
)
1781 OOP_Object
*gc
= msg
->gc
;
1785 EnterFunc(bug("BitMap::FillRect()"));
1787 linepat
= GC_LINEPAT(gc
);
1788 GC_LINEPAT(gc
) = ~0;
1790 for(; y
<= msg
->maxY
; y
++)
1792 HIDD_BM_DrawLine(obj
, gc
, msg
->minX
, y
, msg
->maxX
, y
);
1795 GC_LINEPAT(gc
) = linepat
;
1797 ReturnVoid("BitMap::FillRect");
1800 /*****************************************************************************************
1803 moHidd_BitMap_DrawEllipse
1806 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawEllipse *msg);
1808 VOID HIDD_BM_DrawEllipse (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
1812 hidd.graphics.bitmap
1815 Draws a hollow ellipse from the center point (x,y) with the radii
1816 rx and ry in the specified bitmap.
1817 The function does not clip the ellipse against the drawing area.
1820 obj - A bitmap to draw on
1821 gc - A GC object to use for drawing
1822 x,y - Coordinates of center point in pixels
1823 rx,ry - ry and ry radius in pixels
1833 Because of overflow the current code do not work with big
1834 values of rx and ry.
1843 *****************************************************************************************/
1845 /* TODO: Try to opimize clipping here */
1847 VOID
BM__Hidd_BitMap__DrawEllipse(OOP_Class
*cl
, OOP_Object
*obj
,
1848 struct pHidd_BitMap_DrawEllipse
*msg
)
1850 OOP_Object
*gc
= msg
->gc
;
1851 WORD x
= msg
->rx
, y
= 0; /* ellipse points */
1853 /* intermediate terms to speed up loop */
1854 WORD t1
= msg
->rx
* msg
->rx
, t2
= t1
<< 1, t3
= t2
<< 1;
1855 WORD t4
= msg
->ry
* msg
->ry
, t5
= t4
<< 1, t6
= t5
<< 1;
1856 WORD t7
= msg
->rx
* t5
, t8
= t7
<< 1, t9
= 0L;
1857 WORD d1
= t2
- t7
+ (t4
>> 1); /* error terms */
1858 WORD d2
= (t1
>> 1) - t8
+ t5
;
1860 APTR doclip
= GC_DOCLIP(gc
);
1863 EnterFunc(bug("BitMap::DrawEllipse()"));
1865 while (d2
< 0) /* til slope = -1 */
1867 /* draw 4 points using symmetry */
1872 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
+ y
))
1873 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1875 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
- y
))
1876 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1878 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
+ y
))
1879 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1881 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
- y
))
1882 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1887 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1888 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1889 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1890 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1893 y
++; /* always move up here */
1895 if (d1
< 0) /* move straight up */
1900 else /* move up and left */
1904 d1
= d1
+ t9
+ t2
- t8
;
1905 d2
= d2
+ t9
+ t5
- t8
;
1909 do /* rest of top right quadrant */
1911 /* draw 4 points using symmetry */
1916 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
+ y
))
1917 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1919 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
- y
))
1920 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1922 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
+ y
))
1923 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1925 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
- y
))
1926 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1932 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1933 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1934 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1935 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1939 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1940 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1941 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1942 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1944 x
--; /* always move left here */
1946 if (d2
< 0) /* move up and left */
1950 d2
= d2
+ t9
+ t5
- t8
;
1952 else /* move straight left */
1960 ReturnVoid("BitMap::DrawEllipse");
1963 /*****************************************************************************************
1966 moHidd_BitMap_FillEllipse
1969 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawEllipse *msg);
1971 VOID HIDD_BM_FillEllipse (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
1975 hidd.graphics.bitmap
1978 Draws a solid ellipse from the center point (x,y) with the radii
1979 rx and ry in the specified bitmap.
1980 The function does not clip the ellipse against the drawing area.
1983 obj - A bitmap to draw on
1984 gc - A GC object to use for drawing
1985 x,y - Coordinates of center point in pixels
1986 rx,ry - ry and ry radius in pixels
1992 This method is not used by the system and considered reserved.
1996 Because of overflow the current code do not work with big
1997 values of rx and ry.
2006 *****************************************************************************************/
2008 VOID
BM__Hidd_BitMap__FillEllipse(OOP_Class
*cl
, OOP_Object
*obj
,
2009 struct pHidd_BitMap_DrawEllipse
*msg
)
2012 OOP_Object
*gc
= msg
->gc
;
2013 WORD x
= msg
->rx
, y
= 0; /* ellipse points */
2015 /* intermediate terms to speed up loop */
2016 WORD t1
= msg
->rx
* msg
->rx
, t2
= t1
<< 1, t3
= t2
<< 1;
2017 WORD t4
= msg
->ry
* msg
->ry
, t5
= t4
<< 1, t6
= t5
<< 1;
2018 WORD t7
= msg
->rx
* t5
, t8
= t7
<< 1, t9
= 0L;
2019 WORD d1
= t2
- t7
+ (t4
>> 1); /* error terms */
2020 WORD d2
= (t1
>> 1) - t8
+ t5
;
2022 EnterFunc(bug("BitMap::FillEllipse()"));
2024 while (d2
< 0) /* til slope = -1 */
2026 /* draw 4 points using symmetry */
2027 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
+ y
, msg
->x
+ x
, msg
->y
+ y
);
2028 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
- y
, msg
->x
+ x
, msg
->y
- y
);
2030 y
++; /* always move up here */
2032 if (d1
< 0) /* move straight up */
2037 else /* move up and left */
2041 d1
= d1
+ t9
+ t2
- t8
;
2042 d2
= d2
+ t9
+ t5
- t8
;
2046 do /* rest of top right quadrant */
2048 /* draw 4 points using symmetry */
2049 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
+ y
, msg
->x
+ x
, msg
->y
+ y
);
2050 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
- y
, msg
->x
+ x
, msg
->y
- y
);
2052 x
--; /* always move left here */
2054 if (d2
< 0) /* move up and left */
2058 d2
= d2
+ t9
+ t5
- t8
;
2060 else /* move straight left */
2068 ReturnVoid("BitMap::FillEllipse");
2071 /*****************************************************************************************
2074 moHidd_BitMap_DrawPolygon
2077 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg);
2079 VOID HIDD_BM_DrawPolygon (OOP_Object *obj, OOP_Object *gc, UWORD n, WORD *coords);
2082 hidd.graphics.bitmap
2085 Draws a hollow polygon from the list of coordinates in coords[].
2086 The function does not clip the polygon against the drawing area.
2089 obj - A bitmap to draw on
2090 gc - A GC object to use for drawing
2091 n - number of coordinate pairs
2092 coords - array of n (x, y) coordinates in pixels
2098 This method is not used by the system and considered reserved.
2110 *****************************************************************************************/
2112 VOID
BM__Hidd_BitMap__DrawPolygon(OOP_Class
*cl
, OOP_Object
*obj
,
2113 struct pHidd_BitMap_DrawPolygon
*msg
)
2116 OOP_Object
*gc
= msg
->gc
;
2119 EnterFunc(bug("BitMap::DrawPolygon()"));
2121 for(i
= 2; i
< (2 * msg
->n
); i
= i
+ 2)
2123 HIDD_BM_DrawLine(obj
, gc
, msg
->coords
[i
- 2], msg
->coords
[i
- 1],
2124 msg
->coords
[i
], msg
->coords
[i
+ 1]);
2128 ReturnVoid("BitMap::DrawPolygon");
2131 /*****************************************************************************************
2134 moHidd_BitMap_FillPolygon
2137 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg);
2139 VOID HIDD_BM_FillPolygon (OOP_Object *obj, OOP_Object *gc, UWORD n, WORD *coords);
2142 hidd.graphics.bitmap
2145 This method was initially designed for drawing solid polygons, however it was never
2146 used and implemented. At the moment it is considered reserved, its synopsis and
2147 semantics may change in future.
2150 obj - A bitmap to draw on
2151 gc - A GC object to use for drawing
2152 n - number of coordinate pairs
2153 coords - array of n (x, y) coordinates in pixels
2163 Never used and implemented
2171 *****************************************************************************************/
2173 VOID
BM__Hidd_BitMap__FillPolygon(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawPolygon
*msg
)
2175 D(bug("Sorry, FillPolygon() not implemented yet in bitmap baseclass\n"));
2178 /*****************************************************************************************
2181 moHidd_BitMap_DrawText
2184 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2186 VOID HIDD_BM_DrawText (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2187 STRPTR text, UWORD length);
2190 hidd.graphics.bitmap
2193 Draws the first length characters of text at (x, y).
2194 The function does not clip the text against the drawing area.
2197 obj - A bitmap to draw on
2198 gc - A GC object to use for drawing and font specification
2199 x, y - Position to start drawing in pixels. The x
2200 coordinate is relativ to the left side of the
2202 The y coordinate is relative to the baseline of the font.
2203 text - Pointer to a Latin 1 string
2204 length - Number of characters to draw
2210 At the moment text drawing is processed entirely by graphics.library
2211 using BltTemplate(), which in turn uses moHodd_BitMap_PutTemplate.
2212 This method is considered obsolete.
2217 The default implementation in the base class does not process styles,
2218 color and alpha-blended fonts.
2226 *****************************************************************************************/
2228 VOID
BM__Hidd_BitMap__DrawText(OOP_Class
*cl
, OOP_Object
*obj
,
2229 struct pHidd_BitMap_DrawText
*msg
)
2232 OOP_Object
*gc
= msg
->gc
;
2233 struct TextFont
*font
= GC_FONT(gc
);
2234 UBYTE
*charPatternPtr
= font
->tf_CharData
;
2235 UWORD modulo
= font
->tf_Modulo
;
2237 UBYTE ch
; /* current character to print */
2238 WORD fx
, fx2
, fy
, fw
; /* position and length of character in the */
2239 /* character bitmap */
2240 WORD xMem
= msg
->x
; /* position in bitmap */
2241 WORD yMem
= msg
->y
- font
->tf_Baseline
;
2245 EnterFunc(bug("BitMap::DrawText()"));
2247 for(i
= 0; i
< msg
->length
; i
++)
2251 if((ch
< font
->tf_LoChar
) || (ch
> font
->tf_HiChar
))
2253 ch
= font
->tf_HiChar
- font
->tf_LoChar
+ 1;
2257 ch
= ch
- font
->tf_LoChar
;
2260 if(font
->tf_Flags
& FPF_PROPORTIONAL
)
2262 xMem
= xMem
+ ((UWORD
*) font
->tf_CharKern
)[ch
];
2265 charLog
= ((ULONG
*) font
->tf_CharLoc
)[ch
];
2266 fx2
= charLog
>> 16; /* x position of character pattern in character bitmap */
2267 fw
= (UWORD
) charLog
; /* width of character pattern in character bitmap */
2271 for(fy
= 0; fy
< font
->tf_YSize
; fy
++)
2275 for(fx
= fx2
; fx
< fw
+ fx2
; fx
++)
2277 if(*(charPatternPtr
+ fx
/ 8 + fy
* modulo
) & (128 >> (fx
% 8)))
2279 HIDD_BM_DrawPixel(obj
, msg
->gc
, x
, y
);
2287 if(font
->tf_Flags
& FPF_PROPORTIONAL
)
2289 xMem
= xMem
+ ((UWORD
*) font
->tf_CharSpace
)[ch
];
2293 xMem
= xMem
+ font
->tf_XSize
;
2297 ReturnVoid("BitMap::DrawText");
2300 /*****************************************************************************************
2303 moHidd_BitMap_FillText
2306 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2308 VOID HIDD_BM_FillText (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2309 STRPTR text, UWORD length);
2312 hidd.graphics.bitmap
2315 Historically this method was designed to draw a text with background.
2316 It was never implemented.
2318 Currently this method is considered reserved. Its synopsis and semantics
2319 may change in future.
2322 obj - A bitmap to draw on
2323 gc - A GC object to use for drawing
2324 x, y - Position to start drawing in pixels. The x
2325 coordinate is relative to the left side of the
2327 The y coordinate is relative to the baseline of the font.
2328 text - Pointer to a Latin 1 string
2329 length - Number of characters to draw
2345 *****************************************************************************************/
2347 VOID
BM__Hidd_BitMap__FillText(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawText
*msg
)
2349 D(bug("Sorry, FillText() not implemented yet in bitmap baseclass\n"));
2352 /*****************************************************************************************
2355 moHidd_BitMap_FillSpan
2358 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2361 hidd.graphics.bitmap
2364 Reserved, never implemented method. The definition will change in future.
2383 *****************************************************************************************/
2385 VOID
BM__Hidd_BitMap__FillSpan(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawText
*msg
)
2387 D(bug("Sorry, FillSpan() not implemented yet\n"));
2390 /*****************************************************************************************
2396 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_Clear *msg);
2398 VOID HIDD_BM_Clear (OOP_Object *obj, OOP_Object *gc);
2401 hidd.graphics.bitmap
2404 Sets all pixels of the drawing area to the background color.
2407 obj - A bitmap to clear.
2408 gc - A GC object, specifies background color value
2413 This method is not used by the system and considered reserved. However it can
2414 be useful for display driver's own needs.
2419 Default implementation in the base class sets all pixels to zero color instead of
2420 the background color from GC
2428 *****************************************************************************************/
2430 VOID
BM__Hidd_BitMap__Clear(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_Clear
*msg
)
2432 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
2436 EnterFunc(bug("BitMap::Clear()\n"));
2438 OOP_GetAttr(obj
, aHidd_BitMap_Width
, &width
);
2439 OOP_GetAttr(obj
, aHidd_BitMap_Height
, &height
);
2441 for(y
= 0; y
< height
; y
++)
2443 for(x
= 0; x
< width
; x
++)
2445 HIDD_BM_PutPixel(obj
, x
, y
, 0);
2449 ReturnVoid("BitMap::Clear");
2452 /****************************************************************************************/
2454 static LONG
inline getpixfmtbpp(OOP_Class
*cl
, OOP_Object
*o
, HIDDT_StdPixFmt stdpf
)
2456 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
2458 struct HIDDBitMapData
*data
;
2461 data
= OOP_INST_DATA(cl
, o
);
2465 case vHidd_StdPixFmt_Native
:
2466 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_BytesPerPixel
, &bpp
);
2469 case vHidd_StdPixFmt_Native32
:
2470 bpp
= sizeof (HIDDT_Pixel
);
2474 pf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, stdpf
);
2478 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", stdpf
));
2482 OOP_GetAttr(pf
, aHidd_PixFmt_BytesPerPixel
, &bpp
);
2490 /*****************************************************************************************
2493 moHidd_BitMap_GetImage
2496 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_GetImage *msg);
2498 VOID HIDD_BM_GetImage (OOP_Object *obj, UBYTE *pixels, ULONG modulo, WORD x, WORD y,
2499 WORD width, WORD height, HIDDT_StdPixFmt pixFmt);
2502 hidd.graphics.bitmap
2527 *****************************************************************************************/
2529 VOID
BM__Hidd_BitMap__GetImage(OOP_Class
*cl
, OOP_Object
*o
,
2530 struct pHidd_BitMap_GetImage
*msg
)
2533 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
2534 APTR ppixarray
= &pixarray
;
2536 struct HIDDBitMapData
*data
;
2538 data
= OOP_INST_DATA(cl
, o
);
2540 EnterFunc(bug("BitMap::GetImage(x=%d, y=%d, width=%d, height=%d)\n"
2541 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
2544 bpp
= getpixfmtbpp(cl
, o
, msg
->pixFmt
);
2547 D(bug("!!! INVALID PIXFMT IN BitMap::GetImage(): %d !!!\n", msg
->pixFmt
));
2554 case vHidd_StdPixFmt_Native
:
2555 case vHidd_StdPixFmt_Native32
:
2556 for (y
= 0; y
< msg
->height
; y
++)
2558 for (x
= 0; x
< msg
->width
; x
++)
2560 register HIDDT_Pixel pix
;
2562 pix
= HIDD_BM_GetPixel(o
, x
+ msg
->x
, y
+ msg
->y
);
2571 *((UWORD
*)pixarray
) = pix
;
2577 pixarray
[0] = (pix
>> 16) & 0xFF;
2578 pixarray
[1] = (pix
>> 8) & 0xFF;
2579 pixarray
[2] = pix
& 0xFF;
2581 pixarray
[0] = pix
& 0xFF;
2582 pixarray
[1] = (pix
>> 8) & 0xFF;
2583 pixarray
[2] = (pix
>> 16) & 0xFF;
2589 *(ULONG
*)pixarray
= pix
;
2596 pixarray
+= (msg
->modulo
- msg
->width
* bpp
);
2604 APTR buf
, srcPixels
;
2606 dstpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
2608 buf
= srcPixels
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
2611 for(y
= 0; y
< msg
->height
; y
++)
2620 vHidd_StdPixFmt_Native
);
2622 HIDD_BM_ConvertPixels(o
,
2624 (HIDDT_PixelFormat
*)data
->prot
.pixfmt
,
2627 (HIDDT_PixelFormat
*)dstpf
,
2639 } /* switch(msg->pixFmt) */
2641 ReturnVoid("BitMap::GetImage");
2644 /*****************************************************************************************
2647 moHidd_BitMap_PutImage
2650 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutImage *msg);
2652 VOID HIDD_BM_PutImage (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
2653 WORD x, WORD y, WORD width, WORD height, HIDDT_StdPixFmt pixFmt);
2656 hidd.graphics.bitmap
2682 *****************************************************************************************/
2684 VOID
BM__Hidd_BitMap__PutImage(OOP_Class
*cl
, OOP_Object
*o
,
2685 struct pHidd_BitMap_PutImage
*msg
)
2688 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
2689 APTR ppixarray
= &pixarray
;
2692 struct HIDDBitMapData
*data
;
2693 OOP_Object
*gc
= msg
->gc
;
2695 data
= OOP_INST_DATA(cl
, o
);
2697 EnterFunc(bug("BitMap::PutImage(x=%d, y=%d, width=%d, height=%d)\n"
2698 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
2700 if (msg
->width
<= 0 || msg
->height
<= 0)
2703 bpp
= getpixfmtbpp(cl
, o
, msg
->pixFmt
);
2706 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", msg
->pixFmt
));
2712 case vHidd_StdPixFmt_Native
:
2713 case vHidd_StdPixFmt_Native32
:
2715 /* Preserve old fg pen */
2718 for (y
= 0; y
< msg
->height
; y
++)
2720 for (x
= 0; x
< msg
->width
; x
++)
2722 register HIDDT_Pixel pix
= 0;
2727 pix
= *((UBYTE
*)pixarray
);
2732 pix
= *((UWORD
*)pixarray
);
2738 pix
= ((UBYTE
*)pixarray
)[0] << 16;
2739 pix
|= ((UBYTE
*)pixarray
)[1] << 8;
2740 pix
|= ((UBYTE
*)pixarray
)[2];
2742 pix
= ((UBYTE
*)pixarray
)[2] << 16;
2743 pix
|= ((UBYTE
*)pixarray
)[1] << 8;
2744 pix
|= ((UBYTE
*)pixarray
)[0];
2750 pix
= *((ULONG
*)pixarray
); pixarray
+= 4;
2757 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->x
, y
+ msg
->y
);
2759 pixarray
+= (msg
->modulo
- msg
->width
* bpp
);
2768 APTR buf
, destPixels
;
2770 srcpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
2772 buf
= destPixels
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
2775 for(y
= 0; y
< msg
->height
; y
++)
2777 HIDD_BM_ConvertPixels(o
,
2779 (HIDDT_PixelFormat
*)srcpf
,
2782 (HIDDT_PixelFormat
*)data
->prot
.pixfmt
,
2796 vHidd_StdPixFmt_Native
);
2803 } /* switch(msg->pixFmt) */
2805 ReturnVoid("BitMap::PutImage");
2808 /****************************************************************************************/
2811 __attribute__((always_inline
, const)) do_alpha(int a
, int v
)
2814 return ((tmp
<<8) + tmp
+ 32768)>>16;
2819 #define RGB32_DECOMPOSE(red, green, blue, pix) \
2820 red = ((pix) & 0x00FF0000) >> 16; \
2821 green = ((pix) & 0x0000FF00) >> 8; \
2822 blue = ((pix) & 0x000000FF);
2824 #define ARGB32_ALPHA(pix) ((pix) & 0xFF000000)
2826 #define ARGB32_DECOMPOSE(alpha, red, green, blue, pix) \
2827 alpha = ((pix) & 0xFF000000) >> 24; \
2828 red = ((pix) & 0x00FF0000) >> 16; \
2829 green = ((pix) & 0x0000FF00) >> 8; \
2830 blue = ((pix) & 0x000000FF);
2832 #define ARGB32_COMPOSE(red, green, blue, old) (((old) & 0xFF000000) + ((red) << 16) + ((green) << 8) + (blue))
2836 #define RGB32_DECOMPOSE(red, green, blue, pix) \
2837 red = (pix & 0x0000FF00) >> 8; \
2838 green = (pix & 0x00FF0000) >> 16; \
2839 blue = (pix & 0xFF000000) >> 24
2841 #define ARGB32_ALPHA(pix) ((pix) & 0x000000FF)
2843 #define ARGB32_DECOMPOSE(alpha, red, green, blue, pix) \
2844 alpha = (pix & 0x000000FF); \
2845 red = (pix & 0x0000FF00) >> 8; \
2846 green = (pix & 0x00FF0000) >> 16; \
2847 blue = (pix & 0xFF000000) >> 24
2849 #define ARGB32_COMPOSE(red, green, blue, old) (((blue) << 24) + ((green) << 16) + ((red) << 8) + ((old) & 0x000000FF))
2853 /*****************************************************************************************
2856 moHidd_BitMap_PutAlphaImage
2859 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutAlphaImage *msg);
2861 VOID HIDD_BM_PutAlphaImage (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
2862 WORD x, WORD y, WORD width, WORD height);
2865 hidd.graphics.bitmap
2868 Perform an alpha-blending operation between a bitmap and ARGB pixel array.
2871 obj - A bitmap to operate on
2872 gc - A GC object, internally needed to perform the operation. All its attributes
2874 pixels - A pointer to an array of pixels
2875 modulo - Number of bytes per row in pixel array
2876 x, y - Top-left corner of affected bitmap's region
2877 width - Width of the modified rectangle.
2878 height - Height of the modified rectangle.
2884 Do not rely on 'gc' parameter being valid when implementing this method in own
2885 display driver. This parameter is actually obsolete, and will be set to NULL in
2886 future AROS versions. Current base class implementation ignores it.
2896 *****************************************************************************************/
2906 * 1. Merge buffered and slow versions of PutAlphaImage(), use the same processing algorithm
2907 * (convert array's pixels to bitmap's format, not vice versa)
2908 * 2. Make DoBufferedOperation() public, to be used for cybergraphics.library/ProcessPixelArray()
2909 * implementation, and for some other functions in graphics.library and cybergraphics.library,
2910 * currently using own implementation of pixel buffer.
2911 * 3. Reuse the new code for other buffered operations (currently using old macros).
2914 static void PutAlphaImageBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct paib_data
*data
)
2918 for (y
= 0; y
< height
; y
++)
2920 ULONG
*pixarray
= data
->pixels
;
2922 for (x
= 0; x
< width
; x
++)
2926 ULONG src_red
, src_green
, src_blue
, src_alpha
;
2927 ULONG dst_red
, dst_green
, dst_blue
;
2929 srcpix
= *pixarray
++;
2931 if (ARGB32_ALPHA(srcpix
) == ARGB32_ALPHA(0xFFFFFFFF))
2935 else if (ARGB32_ALPHA(srcpix
) != 0)
2937 ARGB32_DECOMPOSE(src_alpha
, src_red
, src_green
, src_blue
, srcpix
);
2940 RGB32_DECOMPOSE(dst_red
, dst_green
, dst_blue
, destpix
);
2942 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
2943 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
2944 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
2946 xbuf
[x
] = ARGB32_COMPOSE(dst_red
, dst_green
, dst_blue
, destpix
);
2951 data
->pixels
+= data
->modulo
;
2955 VOID
BM__Hidd_BitMap__PutAlphaImage(OOP_Class
*cl
, OOP_Object
*o
,
2956 struct pHidd_BitMap_PutAlphaImage
*msg
)
2959 struct paib_data data
= {msg
->pixels
, msg
->modulo
};
2961 EnterFunc(bug("BitMap::PutAlphaImage(x=%d, y=%d, width=%d, height=%d)\n"
2962 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
2964 if (msg
->width
<= 0 || msg
->height
<= 0)
2967 if (!DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, TRUE
, vHidd_StdPixFmt_ARGB32
,
2968 (VOID_FUNC
)PutAlphaImageBuffered
, &data
))
2970 /* Buffered method failed, use slow pixel-by-pixel method */
2971 for (y
= msg
->y
; y
< msg
->y
+ msg
->height
; y
++)
2973 ULONG
*pixarray
= data
.pixels
;
2975 for (x
= msg
->x
; x
< msg
->x
+ msg
->width
; x
++)
2977 HIDDT_Pixel destpix
;
2980 LONG src_red
, src_green
, src_blue
, src_alpha
;
2981 LONG dst_red
, dst_green
, dst_blue
;
2983 destpix
= HIDD_BM_GetPixel(o
, x
, y
);
2984 HIDD_BM_UnmapPixel(o
, destpix
, &col
);
2986 srcpix
= *pixarray
++;
2987 ARGB32_DECOMPOSE(src_alpha
, src_red
, src_green
, src_blue
, srcpix
);
2989 dst_red
= col
.red
>> 8;
2990 dst_green
= col
.green
>> 8;
2991 dst_blue
= col
.blue
>> 8;
2993 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
2994 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
2995 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
2997 col
.red
= dst_red
<< 8;
2998 col
.green
= dst_green
<< 8;
2999 col
.blue
= dst_blue
<< 8;
3001 HIDD_BM_PutPixel(o
, x
, y
, HIDD_BM_MapColor(o
, &col
));
3003 } /* for(x = msg->x; x < msg->x + msg->width; x++) */
3005 data
.pixels
+= msg
->modulo
;
3007 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
3009 ReturnVoid("BitMap::PutAlphaImage");
3012 /*****************************************************************************************
3015 moHidd_BitMap_PutTemplate
3018 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutTemplate *msg);
3020 VOID HIDD_BM_PutTemplate (OOP_Object *obj, OOP_Object *gc, UBYTE *masktemplate, ULONG modulo,
3021 WORD srcx, WORD x, WORD y, WORD width, WORD height, BOOL inverttemplate);
3024 hidd.graphics.bitmap
3027 Apply a single-bit mask to the given portion of the bitmap. Pixels set to 1 in the mask will be filled
3028 by foreground color. Pixels set to 0 in the mask will be filled by background color or left unchanged,
3029 according to the following GC attributes:
3030 Foreground - a foreground color
3031 Background - a background color
3032 DrawMode - if set to Invert, foreground and background colors will be ignored. Instead,
3033 pixels which are set to 1 in the mask, will be inverted. Other pixels will be
3035 ColorExpansion - if set to Transparent, only pixels which are set to 1 in the mask, will be modified.
3036 Other pixels will not be changed (background color will be ignored).
3039 obj - A bitmap to draw on
3040 gc - A GC object, holding operation parameters
3041 masktemplate - A pointer to a bit mask
3042 modulo - Number of bytes per line in the mask
3043 srcx - Horizontal offset of the mask
3044 x, y - Top-left corner of the bitmap's region to affect
3045 width - Width of the affected region
3046 height - Height of the affected region
3047 inverttemplate - If set to TRUE, bit mask will be interpreted in inverted form
3062 *****************************************************************************************/
3074 static void JAM1TemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ptb_data
*data
)
3078 for (y
= 0; y
< height
; y
++)
3080 ULONG mask
= data
->bitmask
;
3081 UWORD
*array
= data
->bitarray
;
3082 UWORD bitword
= AROS_BE2WORD(*array
);
3084 for (x
= 0; x
< width
; x
++)
3086 if ((bitword
& mask
) == (data
->invert
& mask
))
3094 bitword
= AROS_BE2WORD(*array
);
3099 data
->bitarray
+= data
->modulo
;
3103 static void ComplementTemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ptb_data
*data
)
3107 for (y
= 0; y
< height
; y
++)
3109 ULONG mask
= data
->bitmask
;
3110 UWORD
*array
= data
->bitarray
;
3111 UWORD bitword
= AROS_BE2WORD(*array
);
3113 for (x
= 0; x
< width
; x
++)
3115 if ((bitword
& mask
) == (data
->invert
& mask
))
3123 bitword
= AROS_BE2WORD(*array
);
3128 data
->bitarray
+= data
->modulo
;
3132 static void JAM2TemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ptb_data
*data
)
3136 for (y
= 0; y
< height
; y
++)
3138 ULONG mask
= data
->bitmask
;
3139 UWORD
*array
= data
->bitarray
;
3140 UWORD bitword
= AROS_BE2WORD(*array
);
3142 for (x
= 0; x
< width
; x
++)
3144 if ((bitword
& mask
) == (data
->invert
& mask
))
3154 bitword
= AROS_BE2WORD(*array
);
3159 data
->bitarray
+= data
->modulo
;
3163 VOID
BM__Hidd_BitMap__PutTemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTemplate
*msg
)
3165 OOP_Object
*gc
= msg
->gc
;
3167 void (*op
)(ULONG
*, UWORD
, UWORD
, UWORD
, struct ptb_data
*);
3168 struct ptb_data data
;
3170 EnterFunc(bug("BitMap::PutTemplate(x=%d, y=%d, width=%d, height=%d)\n"
3171 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3173 if (msg
->width
<= 0 || msg
->height
<= 0)
3176 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
3178 op
= JAM1TemplateBuffered
;
3180 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
3182 op
= ComplementTemplateBuffered
;
3186 op
= JAM2TemplateBuffered
;
3190 data
.bitarray
= msg
->masktemplate
+ ((msg
->srcx
/ 16) * 2);
3191 data
.bitmask
= 0x8000 >> (msg
->srcx
& 0xF);
3192 data
.modulo
= msg
->modulo
;
3193 data
.fg
= GC_FG(msg
->gc
);
3194 data
.bg
= GC_BG(msg
->gc
);
3195 data
.invert
= msg
->inverttemplate
? 0 : 0xFFFF;
3197 DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, get
, vHidd_StdPixFmt_Native32
, (VOID_FUNC
)op
, &data
);
3199 /* TODO: write fallback */
3201 ReturnVoid("BitMap::PutTemplate");
3204 /*****************************************************************************************
3207 moHidd_BitMap_PutAlphaTemplate
3210 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutAlphaTemplate *msg);
3212 VOID HIDD_BM_PutAlphaTemplate (OOP_Object *obj, OOP_Object *gc, UBYTE *alpha, ULONG modulo,
3213 WORD x, WORD y, WORD width, WORD height, BOOL invertalpha);
3216 hidd.graphics.bitmap
3219 Perform a drawing with current foreground color, using 8-bit alpha channel mask. The following
3220 GC attributes are considered:
3221 Foreground - a foreground color
3222 Background - a background color
3223 DrawMode - if set to Invert, foreground and background colors will be ignored. Instead,
3224 pixels, for which alpha channel value is greater than 127, will be inverted.
3225 Other pixels will be left unchanged.
3226 ColorExpansion - if set to Opaque, alpha blending will happen between foreground and background
3227 colors, instead of between foreground color and old bitmap contents.
3230 obj - A bitmap to draw on
3231 gc - A GC object specifying drawing parameters
3232 alpha - A pointer to a 8-bit per pixel alpha channel mask
3233 modulo - Number of bytes per line in the mask
3234 x, y - Top-left corner of the affected bitmap's region
3235 width - Width of the affected bitmap's region
3236 height - Height of the affected bitmap's region
3237 invertalpha - If set to TRUE, alpha mask values will be treated in inverted form
3252 *****************************************************************************************/
3258 LONG a_red
, a_green
, a_blue
;
3259 LONG b_red
, b_green
, b_blue
;
3263 static void JAM1AlphaTemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct patb_data
*data
)
3267 for (y
= 0; y
< height
; y
++)
3269 UBYTE
*pixarray
= data
->pixarray
;
3271 for (x
= 0; x
< width
; x
++)
3273 LONG dst_red
, dst_green
, dst_blue
, alpha
;
3275 alpha
= (*pixarray
++) ^ data
->invert
;
3276 RGB32_DECOMPOSE(dst_red
, dst_green
, dst_blue
, xbuf
[x
]);
3278 dst_red
+= do_alpha(alpha
, data
->a_red
- dst_red
);
3279 dst_green
+= do_alpha(alpha
, data
->a_green
- dst_green
);
3280 dst_blue
+= do_alpha(alpha
, data
->a_blue
- dst_blue
);
3282 xbuf
[x
] = ARGB32_COMPOSE(dst_red
, dst_green
, dst_blue
, 0);
3286 data
->pixarray
+= data
->modulo
;
3290 static void ComplementAlphaTemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct patb_data
*data
)
3294 for (y
= 0; y
< height
; y
++)
3296 UBYTE
*pixarray
= data
->pixarray
;
3298 for (x
= 0; x
< width
; x
++)
3300 UBYTE alpha
= (*pixarray
++) ^ data
->invert
;
3307 data
->pixarray
+= data
->modulo
;
3311 static void JAM2AlphaTemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct patb_data
*data
)
3315 for (y
= 0; y
< height
; y
++)
3317 UBYTE
*pixarray
= data
->pixarray
;
3319 for (x
= 0; x
< width
; x
++)
3321 LONG dst_red
, dst_green
, dst_blue
, alpha
;
3323 alpha
= (*pixarray
++) ^ data
->invert
;
3325 dst_red
= data
->b_red
+ ((data
->a_red
- data
->b_red
) * alpha
) / 256;
3326 dst_green
= data
->b_green
+ ((data
->a_green
- data
->b_green
) * alpha
) / 256;
3327 dst_blue
= data
->b_blue
+ ((data
->a_blue
- data
->b_blue
) * alpha
) / 256;
3329 xbuf
[x
] = ARGB32_COMPOSE(dst_red
, dst_green
, dst_blue
, 0);
3333 data
->pixarray
+= data
->modulo
;
3337 VOID
BM__Hidd_BitMap__PutAlphaTemplate(OOP_Class
*cl
, OOP_Object
*o
,
3338 struct pHidd_BitMap_PutAlphaTemplate
*msg
)
3340 OOP_Object
*gc
= msg
->gc
;
3342 void (*op
)(ULONG
*, UWORD
, UWORD
, UWORD
, struct patb_data
*);
3343 struct patb_data data
;
3346 EnterFunc(bug("BitMap::PutAlphaTemplate(x=%d, y=%d, width=%d, height=%d)\n"
3347 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3349 if (msg
->width
<= 0 || msg
->height
<= 0)
3352 HIDD_BM_UnmapPixel(o
, GC_FG(gc
), &color
);
3353 data
.a_red
= color
.red
>> 8;
3354 data
.a_green
= color
.green
>> 8;
3355 data
.a_blue
= color
.blue
>> 8;
3357 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
3359 op
= JAM1AlphaTemplateBuffered
;
3361 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
3363 op
= ComplementAlphaTemplateBuffered
;
3367 op
= JAM2AlphaTemplateBuffered
;
3370 HIDD_BM_UnmapPixel(o
, GC_BG(gc
), &color
);
3371 data
.b_red
= color
.red
>> 8;
3372 data
.b_green
= color
.green
>> 8;
3373 data
.b_blue
= color
.blue
>> 8;
3376 data
.pixarray
= msg
->alpha
;
3377 data
.modulo
= msg
->modulo
;
3378 data
.invert
= msg
->invertalpha
? 255 : 0;
3380 DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, get
, vHidd_StdPixFmt_ARGB32
, (VOID_FUNC
)op
, &data
);
3382 /* TODO: write fallback */
3384 ReturnVoid("BitMap::PutAlphaTemplate");
3387 /*****************************************************************************************
3390 moHidd_BitMap_PutPattern
3393 VOID OOP_DoMethod(OOP_Object *o, struct pHidd_BitMap_PutPattern *msg);
3395 VOID HIDD_BM_PutPattern(OOP_Object *obj, OOP_Object *gc, UBYTE *pattern,
3396 WORD patternsrcx, WORD patternsrcy, WORD patternheight, WORD patterndepth,
3397 HIDDT_PixelLUT *patternlut, BOOL invertpattern, UBYTE *mask,
3398 ULONG maskmodulo, WORD masksrcx, WORD x, WORD y,
3399 WORD width, WORD height);
3402 hidd.graphics.bitmap
3407 obj - A bitmap to draw on
3408 gc - A GC object to use for drawing
3436 *****************************************************************************************/
3445 UWORD patternheight
;
3455 static void JAM1PatternBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
)
3459 for (y
= 0; y
< height
; y
++)
3461 UWORD pmask
= data
->patmask
;
3462 UWORD mmask
= data
->maskmask
;
3463 UWORD
*parray
= data
->patarray
+ ((y
+ starty
+ data
->patternsrcy
- data
->desty
) % data
->patternheight
);
3464 UWORD patword
= AROS_BE2WORD(*parray
);
3465 UWORD
*marray
= data
->maskarray
;
3466 UWORD maskword
= marray
? AROS_BE2WORD(*marray
) : 0xFFFF;
3468 for (x
= 0; x
< width
; x
++)
3470 if (maskword
& mmask
)
3472 if ((patword
& pmask
) == (data
->invert
& pmask
))
3483 maskword
= AROS_BE2WORD(*marray
);
3494 if (data
->maskarray
)
3495 data
->maskarray
+= data
->maskmodulo
;
3500 static void ComplementPatternBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
)
3504 for (y
= 0; y
< height
; y
++)
3506 UWORD pmask
= data
->patmask
;
3507 UWORD mmask
= data
->maskmask
;
3508 UWORD
*parray
= data
->patarray
+ ((y
+ starty
+ data
->patternsrcy
- data
->desty
) % data
->patternheight
);
3509 UWORD patword
= AROS_BE2WORD(*parray
);
3510 UWORD
*marray
= data
->maskarray
;
3511 UWORD maskword
= marray
? AROS_BE2WORD(*marray
) : 0xFFFF;
3513 for (x
= 0; x
< width
; x
++)
3515 if (maskword
& mmask
)
3517 if ((patword
& pmask
) == (data
->invert
& pmask
))
3528 maskword
= AROS_BE2WORD(*marray
);
3539 if (data
->maskarray
)
3540 data
->maskarray
+= data
->maskmodulo
;
3545 static void JAM2PatternBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
)
3549 for (y
= 0; y
< height
; y
++)
3551 UWORD pmask
= data
->patmask
;
3552 UWORD mmask
= data
->maskmask
;
3553 UWORD
*parray
= data
->patarray
+ ((y
+ starty
+ data
->patternsrcy
- data
->desty
) % data
->patternheight
);
3554 UWORD patword
= AROS_BE2WORD(*parray
);
3555 UWORD
*marray
= data
->maskarray
;
3556 UWORD maskword
= marray
? AROS_BE2WORD(*marray
) : 0xFFFF;
3558 for (x
= 0; x
< width
; x
++)
3560 if (maskword
& mmask
)
3562 if ((patword
& pmask
) == (data
->invert
& pmask
))
3575 maskword
= AROS_BE2WORD(*marray
);
3586 if (data
->maskarray
)
3587 data
->maskarray
+= data
->maskmodulo
;
3592 static void ColorPatternBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
)
3596 for (y
= 0; y
< height
; y
++)
3598 UWORD pmask
= data
->patmask
;
3599 UWORD mmask
= data
->maskmask
;
3600 UWORD
*parray
= data
->patarray
+ ((y
+ starty
+ data
->patternsrcy
- data
->desty
) % data
->patternheight
);
3601 UWORD patword
= AROS_BE2WORD(*parray
);
3602 UWORD
*marray
= data
->maskarray
;
3603 UWORD maskword
= marray
? AROS_BE2WORD(*marray
) : 0xFFFF;
3605 for (x
= 0; x
< width
; x
++)
3607 if (maskword
& mmask
)
3610 ULONG pixel
= (patword
& pmask
) ? 1 : 0; /* CHECKME: Shouldn't we handle INVERSVID here too ? */
3612 for (plane
= 1; plane
< data
->patterndepth
; plane
++)
3614 UWORD
*_parray
= parray
+ plane
* data
->patternheight
;
3615 UWORD _patword
= AROS_BE2WORD(*_parray
);
3617 if (_patword
& pmask
)
3618 pixel
|= 1L << plane
;
3621 if (data
->patternlut
)
3622 pixel
= data
->patternlut
[pixel
];
3634 maskword
= AROS_BE2WORD(*marray
);
3645 if (data
->maskarray
)
3646 data
->maskarray
+= data
->maskmodulo
;
3651 VOID
BM__Hidd_BitMap__PutPattern(OOP_Class
*cl
, OOP_Object
*o
,
3652 struct pHidd_BitMap_PutPattern
*msg
)
3654 void (*op
)(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
);
3656 struct ppb_data data
;
3658 DPUTPATTERN(bug("BitMap::PutPattern(x=%d, y=%d, width=%d, height=%d)\n",
3659 msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3661 if (msg
->width
<= 0 || msg
->height
<= 0)
3664 if (msg
->patterndepth
> 1)
3666 DPUTPATTERN(bug("[PutPattern] Color\n"));
3667 op
= ColorPatternBuffered
;
3670 else if (GC_COLEXP(msg
->gc
) == vHidd_GC_ColExp_Transparent
)
3672 DPUTPATTERN(bug("[PutPattern] JAM1\n"));
3673 op
= JAM1PatternBuffered
;
3675 else if (GC_DRMD(msg
->gc
) == vHidd_GC_DrawMode_Invert
)
3677 DPUTPATTERN(bug("[PutPattern] Complement\n"));
3678 op
= ComplementPatternBuffered
;
3682 DPUTPATTERN(bug("[PutPattern] JAM2\n"));
3683 op
= JAM2PatternBuffered
;
3687 data
.patarray
= (UWORD
*)msg
->pattern
;
3688 data
.patmask
= 0x8000 >> (msg
->patternsrcx
& 0xF);
3689 data
.maskarray
= msg
->mask
;
3690 data
.patternlut
= msg
->patternlut
? msg
->patternlut
->pixels
: NULL
;
3691 data
.patternsrcy
= msg
->patternsrcy
;
3692 data
.desty
= msg
->y
;
3693 data
.patternheight
= msg
->patternheight
;
3694 data
.patterndepth
= msg
->patterndepth
;
3695 data
.maskmodulo
= msg
->maskmodulo
;
3696 data
.fg
= GC_FG(msg
->gc
);
3697 data
.bg
= GC_BG(msg
->gc
);
3698 data
.invert
= msg
->invertpattern
? 0 : 0xFFFF;
3702 data
.maskarray
+= (msg
->masksrcx
/ 16) * 2;
3703 data
.maskmask
= 0x8000 >> (msg
->masksrcx
& 0xF);
3707 data
.maskmask
= 0xFFFF;
3709 DPUTPATTERN(bug("[PutPattern] MaskArray 0x%p, MaskMask 0x%04X\n", data
.maskarray
, data
.maskmask
));
3711 DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, get
, vHidd_StdPixFmt_Native32
, (VOID_FUNC
)op
, &data
);
3713 /* TODO: Write fallback */
3715 ReturnVoid("BitMap::PutPattern");
3718 /*****************************************************************************************
3721 moHidd_BitMap_PutImageLUT
3724 VOID OOP_DoMethod(OOP_Object *o, struct pHidd_BitMap_PutImageLUT *msg);
3726 VOID HIDD_BM_PutImageLUT (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
3727 WORD x, WORD y, WORD width, WORD height, HIDDT_PixelLUT *pixlut);
3730 hidd.graphics.bitmap
3756 *****************************************************************************************/
3758 VOID
BM__Hidd_BitMap__PutImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
3759 struct pHidd_BitMap_PutImageLUT
*msg
)
3762 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
3763 HIDDT_PixelLUT
*pixlut
= msg
->pixlut
;
3764 HIDDT_Pixel
*lut
= pixlut
? pixlut
->pixels
: NULL
;
3765 HIDDT_Pixel
*linebuf
;
3766 OOP_Object
*gc
= msg
->gc
;
3768 EnterFunc(bug("BitMap::PutImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
3769 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3771 if (msg
->width
<= 0 || msg
->height
<= 0)
3774 linebuf
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
3776 for(y
= 0; y
< msg
->height
; y
++)
3782 for(x
= 0; x
< msg
->width
; x
++)
3784 linebuf
[x
] = lut
[pixarray
[x
]];
3789 for(x
= 0; x
< msg
->width
; x
++)
3791 linebuf
[x
] = pixarray
[x
];
3794 pixarray
+= msg
->modulo
;
3804 vHidd_StdPixFmt_Native32
);
3806 } /* if (linebuf) */
3811 /* Preserve old fg pen */
3816 for(x
= 0; x
< msg
->width
; x
++)
3818 GC_FG(gc
) = lut
[pixarray
[x
]];
3819 HIDD_BM_DrawPixel(o
, gc
, msg
->x
+ x
, msg
->y
+ y
);
3824 for(x
= 0; x
< msg
->width
; x
++)
3826 GC_FG(gc
) = pixarray
[x
];
3827 HIDD_BM_DrawPixel(o
, gc
, msg
->x
+ x
, msg
->y
+ y
);
3832 pixarray
+= msg
->modulo
;
3834 } /* if (linebuf) else ... */
3836 } /* for(y = 0; y < msg->height; y++) */
3840 ReturnVoid("BitMap::PutImageLUT");
3842 /*****************************************************************************************
3845 moHidd_BitMap_PutTranspImageLUT
3848 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutTranspImageLUT *msg);
3850 VOID HIDD_BM_PutTranspImageLUT (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels,
3851 ULONG modulo, WORD x, WORD y, WORD width, WORD height,
3852 HIDDT_PixelLUT *pixlut, UBYTE transparent);
3855 hidd.graphics.bitmap
3858 Copy an array of 8-bit LUT pixels to the bitmap at the specified position making
3859 one of colors transparent.
3861 Pixels are converted to bitmap's native format using either user-supplied LUT (if
3862 given) or bitmap's own colormap.
3864 Draw mode of the supplied GC is ignored, the operation is always bulk copy.
3867 obj - A bitmap to draw image on
3868 gc - A GC used for drawing
3869 pixels - A pointer to source pixel array
3870 modulo - Total number of bytes per line in the source array
3871 x, y - Top-left corner of the destination rectangle
3872 width - Width of the image to draw
3873 height - Height of the image to draw
3874 pixlut - An optional pointer to a LUT to use. NULL means using bitmap's
3875 own colormap (if available)
3876 transparent - Value of pixels in the source array which will be made
3892 *****************************************************************************************/
3894 #undef csd /* Bad hack, but there's no other way */
3901 struct class_static_data
*csd
;
3906 static void PutTranspImageLUTBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ptilb_data
*data
)
3908 struct class_static_data
*csd
= data
->csd
;
3911 for (y
= 0; y
< height
; y
++)
3913 UBYTE
*pixarray
= data
->pixarray
;
3917 for (x
= 0; x
< width
; x
++)
3919 UBYTE pix
= *pixarray
++;
3921 if (pix
!= data
->transparent
)
3922 xbuf
[x
] = data
->lut
[pix
];
3928 for (x
= 0; x
< width
; x
++)
3930 UBYTE pix
= *pixarray
++;
3932 if (pix
!= data
->transparent
)
3935 pix
= HIDD_CM_GetPixel(data
->colmap
, pix
);
3944 data
->pixarray
+= data
->modulo
;
3948 VOID
BM__Hidd_BitMap__PutTranspImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
3949 struct pHidd_BitMap_PutTranspImageLUT
*msg
)
3951 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
3952 struct ptilb_data userdata
=
3962 EnterFunc(bug("BitMap::PutTranspImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
3963 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3965 if (msg
->width
<= 0 || msg
->height
<= 0)
3969 userdata
.lut
= msg
->pixlut
->pixels
;
3971 DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, TRUE
, vHidd_StdPixFmt_Native32
,
3972 (VOID_FUNC
)PutTranspImageLUTBuffered
, &userdata
);
3974 /* TODO: Write fallback */
3976 ReturnVoid("BitMap::PutTranspImageLUT");
3981 /*****************************************************************************************
3984 moHidd_BitMap_GetImageLUT
3987 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_GetImageLUT *msg);
3989 VOID HIDD_BM_GetImageLUT (OOP_Object *obj, UBYTE *pixels, ULONG modulo, WORD x, WORD y,
3990 WORD width, WORD height, HIDDT_PixelLUT *pixlut);
3993 hidd.graphics.bitmap
4018 *****************************************************************************************/
4020 VOID
BM__Hidd_BitMap__GetImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
4021 struct pHidd_BitMap_GetImageLUT
*msg
)
4024 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
4025 HIDDT_PixelLUT
*pixlut
= msg
->pixlut
;
4026 HIDDT_Pixel
*lut
= pixlut
? pixlut
->pixels
: NULL
;
4027 HIDDT_Pixel
*linebuf
;
4029 EnterFunc(bug("BitMap::GetImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
4030 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
4032 linebuf
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
4034 for(y
= 0; y
< msg
->height
; y
++)
4045 vHidd_StdPixFmt_Native32
);
4048 /* FIXME: This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway */
4049 for(x
= 0; x
< msg
->width
; x
++)
4051 pixarray
[x
] = (UBYTE
)linebuf
[x
];
4056 for(x
= 0; x
< msg
->width
; x
++)
4058 pixarray
[x
] = (UBYTE
)linebuf
[x
];
4061 pixarray
+= msg
->modulo
;
4063 } /* if (linebuf) */
4068 /* FIXME: This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway */
4069 for(x
= 0; x
< msg
->width
; x
++)
4071 pixarray
[x
] = (UBYTE
)HIDD_BM_GetPixel(o
, msg
->x
+ x
, msg
->y
+ y
);
4076 for(x
= 0; x
< msg
->width
; x
++)
4078 pixarray
[x
] = (UBYTE
)HIDD_BM_GetPixel(o
, msg
->x
+ x
, msg
->y
+ y
);
4082 pixarray
+= msg
->modulo
;
4084 } /* if (linebuf) else ... */
4086 } /* for(y = 0; y < msg->height; y++) */
4088 if (linebuf
) FreeVec(linebuf
);
4090 ReturnVoid("BitMap::GetImageLUT");
4093 /*****************************************************************************************
4096 moHidd_BitMap_BlitColorExpansion
4099 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BlitColorExpansion *msg);
4101 VOID HIDD_BM_BlitColorExpansion (OOP_Object *obj, OOP_Object *gc, OOP_Object *srcBitMap,
4102 WORD srcX, WORD srcY, WORD destX, WORD destY,
4103 UWORD width, UWORD height);
4106 hidd.graphics.bitmap
4109 Perform a color expansion of the mask in srcBitMap according to foreground and background
4110 colors and expansion mode specified by the supplied GC. Pixels which are set to zero in
4111 the mask bitmap will be either painted by background (in opaque mode) or left without
4112 change (in transparent mode). Pixels which are set to nonzero in the mask will be painted
4113 by foreground color.
4115 The result of expansion is blitted onto the destination bitmap accorging to GC's draw mode.
4118 obj - A bitmap to draw on
4119 gc - A GC object to use for drawing
4120 srcBitMap - A bitmap object containing mask image.
4121 srcX, srcY - A top-left coordinate of the used rectangle in the source bitmap
4122 destX, destY - A top-left coordinate of the destination rectangle to draw in
4123 width, height - A size of the rectangle to blit
4129 This method was previously used by graphics.library/Text() to draw fonts with no
4130 styles specified. Currently graphics.library always uses BltTemplate() and this
4131 method is considered obsolete.
4141 *****************************************************************************************/
4143 VOID
BM__Hidd_BitMap__BlitColorExpansion(OOP_Class
*cl
, OOP_Object
*o
,
4144 struct pHidd_BitMap_BlitColorExpansion
*msg
)
4151 OOP_Object
*gc
= msg
->gc
;
4153 EnterFunc(bug("BitMap::BlitColorExpansion(srcBM=%p, srcX=%d, srcY=%d, destX=%d, destY=%d, width=%d, height=%d)\n",
4154 msg
->srcBitMap
, msg
->srcX
, msg
->srcY
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
));
4156 cemd
= GC_COLEXP(gc
);
4160 /* bug("------------- Blit_ColExp: (%d, %d, %d, %d, %d, %d) cemd=%d, fg=%p, bg=%p -------------\n"
4161 , msg->srcX, msg->srcY, msg->destX, msg->destY, msg->width, msg->height
4164 for (y
= 0; y
< msg
->height
; y
++)
4166 for (x
= 0; x
< msg
->width
; x
++)
4170 /* Pixel value is either 0 or 1 for BM of depth 1 */
4171 is_set
= HIDD_BM_GetPixel(msg
->srcBitMap
, x
+ msg
->srcX
, y
+ msg
->srcY
);
4181 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->destX
, y
+ msg
->destY
);
4185 if (cemd
& vHidd_GC_ColExp_Opaque
)
4187 /* Write bixel with BG pen */
4189 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->destX
, y
+ msg
->destY
);
4190 /* Reset to FG pen */
4196 } /* for (each x) */
4200 } /* for ( each y ) */
4203 ReturnVoid("BitMap::BlitColorExpansion");
4206 /*****************************************************************************************
4209 moHidd_BitMap_BytesPerLine
4212 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BytesPerLine *msg);
4214 ULONG HIDD_BM_BytesPerLine(OOP_Object *obj, HIDDT_StdPixFmt pixFmt, UWORD width);
4217 hidd.graphics.bitmap
4220 This method is currently not used and reserved.
4239 *****************************************************************************************/
4241 ULONG
BM__Hidd_BitMap__BytesPerLine(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_BytesPerLine
*msg
)
4246 switch (msg
->pixFmt
)
4248 case vHidd_StdPixFmt_Native32
:
4249 bpl
= sizeof (HIDDT_Pixel
) * msg
->width
;
4252 case vHidd_StdPixFmt_Native
:
4254 struct HIDDBitMapData
*data
;
4256 data
= OOP_INST_DATA(cl
, o
);
4258 bpl
= ((HIDDT_PixelFormat
*)data
->prot
.pixfmt
)->bytes_per_pixel
* msg
->width
;
4265 struct HIDDBitMapData
*data
;
4267 data
= OOP_INST_DATA(cl
, o
);
4269 pf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
4273 D(bug("!!! COULD NOT GET STD PIXFMT IN BitMap::BytesPerLine() !!!\n"));
4277 bpl
= ((HIDDT_PixelFormat
*)pf
)->bytes_per_pixel
* msg
->width
;
4289 /****************************************************************************************/
4292 This makes it easier to create a subclass of the graphics hidd.
4293 It is only allowed to use this method in the p_RootNew method of a
4297 /****************************************************************************************/
4299 IPTR
BM__Root__Set(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_Set
*msg
)
4301 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
4302 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
4303 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
4305 if (data
->framebuffer
)
4308 * If this is a framebuffer, we can process ModeID change.
4309 * We do it before parsing the rest of tags, because here we retrieve
4310 * defaults for new bitmap parameters (size and pixelformat).
4311 * They can be overriden by other tags. For example we can imagine
4312 * a hardware scrollable framebuffer whose width and height are larger
4313 * than visible part.
4315 HIDDT_ModeID modeid
= GetTagData(aHidd_BitMap_ModeID
, vHidd_ModeID_Invalid
, msg
->attrList
);
4316 OOP_Object
*sync
, *pixfmt
;
4318 if (HIDD_Gfx_GetMode(data
->gfxhidd
, modeid
, &sync
, &pixfmt
))
4320 data
->modeid
= modeid
;
4322 * Set defaults based on the ModeID.
4323 * They can be overriden lated, in SetBitMapTags.
4325 data
->width
= OOP_GET(sync
, aHidd_Sync_HDisp
);
4326 data
->height
= OOP_GET(sync
, aHidd_Sync_VDisp
);
4327 data
->bytesPerRow
= GetBytesPerRow(data
, CSD(cl
));
4328 data
->prot
.pixfmt
= pixfmt
;
4332 /* Bad ModeID given, request rejected */
4336 /* Process the rest of tags. */
4337 BM__Hidd_BitMap__SetBitMapTags(cl
, obj
, msg
->attrList
);
4339 /* There's no superclass above us */
4343 /*****************************************************************************************
4346 moHidd_BitMap_SetColorMap
4349 OOP_Object * OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetColorMap *msg);
4351 OOP_Object * HIDD_BM_SetColorMap(OOP_Object *obj, OOP_Object *colorMap);
4354 hidd.graphics.bitmap
4374 *****************************************************************************************/
4376 OOP_Object
*BM__Hidd_BitMap__SetColorMap(OOP_Class
*cl
, OOP_Object
*o
,
4377 struct pHidd_BitMap_SetColorMap
*msg
)
4379 struct HIDDBitMapData
*data
;
4382 data
= OOP_INST_DATA(cl
, o
);
4385 data
->colmap
= msg
->colorMap
;
4390 /*****************************************************************************************
4393 moHidd_BitMap_MapColor
4396 HIDDT_Pixel OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_MapColor *msg);
4398 HIDDT_Pixel HIDD_BM_MapColor(OOP_Object *obj, HIDDT_Color *color);
4401 hidd.graphics.bitmap
4421 *****************************************************************************************/
4423 /* We only care about magnitudes here, so we don't
4424 * have to perform the square root operation to get
4425 * the real distance.
4427 static ULONG
colorDistance(HIDDT_Color
*a
, HIDDT_Color
*b
)
4429 #define SQR(x) ((x) * (x))
4430 return SQR((int)a
->red
- (int)b
->red
) +
4431 SQR((int)a
->blue
- (int)b
->blue
) +
4432 SQR((int)a
->green
- (int)b
->green
) +
4433 SQR((int)a
->alpha
- (int)b
->alpha
);
4437 HIDDT_Pixel
BM__Hidd_BitMap__MapColor(OOP_Class
*cl
, OOP_Object
*o
,
4438 struct pHidd_BitMap_MapColor
*msg
)
4440 HIDDT_PixelFormat
*pf
= BM_PIXFMT(o
);
4442 HIDDT_Pixel red
= msg
->color
->red
;
4443 HIDDT_Pixel green
= msg
->color
->green
;
4444 HIDDT_Pixel blue
= msg
->color
->blue
;
4445 HIDDT_Pixel alpha
= msg
->color
->alpha
;
4447 /* This code assumes that sizeof(HIDDT_Pixel) is a multiple of sizeof(col->#?),
4448 which should be true for most (all?) systems. I have never heard
4449 of any system with for example 3 byte types.
4452 if (IS_TRUECOLOR(pf
))
4454 if (HIDD_PF_SWAPPIXELBYTES(pf
))
4456 /* FIXME: BM__Hidd_BitMap__MapColor assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats */
4458 HIDDT_Pixel pixel
= MAP_RGBA(red
, green
, blue
, alpha
, pf
);
4460 msg
->color
->pixval
= SWAPBYTES_WORD(pixel
);
4464 msg
->color
->pixval
= MAP_RGBA(red
, green
, blue
, alpha
, pf
);
4469 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
4471 HIDDT_ColorLUT
*cmap
;
4473 ULONG best_ndx
= ~0, best_dist
= ~0;
4475 cmap
= (HIDDT_ColorLUT
*)data
->colmap
;
4476 ctab
= cmap
->colors
;
4477 /* Search for the best match in the color table */
4478 for (i
= 0; i
< cmap
->entries
; i
++) {
4481 dist
= colorDistance(&ctab
[i
], msg
->color
);
4482 if (dist
< best_dist
) {
4488 if (best_dist
!= ~0)
4489 msg
->color
->pixval
= ctab
[best_ndx
].pixval
;
4492 return msg
->color
->pixval
;
4495 /*****************************************************************************************
4498 moHidd_BitMap_UnmapPixel
4501 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_UnmapPixel *msg);
4503 VOID HIDD_BM_UnmapPixel(OOP_Object *obj, HIDDT_Pixel pixel, HIDDT_Color *color);
4506 hidd.graphics.bitmap
4527 *****************************************************************************************/
4529 VOID
BM__Hidd_BitMap__UnmapPixel(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_UnmapPixel
*msg
)
4532 HIDDT_PixelFormat
*pf
= BM_PIXFMT(o
);
4534 if (IS_TRUECOLOR(pf
))
4536 HIDDT_Pixel pixel
= msg
->pixel
;
4538 if (HIDD_PF_SWAPPIXELBYTES(pf
))
4540 /* FIXME: bitmap_unmappixel assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats */
4541 pixel
= SWAPBYTES_WORD(pixel
);
4544 msg
->color
->red
= RED_COMP (pixel
, pf
);
4545 msg
->color
->green
= GREEN_COMP (pixel
, pf
);
4546 msg
->color
->blue
= BLUE_COMP (pixel
, pf
);
4547 msg
->color
->alpha
= ALPHA_COMP (pixel
, pf
);
4551 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
4552 HIDDT_ColorLUT
*clut
;
4554 clut
= (HIDDT_ColorLUT
*)data
->colmap
;
4558 /* FIXME: Use CLUT shift and CLUT mask here */
4559 if (msg
->pixel
< 0 || msg
->pixel
>= clut
->entries
)
4562 *msg
->color
= clut
->colors
[msg
->pixel
];
4566 /* Unnecessary, but... */
4567 msg
->color
->pixval
= msg
->pixel
;
4570 /*****************************************************************************************
4573 moHidd_BitMap_ObtainDirectAccess
4576 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_ObtainDirectAccess *msg);
4578 BOOL HIDD_BM_ObtainDirectAccess(OOP_Object *obj, UBYTE **addressReturn,
4579 ULONG *widthReturn, ULONG *heightReturn,
4580 ULONG *bankSizeReturn, ULONG *memSizeReturn);
4583 hidd.graphics.bitmap
4608 *****************************************************************************************/
4610 BOOL
BM__Hidd_BitMap__ObtainDirectAccess(OOP_Class
*cl
, OOP_Object
*o
,
4611 struct pHidd_BitMap_ObtainDirectAccess
*msg
)
4613 /* Default implementation of direct access funcs. Just return FALSE */
4617 /*****************************************************************************************
4620 moHidd_BitMap_ReleaseDirectAccess
4623 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_ReleaseDirectAccess *msg);
4625 VOID HIDD_BM_ReleaseDirectAccess(OOP_Object *obj);
4628 hidd.graphics.bitmap
4647 *****************************************************************************************/
4649 VOID
BM__Hidd_BitMap__ReleaseDirectAccess(OOP_Class
*cl
, OOP_Object
*o
,
4650 struct pHidd_BitMap_ReleaseDirectAccess
*msg
)
4652 D(bug("!!! BitMap BaseClasse ReleaseDirectAccess() called !!!\n"));
4653 D(bug("!!! This should never happen and is probably due to a buggy implementation in the subclass !!!\n"));
4658 /*****************************************************************************************
4661 moHidd_BitMap_BitMapScale
4664 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BitMapScale * msg);
4666 VOID HIDD_BM_BitMapScale(OOP_Object *obj, OOP_Object *src, OOP_Object *dest,
4667 struct BitScaleArgs * bsa, OOP_Object *gc);
4670 hidd.graphics.bitmap
4693 *****************************************************************************************/
4695 VOID
BM__Hidd_BitMap__BitMapScale(OOP_Class
* cl
, OOP_Object
*o
,
4696 struct pHidd_BitMap_BitMapScale
* msg
)
4698 struct BitScaleArgs
*bsa
= msg
->bsa
;
4699 ULONG
*srcbuf
, *dstbuf
;
4703 UWORD ys
= bsa
->bsa_SrcY
;
4704 UWORD xs
= bsa
->bsa_SrcX
;
4705 UWORD dyd
= bsa
->bsa_DestHeight
;
4706 UWORD dxd
= bsa
->bsa_DestWidth
;
4709 UWORD dxs
= bsa
->bsa_SrcWidth
;
4710 UWORD dys
= bsa
->bsa_SrcHeight
;
4711 LONG accuyd
= - (dys
>> 1);
4712 LONG accuxd
= - (dxs
>> 1);
4715 if ((srcbuf
= AllocVec(bsa
->bsa_SrcWidth
* sizeof(ULONG
), 0)) == NULL
)
4718 if ((dstbuf
= AllocVec(bsa
->bsa_DestWidth
* sizeof(ULONG
), 0)) == NULL
) {
4723 if ((linepattern
= (UWORD
*) AllocVec(bsa
->bsa_DestWidth
* sizeof(UWORD
), 0)) == NULL
) {
4730 while (count
< bsa
->bsa_DestWidth
) {
4732 while (accuxd
> accuxs
) {
4737 linepattern
[count
] = xs
;
4742 count
= bsa
->bsa_DestY
;
4743 while (count
< bsa
->bsa_DestHeight
+ bsa
->bsa_DestY
) {
4745 while (accuyd
> accuys
) {
4750 if (srcline
!= ys
) {
4751 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
);
4754 for (x
= 0; x
< bsa
->bsa_DestWidth
; x
++)
4755 dstbuf
[x
] = srcbuf
[linepattern
[x
]];
4758 HIDD_BM_PutImage(msg
->dst
, msg
->gc
, (UBYTE
*) dstbuf
, bsa
->bsa_DestWidth
* sizeof(ULONG
), bsa
->bsa_DestX
, count
, bsa
->bsa_DestWidth
, 1, vHidd_StdPixFmt_Native32
);
4763 FreeVec(linepattern
);
4769 /*****************************************************************************************
4772 moHidd_BitMap_SetRGBConversionFunction
4775 HIDDT_RGBConversionFunction
4776 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetRGBConversionFunction *msg);
4778 HIDDT_RGBConversionFunction
4779 HIDD_BM_SetRGBConversionFunction(OOP_Object *obj, HIDDT_StdPixFmt srcPixFmt,
4780 HIDDT_StdPixFmt dstPixFmt,
4781 HIDDT_RGBConversionFunction function);
4784 hidd.graphics.bitmap
4802 *****************************************************************************************/
4804 HIDDT_RGBConversionFunction
BM__Hidd_BitMap__SetRGBConversionFunction(OOP_Class
* cl
, OOP_Object
*o
,
4805 struct pHidd_BitMap_SetRGBConversionFunction
* msg
)
4807 HIDDT_RGBConversionFunction old
;
4809 if ((msg
->srcPixFmt
< FIRST_RGB_STDPIXFMT
) ||
4810 (msg
->dstPixFmt
< FIRST_RGB_STDPIXFMT
) ||
4811 (msg
->srcPixFmt
> LAST_RGB_STDPIXFMT
) ||
4812 (msg
->dstPixFmt
> LAST_RGB_STDPIXFMT
))
4814 return (HIDDT_RGBConversionFunction
)-1;
4818 ObtainSemaphore(&CSD(cl
)->rgbconvertfuncs_sem
);
4819 old
= CSD(cl
)->rgbconvertfuncs
[msg
->srcPixFmt
- FIRST_RGB_STDPIXFMT
][msg
->dstPixFmt
- FIRST_RGB_STDPIXFMT
];
4820 CSD(cl
)->rgbconvertfuncs
[msg
->srcPixFmt
- FIRST_RGB_STDPIXFMT
][msg
->dstPixFmt
- FIRST_RGB_STDPIXFMT
] = msg
->function
;
4821 ReleaseSemaphore(&CSD(cl
)->rgbconvertfuncs_sem
);
4827 /*****************************************************************************************
4830 moHidd_BitMap_UpdateRect
4833 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_UpdateRect *msg);
4835 VOID HIDD_BM_UpdateRect(OOP_Object *obj, WORD x, WORD y, WORD width, WORD height);
4838 hidd.graphics.bitmap
4841 Update displayed image of the given rectangle.
4843 Some drivers (like VGA and VESA) may work not with VRAM directly, but with a mirrored
4844 copy of it. Usually it is done in case if VRAM reading is slow. This method is called
4845 by the system after it completes any drawing operation, in order to make sure that
4846 changes made are visible on the actual screen. If your driver uses mirroring, this method
4847 should copy the given rectangle (at least) from the mirror buffer to the actual VRAM.
4849 This method is also called after changing currently visible bitmap (after moHidd_Gfx_Show
4850 method call) in order to allow the mirroring driver to refresh the screen after current bitmap
4851 changed. Note that moHidd_Gfx_ShowViewPorts is very different and moHidd_BitMap_UpdateRect
4852 will not be called if it succeeded!
4855 obj - an object whose image to refresh
4856 x, y - A top-left edge of the rectangle to refresh
4857 width - Width of the rectangle to refresh
4858 height - Height of the rectangle to refresh
4864 This method is called also on offscreen bitmaps. You should track visible state of your bitmap
4865 and ignore these calls if it's not currently visible on the screen.
4875 *****************************************************************************************/
4877 VOID
BM__Hidd_BitMap__UpdateRect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_UpdateRect
*msg
) {
4878 /* baseclass version does nothing */
4882 /****************************************************************************************/
4885 * Private methods follow.
4886 * They are implemented as non-virtual, for speed up.
4889 /* This is a private form of Set method. Doesn't need a standard message. */
4890 void BM__Hidd_BitMap__SetBitMapTags(OOP_Class
*cl
, OOP_Object
*o
, struct TagItem
*bitMapTags
)
4892 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
4893 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
4894 struct TagItem
*tag
;
4896 while ((tag
= NextTagItem(&bitMapTags
)))
4900 if (IS_BITMAP_ATTR(tag
->ti_Tag
, idx
))
4904 case aoHidd_BitMap_Width
:
4905 data
->width
= tag
->ti_Data
;
4908 case aoHidd_BitMap_Height
:
4909 data
->height
= tag
->ti_Data
;
4912 case aoHidd_BitMap_BytesPerRow
:
4913 data
->bytesPerRow
= tag
->ti_Data
;
4921 * Updates bitmap's pixelformat.
4922 * Used from within planarbm subclass, and would be extremely dangerous to expose
4923 * as setable aHidd_BitMap_PixFmt, so implemented as a separate method.
4925 void BM__Hidd_BitMap__SetPixFmt(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*pf
)
4927 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
4929 /* Already a pixfmt registered? */
4930 if (data
->pf_registered
)
4931 GFX__Hidd_Gfx__ReleasePixFmt(CSD(cl
)->gfxhiddclass
, data
->prot
.pixfmt
);
4933 /* Remember the new pixelformat */
4934 data
->prot
.pixfmt
= pf
;
4937 * This pixelformat was obtained using GFX__Hidd_Gfx__RegisterPixFmt().
4938 * It increases number of pixfmt users, so we'll need to release it when
4939 * not used any more.
4941 data
->pf_registered
= TRUE
;