2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
5 Desc: Graphics bitmap class implementation.
9 /****************************************************************************************/
13 #define DPUTPATTERN(x)
16 #include <aros/debug.h>
17 #include <proto/exec.h>
18 #include <proto/utility.h>
19 #include <proto/oop.h>
20 #include <exec/memory.h>
21 #include <utility/tagitem.h>
23 #include <oop/static_mid.h>
24 #include <graphics/text.h>
25 #include <graphics/scale.h>
26 #include <hidd/graphics.h>
32 #include "graphics_intern.h"
34 /****************************************************************************************/
36 #define POINT_OUTSIDE_CLIP(gc, x, y) \
37 ( (x) < GC_CLIPX1(gc) \
38 || (x) > GC_CLIPX2(gc) \
39 || (y) < GC_CLIPY1(gc) \
40 || (y) > GC_CLIPY2(gc) )
42 /*****************************************************************************************
51 Every display driver should implement at least one bitmap class for displayable
54 Normally this class doesn't need to have public ID. In order to use it the driver
55 should pass class pointer as aoHidd_BitMap_ClassPtr value to the graphics base class
56 in its moHidd_Gfx_CreateObject implementation.
58 BitMap base class is in C++ terminology a pure virtual
59 baseclass. It will not allocate any bitmap data at all;
60 that is up to the subclass to do.
62 The main task of the BitMap baseclass is to store some information about the bitmap
63 like its size and pixelformat. A pixelformat is an object of private class which
64 stores the actual information about the format.
66 There are two ways that we can find out the pixfmt in our moHidd_Gfx_CreateObject
70 The tags will contain a modeid.
71 One can use this modeid to get a pointer to an
72 already registered pixfmt.
74 Non-displayable bitmap -
75 The aoHidd_BitMap_StdPixFmt or aoHidd_BitMap_Friend attribute will always be
78 *****************************************************************************************/
80 #define PIXBUFBYTES 16384
82 static BOOL
DoBufferedOperation(OOP_Class
*cl
, OOP_Object
*o
, UWORD startx
, UWORD starty
, UWORD width
, UWORD height
,
83 BOOL getimage
, HIDDT_StdPixFmt stdpf
, VOID_FUNC operation
, void *userdata
)
85 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
86 ULONG bytesperline
= width
* sizeof(ULONG
);
87 UWORD buflines
= PIXBUFBYTES
/ 4; /* Remove slow division */
89 UWORD endy
= starty
+ height
;
95 else if (buflines
> height
)
98 bufsize
= buflines
* bytesperline
;
99 buf
= AllocMem(bufsize
, MEMF_PUBLIC
);
100 if (!buf
&& (buflines
> 1))
102 /* Try to allocate single-line buffer */
104 bufsize
= bytesperline
;
105 buf
= AllocMem(bufsize
, MEMF_PUBLIC
);
110 for (y
= starty
; y
< endy
; y
+= buflines
)
112 if (y
+ buflines
> endy
)
114 /* This prevents overflow on last pass, buffer may be used only partially */
120 /* For some operations this can be optimized away */
121 HIDD_BM_GetImage(o
, buf
, bytesperline
, startx
, y
, width
, buflines
, stdpf
);
124 operation(buf
, y
, width
, buflines
, userdata
);
126 HIDD_BM_PutImage(o
, data
->gc
, buf
, bytesperline
, startx
, y
, width
, buflines
, stdpf
);
129 FreeMem(buf
, bufsize
);
133 /*****************************************************************************************
145 Specifies bitmap width in pixels.
147 Setting this attribute does not cause actual bitmap resize, just updates the information
148 about it. Use this only from within subclasses only if you know what you do. For example
149 SDL hosted driver sets it when framebufer changes the resolution.
162 *****************************************************************************************/
164 /*****************************************************************************************
176 Specifies bitmap height in pixels.
178 Setting this attribute does not cause actual bitmap resize, just updates the information
179 about it. Use this only from within subclasses only if you know what you do. For example
180 SDL hosted driver sets it when framebufer changes the resolution.
193 *****************************************************************************************/
195 /*****************************************************************************************
198 aoHidd_BitMap_Displayable
207 The bitmap is displayable. A displayable bitmap is always managed by a display
208 driver and must have valid display mode ID specification.
210 If this attribute is not supplied during bitmap creation, its value defaults
224 *****************************************************************************************/
226 /*****************************************************************************************
229 aoHidd_BitMap_Visible
238 Check if the bitmap is currently visible on screen
245 Not all display drivers implement this attribute. No AROS components currently rely
251 Some drivers may choose to have this attribute internally setable. Do not rely on it
252 in any way and do not attempt to set it manually from within applications, this will
253 not do any nice things.
255 *****************************************************************************************/
257 /*****************************************************************************************
260 aoHidd_BitMap_IsLinearMem
269 Check if the bitmap provides linear memory access. This means that bitmap's
270 pixelbuffer is directly addressable by the CPU.
272 Bitmaps with no linear memory may implement moHidd_BitMap_ObtainDirectAccess,
273 but this means that this method will rely on mirrored buffer. In such a case
274 the user must call moHidd_BitMap_UpdateRect after modifying bitmap's contents.
277 Used by cybergraphics.library/GetCyberMapAttr() for providing CYBRMATTR_ISLINEARMEM
283 Currently no display drivers implement this attribute despite many native mode
284 drivers actually provide linear memory.
287 moHidd_BitMap_ObtainDirectAccess, moHidd_BitMap_ReleaseDirectAccess,
288 moHidd_BitMap_UpdateRect
292 *****************************************************************************************/
294 /*****************************************************************************************
297 aoHidd_BitMap_BytesPerRow
306 Specify or query number of bytes per row in the bitmap storage buffer.
308 Setting this attribute doesn't actually cause changing buffer layout, just updates
309 the information about it. Use this only from within subclasses and only if you
310 exactly know why you do this.
312 Specifying this attribute during object creation overrides the value calculated
313 based on aoHidd_BitMap_Width and aoHidd_BitMap_Align values. Useful for wrapping
314 own buffers into bitmap objects, for example, in conjunction with
315 aoHidd_ChunkyBM_Buffer.
318 The returned value includes possible padding needed for alignment.
329 *****************************************************************************************/
331 /*****************************************************************************************
334 aoHidd_BitMap_ColorMap
343 Return associated colormap (palette) object.
345 By default only displayable bitmaps have colormaps. However a colormap can be attached
346 to any bitmap using moHidd_BitMap_SetColors or moHidd_BitMap_SetColorMap.
348 Note that manual attaching of a colormap to a nondisplayable bitmap may cause undesired
349 side-effects on graphics.library behavior. It's better not to do this at all. The system
350 knows what it does better than you.
359 moHidd_BitMap_SetColorMap, moHidd_BitMap_SetColors.
363 *****************************************************************************************/
365 /*****************************************************************************************
377 Specify a friend bitmap. The bitmap will be allocated so that it
378 is optimized for blitting to this bitmap.
380 Display drivers may query this attribute and then query friend bitmap
381 for anything they want (like pixelformat, mode ID, etc).
383 Note that explicit specification of mode ID and/or standard pixelformat
384 should override defaults provided by friend bitmap (i.e. actually breaking
397 *****************************************************************************************/
399 /*****************************************************************************************
402 aoHidd_BitMap_GfxHidd
411 Specify display driver object this bitmap was created with.
413 Normally the user doesn't have to supply this attribute. Instead you should use
414 driver's moHidd_Gfx_CreateObject method in order to create bitmaps. In this case
415 aoHidd_BitMap_GfxHidd attribute will be provided by graphics driver base class
416 with the correct value.
418 It is illegal to manually create bitmap objects with no driver associated.
419 graphics.library maintains at least a memory driver for nondisplayable
420 bitmaps in system RAM without any acceleration.
429 CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
433 *****************************************************************************************/
435 /*****************************************************************************************
438 aoHidd_BitMap_StdPixFmt
441 [I..], HIDDT_StdPixFmt
447 Specify standard pixelformat code (one of vHidd_StdPixFmt_... values) for the
450 Values less than num_Hidd_PseudoStdPixFmt are illegal for this attribute.
452 The bitmap class itself ignores this attribute. It is processed by
453 CLID_Hidd_Gfx/moHidd_Gfx_CreateObject method in order to look up a corresponding
454 pixelformat object in the system's database.
457 Bitmaps with this attribute set should be created as RAM bitmaps with direct CPU
458 access. It is not recommended to replace them with, for example, virtual surfaces on
459 hosted AROS. Such bitmaps are expected to be directly addressable and breaking
460 this may cause undesired side effects.
467 aoHidd_BitMap_PixFmt, CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
470 Currently all display drivers omit specifying own bitmap class for bitmaps with this
471 attribute set, letting base class (actually memory driver) to select an appropriate
472 class for it. This way it ends up in a bitmap of CLID_Hidd_ChunkyBM or CLID_Hidd_PlanarBM
473 class. It is recommended to follow this rule. It's not prohibited, however, to do some
474 adjustments to the bitmap (like alignment) in order to optimize blitting to/from it.
475 In fact if the display driver was asked to create such a bitmap, this means that
476 the standard bitmap is being created as a friend of some bitmap which was allocated
477 using this driver. This way the bitmap is expected to be friendly to this driver.
479 *****************************************************************************************/
481 /*****************************************************************************************
493 Specify or query pixelformat descriptor object associated with the bitmap.
495 Every bitmap has some associated pixelformat object. Pixelformat objects are
496 shared data storages, so many bitmaps may refer to the same pixelformat objects.
499 This attribute is internally specified during bitmap creation, but it's illegal
500 to do this for the user. CreateObject method of graphics driver performs an explicit
501 check against this. It's up to graphics base classes to figure out its value.
511 *****************************************************************************************/
513 /*****************************************************************************************
525 Specify display mode ID for displayable bitmap.
527 A displayable bitmap must have this attribute supplied with valid value. A nondisplayable
528 one may miss it, however it may remember it if it was created as a friend of displayable
529 one. This way you may create another displayable bitmap as a friend of nondisplayable
530 one which in turn is a friend of displayable one.
532 This attribute can be set on a framebuffer bitmap. Doing so means an explicit request
533 for the driver to change current display mode on the hardware. Dependent parameters
534 (width, height and pixelformat) will be automatically adjusted, if not explicitly
535 specified in the attributes list.
538 If the given ModeID is not supported, the operation causes an error. You can check
539 for this by checking return value of OOP_SetAttrs() function. It will be TRUE in
540 case of success and FALSE upon failure. In case of failure none of bitmap attributes
551 *****************************************************************************************/
553 /*****************************************************************************************
556 aoHidd_BitMap_ClassPtr
565 Explicitly specify bitmap's class pointer.
567 This attribute is not actually a bitmap's attribute. Your display driver class can
568 supply it to base class' moHidd_Gfx_CreateObject method in order to select a class on
569 which to call OOP_NewObject().
571 If neither this attribute nor aoHidd_BitMap_ClassID attribute is provided for
572 moHidd_Gfx_CreateObject, graphics base class will do its best in order to find out the
573 correct class based on aoHidd_StdPixFmt attribute value or friend bitmap.
576 If a friend bitmap is given, the new bitmap will have the same class, if your driver
577 doesn't override it by supplying explicit class specification (using either
578 aoHidd_BitMap_ClassPtr or aoHidd_BitMap_ClassID attribute).
585 aoHidd_BitMap_ClassID, CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
589 *****************************************************************************************/
591 /*****************************************************************************************
594 aoHidd_BitMap_ClassID
603 Explicitly specify bitmap's class ID.
605 The purpose of this attribute is to let graphics driver base class to select a class
606 on which to call OOP_NewObject() in its moHidd_Gfx_CreateObject implementation.
608 If neither this attribute nor aoHidd_BitMap_ClassPtr attribute is provided for
609 moHidd_Gfx_CreateObject, graphics base class will do its best in order to find out the
610 correct class based on aoHidd_StdPixFmt attribute value or aoHidd_BitMap_ClassPtr value
618 The pointer to a given class will not be remembered as aoHidd_BitMap_ClassPtr value.
621 aoHidd_BitMap_ClassPtr, CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
625 *****************************************************************************************/
627 /*****************************************************************************************
630 aoHidd_BitMap_PixFmtTags
639 Private, very obsolete and currently has no function. Considered reserved.
651 *****************************************************************************************/
653 /*****************************************************************************************
656 aoHidd_BitMap_FrameBuffer
665 Specifies that the bitmap is a framebuffer bitmap.
667 A detailed description of a framebuffer is given in CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
668 and in CLID_Hidd_Gfx/moHidd_Gfx_Show documentation.
670 Specifying this attribute causes also implicit setting of aoHidd_BitMap_Displayable
683 *****************************************************************************************/
685 /*****************************************************************************************
688 aoHidd_BitMap_LeftEdge
697 Controls horizontal position of a scrollable screen bitmap.
699 Size of displayable bitmaps may differ from actual screen size. In this case the
700 bitmap can be scrolled around the whole display area. If the bitmap is larger than
701 the display, only its part can be visible.
703 Setting this attribute causes changing left origin point of the bitmap. The value
704 of this attribute represents an offset from the physical edge of the display to the
705 logical edge of the bitmap. This means that if a large bitmap scrolls to the left in
706 order to reveal its right part, the offset will be negative. If the bitmap scrolls
707 to the left (possibly revealing another bitmap behind it), the offset will be positive.
709 It's up to the display driver to set scroll limits. If the value of the attribute
710 becomes unacceptable for any reason, the driver should adjust it and provide the real
711 resulting value back.
714 Implementing screen scrolling does not enforce to implement screen composition, despite
715 the composition is really based on scrolling (in case of composition scrolling a bitmap
716 off-display is expected to reveal another bitmap behind it instead of empty space).
723 aoHidd_BitMap_TopEdge
726 Base class will always provide zero value for this attribute and ignore all attempts
727 to set it. This means that by default bitmaps don't scroll and this needs explicit
728 implementation in the display driver.
730 *****************************************************************************************/
732 /*****************************************************************************************
735 aoHidd_BitMap_TopEdge
744 Controls vertical position of a scrollable screen bitmap.
746 Size of displayable bitmaps may differ from actual screen size. In this case the
747 bitmap can be scrolled around the whole display area. If the bitmap is larger than
748 the display, only its part can be visible.
750 Setting this attribute causes changing top origin point of the bitmap. The value
751 of this attribute represents an offset from the physical edge of the display to the
752 logical edge of the bitmap. This means that if a large bitmap scrolls upwards in
753 order to reveal its bottom part, the offset will be negative. If the bitmap scrolls
754 downwards (possibly revealing another bitmap behind it), the offset will be positive.
756 It's up to the display driver to set scroll limits. If the value of the attribute
757 becomes unacceptable for any reason, the driver should adjust it and provide the real
758 resulting value back.
761 Implementing screen scrolling does not enforce to implement screen composition, despite
762 the composition is really based on scrolling (in case of composition scrolling a bitmap
763 off-display is expected to reveal another bitmap behind it instead of empty space).
773 *****************************************************************************************/
775 /*****************************************************************************************
787 Specify number of pixels to align bitmap data width to.
789 This attribute can be added in order to enforce alignment needed for example by
790 blitting hardware. It will have an impact on default aoHidd_BitMap_BytesPerRow
793 Direct specification of aoHidd_BitMap_BytesPerRow attribute overrides any value
797 Default value of this attribute is 16. This alignment is required by graphics.library
798 for AmigaOS(tm) compatibility reasons.
805 aoHidd_BitMap_BytesPerRow
809 *****************************************************************************************/
811 /*****************************************************************************************
823 Specify or query the actual bitmap depth.
825 This a convenience attribute to simplify handling planar bitmaps, whose actual depth
826 may vary. Default implementation in base class simply returns depth of bitmap's
827 pixelformat, and is ignored during initialization. Planar bitmap class returns the
828 actual depth here. If your specific bitmap class also operates on bitmaps with variable
829 depths, you need to implement this attribute in it.
841 *****************************************************************************************/
843 /****************************************************************************************/
848 * Calculate suggested bytes per row value based on bitmap's default alignment
849 * and pixelformat's bytes per pixel value.
851 static ULONG
GetBytesPerRow(struct HIDDBitMapData
*data
, struct class_static_data
*csd
)
853 struct Library
*OOPBase
= csd
->cs_OOPBase
;
854 UWORD align
= data
->align
- 1;
855 UWORD width
= (data
->width
+ align
) & ~align
;
856 IPTR bytesperpixel
, stdpf
;
858 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_BytesPerPixel
, &bytesperpixel
);
859 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_StdPixFmt
, &stdpf
);
861 if (stdpf
== vHidd_StdPixFmt_Plane
)
864 * Planar format actually have 8 pixels per one byte.
865 * However bytesperpixel == 1 for them. Perhaps this should
872 return width
* bytesperpixel
;
878 OOP_Object
*BM__Root__New(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_New
*msg
)
880 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
881 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
883 EnterFunc(bug("BitMap::New()\n"));
885 obj
= (OOP_Object
*)OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
) msg
);
889 struct TagItem colmap_tags
[] =
891 { aHidd_ColorMap_NumEntries
, 16 },
894 struct TagItem
*tag
, *tstate
;
896 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
898 /* Set some default values */
899 data
->modeid
= vHidd_ModeID_Invalid
;
902 data
->compositable
= FALSE
;
904 tstate
= msg
->attrList
;
905 while ((tag
= NextTagItem(&tstate
)))
909 if (IS_BITMAP_ATTR(tag
->ti_Tag
, idx
))
913 case aoHidd_BitMap_BMStruct
:
914 data
->bmstruct
= (struct BitMap
*)tag
->ti_Data
;
917 case aoHidd_BitMap_Width
:
918 data
->width
= tag
->ti_Data
;
921 case aoHidd_BitMap_Height
:
922 data
->height
= tag
->ti_Data
;
925 case aoHidd_BitMap_Align
:
926 data
->align
= tag
->ti_Data
;
929 case aoHidd_BitMap_BytesPerRow
:
930 data
->bytesPerRow
= tag
->ti_Data
;
933 case aoHidd_BitMap_GfxHidd
:
934 data
->gfxhidd
= (OOP_Object
*)tag
->ti_Data
;
937 case aoHidd_BitMap_Friend
:
938 data
->friend = (OOP_Object
*)tag
->ti_Data
;
941 case aoHidd_BitMap_Displayable
:
942 data
->displayable
= tag
->ti_Data
;
945 case aoHidd_BitMap_Compositable
:
946 data
->compositable
= tag
->ti_Data
;
949 case aoHidd_BitMap_FrameBuffer
:
950 data
->framebuffer
= tag
->ti_Data
;
953 case aoHidd_BitMap_ModeID
:
954 data
->modeid
= tag
->ti_Data
;
957 case aoHidd_BitMap_PixFmt
:
958 data
->prot
.pixfmt
= (OOP_Object
*)tag
->ti_Data
;
964 /* aoHidd_BitMap_GfxHidd is mandatory */
967 D(bug("!!!! BM CLASS DID NOT GET GFX HIDD !!!\n"));
968 D(bug("!!!! The reason for this is that the gfxhidd subclass CreateObject() method\n"));
969 D(bug("!!!! has not left it to the baseclass to actually create the object,\n"));
970 D(bug("!!!! but rather done it itself. This MUST be corrected in the gfxhidd subclass\n"));
975 /* FrameBuffer implies Displayable */
976 if (data
->framebuffer
)
977 data
->displayable
= TRUE
;
979 if (ok
&& (data
->displayable
|| data
->compositable
))
981 HIDDT_ModeID bmmodeid
= data
->modeid
;
983 /* We should always get modeid, but we check anyway */
984 if ((data
->compositable
) && (data
->friend))
986 OOP_GetAttr(data
->friend, aHidd_BitMap_ModeID
, &bmmodeid
);
987 D(bug("!!! BitMap:New() Using Friends ModeID - 0x%08X !!!\n", bmmodeid
));
990 if (bmmodeid
== vHidd_ModeID_Invalid
)
992 D(bug("!!! BitMap:New() NO VALID MODEID SPECIFIED FOR DISPLAYABLE BITMAP !!!\n"));
993 data
->compositable
= ok
= FALSE
;
997 OOP_Object
*sync
, *pf
;
999 if (!HIDD_Gfx_GetMode(data
->gfxhidd
, bmmodeid
, &sync
, &pf
))
1001 D(bug("!!! BitMap::New() RECEIVED INVALID MODEID 0x%08X\n", bmmodeid
));
1002 data
->compositable
= ok
= FALSE
;
1006 /* Get display size from the modeid */
1007 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &data
->displayWidth
);
1008 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &data
->displayHeight
);
1009 data
->display
.MaxX
= data
->displayWidth
;
1010 data
->display
.MaxY
= data
->displayHeight
;
1012 /* Update the missing bitmap data */
1014 data
->width
= data
->displayWidth
;
1016 data
->height
= data
->displayHeight
;
1018 D(bug("[BitMap] Bitmap %dx%d, display %dx%d\n",
1019 data
->width
, data
->height
,
1020 data
->displayWidth
, data
->displayHeight
));
1022 if (!data
->prot
.pixfmt
)
1024 /* The PixFmt is allready registered and locked in the PixFmt database */
1025 data
->prot
.pixfmt
= pf
;
1033 /* * PixFmt will be NULL in case of e.g. planarbm late initialization. */
1034 if (data
->prot
.pixfmt
)
1036 ULONG bytesPerRow
= GetBytesPerRow(data
, CSD(cl
));
1038 if (data
->bytesPerRow
)
1040 /* If we have user-supplied BytesPerRow value, make sure it's suitable */
1041 if (data
->bytesPerRow
< bytesPerRow
)
1046 /* Otherwise we have what we calculated */
1047 data
->bytesPerRow
= bytesPerRow
;
1054 InitSemaphore(&data
->lock
);
1056 /* Cache default GC */
1057 OOP_GetAttr(data
->gfxhidd
, aHidd_Gfx_DefaultGC
, (IPTR
*)&data
->gc
);
1060 * Initialize the direct method calling.
1061 * We don't check against errors because our base class contains all
1064 #if USE_FAST_PUTPIXEL
1065 data
->putpixel
= OOP_GetMethod(obj
, HiddBitMapBase
+ moHidd_BitMap_PutPixel
, &data
->putpixel_Class
);
1067 #if USE_FAST_GETPIXEL
1068 data
->getpixel
= OOP_GetMethod(obj
, HiddBitMapBase
+ moHidd_BitMap_GetPixel
, &data
->getpixel_Class
);
1070 #if USE_FAST_DRAWPIXEL
1071 data
->drawpixel
= OOP_GetMethod(obj
, HiddBitMapBase
+ moHidd_BitMap_DrawPixel
, &data
->drawpixel_Class
);
1075 * Try to create the colormap.
1077 * stegerg: Only add a ColorMap for a visible bitmap (screen). This
1078 * is important because one can create for example a bitmap
1079 * in PIXFMT_LUT8 without friend bitmap and then copy this
1080 * bitmap to a 16 bit screen. During copy the screen bitmap
1081 * CLUT must be used, which would not happen if our PIXFMT_LUT8
1082 * also had a colormap itself because then bltbitmap would use the
1083 * colormap of the PIXFMT_LUT8 bitmap as lookup, which in this
1084 * case would just cause everything to become black in the
1085 * destination (screen) bitmap, because noone ever sets up the
1086 * colormap of the PIXFMT_LUT8 bitmap
1088 * sonic: CHECKME: Why does the colormap always have 16 colors? May be calculate this
1089 * based on depth ? The colormap auto-enlarges itself if SetColors method requests
1090 * missing entries, but is it so good?
1093 if (data
->displayable
)
1095 data
->colmap
= OOP_NewObject(NULL
, CLID_Hidd_ColorMap
, colmap_tags
);
1096 if (NULL
== data
->colmap
)
1104 ULONG dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
1106 OOP_CoerceMethod(cl
, obj
, &dispose_mid
);
1111 } /* if (NULL != obj) */
1113 ReturnPtr("BitMap::New", OOP_Object
*, obj
);
1116 /****************************************************************************************/
1118 void BM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*obj
, OOP_Msg
*msg
)
1120 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
1121 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
1123 EnterFunc(bug("BitMap::Dispose()\n"));
1125 if (NULL
!= data
->colmap
)
1126 OOP_DisposeObject(data
->colmap
);
1128 D(bug("Calling super\n"));
1130 /* Release the previously registered pixel format */
1131 if (data
->pf_registered
)
1132 GFX__Hidd_Gfx__ReleasePixFmt(CSD(cl
)->gfxhiddclass
, data
->prot
.pixfmt
);
1134 OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
) msg
);
1136 ReturnVoid("BitMap::Dispose");
1139 /****************************************************************************************/
1141 VOID
BM__Root__Get(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_Get
*msg
)
1143 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
1146 EnterFunc(bug("BitMap::Get() attrID: %i storage: %p\n", msg
->attrID
, msg
->storage
));
1148 if (IS_BITMAP_ATTR(msg
->attrID
, idx
))
1152 case aoHidd_BitMap_BMStruct
:
1153 *msg
->storage
= (IPTR
)data
->bmstruct
;
1156 case aoHidd_BitMap_Width
:
1157 *msg
->storage
= data
->width
;
1158 D(bug(" width: %i\n", data
->width
));
1161 case aoHidd_BitMap_Height
:
1162 *msg
->storage
= data
->height
;
1165 case aoHidd_BitMap_Depth
:
1167 * Generally our bitmaps have a fixed depth, which depends on pixelformat.
1168 * If this is not true for your bitmap, overload aoHidd_BitMap_Depth in your class.
1170 *msg
->storage
= ((HIDDT_PixelFormat
*)data
->prot
.pixfmt
)->depth
;
1173 case aoHidd_BitMap_Displayable
:
1174 *msg
->storage
= data
->displayable
;
1177 case aoHidd_BitMap_FrameBuffer
:
1178 *msg
->storage
= data
->framebuffer
;
1181 case aoHidd_BitMap_PixFmt
:
1182 *msg
->storage
= (IPTR
)data
->prot
.pixfmt
;
1185 case aoHidd_BitMap_Friend
:
1186 *msg
->storage
= (IPTR
)data
->friend;
1189 case aoHidd_BitMap_ColorMap
:
1190 *msg
->storage
= (IPTR
)data
->colmap
;
1193 case aoHidd_BitMap_GfxHidd
:
1194 *msg
->storage
= (IPTR
)data
->gfxhidd
;
1197 case aoHidd_BitMap_ModeID
:
1198 *msg
->storage
= data
->modeid
;
1201 case aoHidd_BitMap_Align
:
1202 *msg
->storage
= data
->align
;
1205 case aoHidd_BitMap_BytesPerRow
:
1206 *msg
->storage
= data
->bytesPerRow
;
1209 case aoHidd_BitMap_Visible
:
1210 /* Framebuffer is always visible */
1211 *msg
->storage
= data
->framebuffer
? TRUE
: data
->visible
;
1214 case aoHidd_BitMap_Compositable
:
1215 *msg
->storage
= (IPTR
)data
->compositable
;
1219 * The following two are stored with inverted sign!
1220 * Verbose explanation is in Set method.
1222 case aoHidd_BitMap_LeftEdge
:
1223 *msg
->storage
= -data
->display
.MinX
;
1226 case aoHidd_BitMap_TopEdge
:
1227 *msg
->storage
= -data
->display
.MinY
;
1230 D(default: bug("UNKNOWN ATTR IN BITMAP BASECLASS: %d\n", idx
);)
1234 OOP_DoSuperMethod(cl
, obj
, &msg
->mID
);
1235 ReturnVoid("BitMap::Get");
1238 /****************************************************************************************/
1240 #define UB(x) ((UBYTE *)x)
1242 /*****************************************************************************************
1245 moHidd_BitMap_SetColors
1248 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetColors *msg);
1250 BOOL HIDD_BM_SetColors (OOP_Object *obj, HIDDT_Color *colors,
1251 UWORD firstColor, UWORD numColors);
1254 hidd.graphics.bitmap
1257 Sets values for one or more colors in the colormap object associated with the
1260 The colormap will be created if it does not exist.
1262 Only ARGB values from the source array are taken into account. pixval member is
1263 updated with the real pixel value for every color.
1266 obj - A bitmap object whose colormap needs to be set
1267 colors - A pointer to source data array
1268 firstColor - Number of the first color to set
1269 numColors - Number of subsequent colors to set
1272 TRUE on success, FALSE in case of some error (like out of memory)
1281 CLID_Hidd_ColorMap/moHidd_ColorMap_SetColors
1285 *****************************************************************************************/
1287 BOOL
BM__Hidd_BitMap__SetColors(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_SetColors
*msg
)
1289 /* Copy the colors into the internal buffer */
1290 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
1291 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
1294 /* Subclass has initialized HIDDT_Color->pixelVal field and such.
1295 Just copy it into the colortab.
1298 if (NULL
== data
->colmap
)
1300 struct TagItem colmap_tags
[] =
1302 { aHidd_ColorMap_NumEntries
, 0 },
1306 colmap_tags
[0].ti_Data
= msg
->firstColor
+ msg
->numColors
;
1307 data
->colmap
= OOP_NewObject(NULL
, CLID_Hidd_ColorMap
, colmap_tags
);
1310 if (NULL
== data
->colmap
)
1315 /* Use the colormap class to set the colors */
1316 if (!HIDD_CM_SetColors(data
->colmap
, msg
->colors
,
1317 msg
->firstColor
, msg
->numColors
,
1323 /* We may need to duplicate changes on framebuffer if running in mirrored mode */
1326 ObtainSemaphoreShared(&data
->lock
);
1330 ret
= GFX__Hidd_Gfx__SetFBColors(CSD(cl
)->gfxhiddclass
, data
->gfxhidd
, msg
);
1333 ReleaseSemaphore(&data
->lock
);
1339 /*******************************************************************************
1342 moHidd_BitMap_PutPixel
1345 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutPixel *msg);
1347 VOID HIDD_BM_PutPixel(OOP_Object *obj, WORD x, WORD y,
1351 hidd.graphics.bitmap
1354 Sets a new color value for the pixel at (x,y). The actual color stored
1355 may be an approximation, due to the limited color depth or palette size
1356 of the bitmap. This function does not check the coordinates.
1359 obj - bitmap to write to.
1360 x, y - coordinates of the pixel to write.
1361 pixel - the pixel's new color value.
1376 *******************************************************************************/
1378 /* PutPixel must be implemented in a subclass */
1380 /*****************************************************************************************
1383 moHidd_BitMap_DrawPixel
1386 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPixel *msg);
1388 VOID HIDD_BM_DrawPixel(OOP_Object *obj, OOP_Object *gc, WORD x, WORD y);
1391 hidd.graphics.bitmap
1394 Changes the pixel at (x,y). The color of the pixel depends on the
1395 attributes of gc, eg. colors, drawmode, colormask etc.
1396 This function does not check the coordinates.
1399 obj - A bitmap to draw on
1400 gc - A GC (graphics context) object to use for drawing
1401 x, y - Coordinates of the pixel to draw
1417 - Support for shapeplane.
1420 *****************************************************************************************/
1422 VOID
BM__Hidd_BitMap__DrawPixel(OOP_Class
*cl
, OOP_Object
*obj
,
1423 struct pHidd_BitMap_DrawPixel
*msg
)
1425 HIDDT_Pixel src
, dest
, val
;
1426 HIDDT_DrawMode mode
;
1427 HIDDT_Pixel writeMask
;
1430 /* EnterFunc(bug("BitMap::DrawPixel() x: %i, y: %i\n", msg->x, msg->y));
1433 Example: Pixels whose bits are set to 0 in the colMask must be
1436 data->colMask = 001111
1440 writeMask = ~data->colMask & dest
1444 dest = data->fg && dest = 010100
1447 dest = dest & (writeMask | data->ColMask)
1448 = 010100 & (100000 | 001111)
1453 dest = dest | writeMask;
1464 #if OPTIMIZE_DRAWPIXEL_FOR_COPY
1465 if (vHidd_GC_DrawMode_Copy
== mode
&& GC_COLMASK(gc
) == ~0)
1472 dest
= GETPIXEL(cl
, obj
, msg
->x
, msg
->y
);
1473 writeMask
= ~GC_COLMASK(gc
) & dest
;
1477 if(mode
& 1) val
= ( src
& dest
);
1478 if(mode
& 2) val
= ( src
& ~dest
) | val
;
1479 if(mode
& 4) val
= (~src
& dest
) | val
;
1480 if(mode
& 8) val
= (~src
& ~dest
) | val
;
1482 val
= (val
& (writeMask
| GC_COLMASK(gc
) )) | writeMask
;
1486 PUTPIXEL(cl
, obj
, msg
->x
, msg
->y
, val
);
1489 /*****************************************************************************************
1492 moHidd_BitMap_DrawLine
1495 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPixel *msg);
1497 VOID HIDD_BM_DrawLine(OOP_Object *obj, OOP_Object *gc, WORD x1, WORD y1,
1501 hidd.graphics.bitmap
1504 Draws a line from (x1,y1) to (x2,y2) in the specified gc.
1505 The function does not clip the line against the drawing area.
1508 obj - A bitmap to draw on
1509 gc - A graphics context object to use
1510 x1,y1 - start point of the line in pixels
1511 x2,y2 - end point of the line in pixels
1525 Uses midpoint line ("Bresenham") algorithm([FOL90] 3.2.2)
1527 TODO Support for line pattern
1528 Optimize remove if t == 1 ...
1529 Implement better clipping: Should be no reason to calculate
1530 more than the part of the line that is inside the cliprect
1532 *****************************************************************************************/
1534 VOID BM__Hidd_BitMap__DrawLine
1536 OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawLine
*msg
1539 WORD dx
, dy
, incrE
, incrNE
, d
, x
, y
, s1
, s2
, t
, i
;
1540 WORD x1
, y1
, x2
, y2
;
1541 UWORD maskLine
; /* for line pattern */
1542 ULONG fg
; /* foreground pen */
1548 /* bug("BitMap::DrawLine()\n");
1549 */ EnterFunc(bug("BitMap::DrawLine() x1: %i, y1: %i x2: %i, y2: %i\n", msg
->x1
, msg
->y1
, msg
->x2
, msg
->y2
));
1552 doclip
= GC_DOCLIP(gc
);
1553 opaque
= (GC_COLEXP(gc
) & vHidd_GC_ColExp_Opaque
) ? TRUE
: FALSE
;
1556 maskLine
= 1 << GC_LINEPATCNT(gc
);
1560 /* If line is not inside cliprect, then just return */
1561 /* Normalize coords */
1562 if (msg
->x1
> msg
->x2
)
1564 x1
= msg
->x2
; x2
= msg
->x1
;
1568 x1
= msg
->x1
; x2
= msg
->x2
;
1571 if (msg
->y1
> msg
->y2
)
1573 y1
= msg
->y2
; y2
= msg
->y1
;
1577 y1
= msg
->y1
; y2
= msg
->y2
;
1580 if ( x1
> GC_CLIPX2(gc
)
1581 || x2
< GC_CLIPX1(gc
)
1582 || y1
> GC_CLIPY2(gc
)
1583 || y2
< GC_CLIPY1(gc
) )
1586 /* Line is not inside cliprect, so just return */
1600 Horizontal line drawing code.
1604 /* Don't swap coordinates if x2 < x1! Because of linepattern! */
1617 for(i
= x1
; i
!= x2
; i
+= dx
)
1619 /* Pixel inside ? */
1621 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, i
, y
))
1623 if(GC_LINEPAT(gc
) & maskLine
)
1625 HIDD_BM_DrawPixel(obj
, gc
, i
, y
);
1629 GC_FG(gc
) = GC_BG(gc
);
1630 HIDD_BM_DrawPixel(obj
, gc
, i
, y
);
1635 maskLine
= maskLine
>> 1;
1636 if (!maskLine
) maskLine
= 1L << 15;
1642 Vertical line drawing code.
1646 /* Don't swap coordinates if y2 < y1! Because of linepattern! */
1659 for(i
= y1
; i
!= y2
; i
+= dy
)
1661 /* Pixel inside ? */
1662 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, x
, i
))
1664 if(GC_LINEPAT(gc
) & maskLine
)
1666 HIDD_BM_DrawPixel(obj
, gc
, x
, i
);
1670 GC_FG(gc
) = GC_BG(gc
);
1671 HIDD_BM_DrawPixel(obj
, gc
, x
, i
);
1676 maskLine
= maskLine
>> 1;
1677 if (!maskLine
) maskLine
= 1L << 15;
1684 Generic line drawing code.
1686 /* Calculate slope */
1690 /* which direction? */
1691 if((x2
- x1
) > 0) s1
= 1; else s1
= - 1;
1692 if((y2
- y1
) > 0) s2
= 1; else s2
= - 1;
1694 /* change axes if dx < dy */
1707 d
= 2 * dy
- dx
; /* initial value of d */
1709 incrE
= 2 * dy
; /* Increment use for move to E */
1710 incrNE
= 2 * (dy
- dx
); /* Increment use for move to NE */
1714 for(i
= 0; i
<= dx
; i
++)
1716 /* Pixel inside ? */
1717 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, x
, y
))
1719 if(GC_LINEPAT(gc
) & maskLine
)
1721 HIDD_BM_DrawPixel(obj
, gc
, x
, y
);
1725 GC_FG(gc
) = GC_BG(gc
);
1726 HIDD_BM_DrawPixel(obj
, gc
, x
, y
);
1751 maskLine
= maskLine
>> 1;
1752 if (!maskLine
) maskLine
= 1L << 15;
1757 ReturnVoid("BitMap::DrawLine ");
1760 /*****************************************************************************************
1763 moHidd_BitMap_DrawRect
1766 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawRect *msg);
1768 VOID HIDD_BM_DrawRect (OOP_Object *obj, OOP_Object *gc, WORD minX, WORD minY,
1769 WORD maxX, WORD maxY);
1772 hidd.graphics.bitmap
1775 Draws a hollow rectangle. minX and minY specifies the upper
1776 left corner of the rectangle. minY and maxY specifies the lower
1777 right corner of the rectangle.
1778 The function does not clip the rectangle against the drawing area.
1781 obj - A bitmap to draw on
1782 gc - A GC object to use for drawing
1783 minX, minY - upper left corner of the rectangle in pixels
1784 maxX, maxY - lower right corner of the rectangle in pixels
1790 This method is not used by the system and considered reserved.
1802 *****************************************************************************************/
1804 VOID
BM__Hidd_BitMap__DrawRect(OOP_Class
*cl
, OOP_Object
*obj
,
1805 struct pHidd_BitMap_DrawRect
*msg
)
1808 OOP_Object
*gc
= msg
->gc
;
1811 EnterFunc(bug("BitMap::DrawRect()"));
1813 if(msg
->minX
== msg
->maxX
) addX
= 0; else addX
= 1;
1814 if(msg
->minY
== msg
->maxY
) addY
= 0; else addY
= 1;
1816 HIDD_BM_DrawLine(obj
, gc
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->minY
);
1817 HIDD_BM_DrawLine(obj
, gc
, msg
->maxX
, msg
->minY
+ addY
, msg
->maxX
, msg
->maxY
);
1818 HIDD_BM_DrawLine(obj
, gc
, msg
->maxX
- addX
, msg
->maxY
, msg
->minX
, msg
->maxY
);
1819 HIDD_BM_DrawLine(obj
, gc
, msg
->minX
, msg
->maxY
- addY
, msg
->minX
, msg
->minY
+ addY
);
1822 ReturnVoid("BitMap::DrawRect");
1825 /*****************************************************************************************
1828 moHidd_BitMap_FillRect
1831 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawRect *msg);
1833 VOID HIDD_BM_FillRect (OOP_Object *obj, OOP_Object *gc, WORD minX, WORD minY,
1834 WORD maxX, WORD maxY);
1837 hidd.graphics.bitmap
1841 Draws a solid rectangle. minX and minY specifies the upper
1842 left corner of the rectangle. maxX and maxY specifies the lower
1843 right corner of the rectangle.
1844 The function does not clip the rectangle against the drawing area.
1847 obj - A bitmap to draw on
1848 gc - A GC object to use for drawing
1849 minX, minY - upper left corner of the rectangle in pixels
1850 maxX, maxY - lower right corner of the rectangle in pixels
1868 *****************************************************************************************/
1870 VOID
BM__Hidd_BitMap__FillRect(OOP_Class
*cl
, OOP_Object
*obj
,
1871 struct pHidd_BitMap_DrawRect
*msg
)
1873 OOP_Object
*gc
= msg
->gc
;
1877 EnterFunc(bug("BitMap::FillRect()"));
1879 linepat
= GC_LINEPAT(gc
);
1880 GC_LINEPAT(gc
) = ~0;
1882 for(; y
<= msg
->maxY
; y
++)
1884 HIDD_BM_DrawLine(obj
, gc
, msg
->minX
, y
, msg
->maxX
, y
);
1887 GC_LINEPAT(gc
) = linepat
;
1889 ReturnVoid("BitMap::FillRect");
1892 /*****************************************************************************************
1895 moHidd_BitMap_DrawEllipse
1898 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawEllipse *msg);
1900 VOID HIDD_BM_DrawEllipse (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
1904 hidd.graphics.bitmap
1907 Draws a hollow ellipse from the center point (x,y) with the radii
1908 rx and ry in the specified bitmap.
1909 The function does not clip the ellipse against the drawing area.
1912 obj - A bitmap to draw on
1913 gc - A GC object to use for drawing
1914 x,y - Coordinates of center point in pixels
1915 rx,ry - ry and ry radius in pixels
1925 Because of overflow the current code do not work with big
1926 values of rx and ry.
1935 *****************************************************************************************/
1937 /* TODO: Try to opimize clipping here */
1939 VOID
BM__Hidd_BitMap__DrawEllipse(OOP_Class
*cl
, OOP_Object
*obj
,
1940 struct pHidd_BitMap_DrawEllipse
*msg
)
1942 OOP_Object
*gc
= msg
->gc
;
1943 WORD x
= msg
->rx
, y
= 0; /* ellipse points */
1945 /* intermediate terms to speed up loop */
1946 LONG t1
= msg
->rx
* msg
->rx
, t2
= t1
<< 1, t3
= t2
<< 1;
1947 LONG t4
= msg
->ry
* msg
->ry
, t5
= t4
<< 1, t6
= t5
<< 1;
1948 LONG t7
= msg
->rx
* t5
, t8
= t7
<< 1, t9
= 0L;
1949 LONG d1
= t2
- t7
+ (t4
>> 1); /* error terms */
1950 LONG d2
= (t1
>> 1) - t8
+ t5
;
1952 APTR doclip
= GC_DOCLIP(gc
);
1955 EnterFunc(bug("BitMap::DrawEllipse()"));
1957 while (d2
< 0) /* till slope = -1 */
1959 /* draw 4 points using symmetry */
1964 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
+ y
))
1965 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1967 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
- y
))
1968 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1970 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
+ y
))
1971 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1973 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
- y
))
1974 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1979 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1980 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1981 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1982 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1985 y
++; /* always move up here */
1987 if (d1
< 0) /* move straight up */
1992 else /* move up and left */
1996 d1
= d1
+ t9
+ t2
- t8
;
1997 d2
= d2
+ t9
+ t5
- t8
;
2001 do /* rest of top right quadrant */
2003 /* draw 4 points using symmetry */
2008 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
+ y
))
2009 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
2011 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
- y
))
2012 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
2014 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
+ y
))
2015 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
2017 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
- y
))
2018 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
2024 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
2025 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
2026 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
2027 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
2031 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
2032 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
2033 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
2034 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
2036 x
--; /* always move left here */
2038 if (d2
< 0) /* move up and left */
2042 d2
= d2
+ t9
+ t5
- t8
;
2044 else /* move straight left */
2052 ReturnVoid("BitMap::DrawEllipse");
2055 /*****************************************************************************************
2058 moHidd_BitMap_FillEllipse
2061 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawEllipse *msg);
2063 VOID HIDD_BM_FillEllipse (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2067 hidd.graphics.bitmap
2070 Draws a solid ellipse from the center point (x,y) with the radii
2071 rx and ry in the specified bitmap.
2072 The function does not clip the ellipse against the drawing area.
2075 obj - A bitmap to draw on
2076 gc - A GC object to use for drawing
2077 x,y - Coordinates of center point in pixels
2078 rx,ry - ry and ry radius in pixels
2084 This method is not used by the system and considered reserved.
2088 Because of overflow the current code do not work with big
2089 values of rx and ry.
2098 *****************************************************************************************/
2100 VOID
BM__Hidd_BitMap__FillEllipse(OOP_Class
*cl
, OOP_Object
*obj
,
2101 struct pHidd_BitMap_DrawEllipse
*msg
)
2104 OOP_Object
*gc
= msg
->gc
;
2105 WORD x
= msg
->rx
, y
= 0; /* ellipse points */
2107 /* intermediate terms to speed up loop */
2108 LONG t1
= msg
->rx
* msg
->rx
, t2
= t1
<< 1, t3
= t2
<< 1;
2109 LONG t4
= msg
->ry
* msg
->ry
, t5
= t4
<< 1, t6
= t5
<< 1;
2110 LONG t7
= msg
->rx
* t5
, t8
= t7
<< 1, t9
= 0L;
2111 LONG d1
= t2
- t7
+ (t4
>> 1); /* error terms */
2112 LONG d2
= (t1
>> 1) - t8
+ t5
;
2114 EnterFunc(bug("BitMap::FillEllipse()"));
2116 while (d2
< 0) /* till slope = -1 */
2118 /* draw 4 points using symmetry */
2119 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
+ y
, msg
->x
+ x
, msg
->y
+ y
);
2120 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
- y
, msg
->x
+ x
, msg
->y
- y
);
2122 y
++; /* always move up here */
2124 if (d1
< 0) /* move straight up */
2129 else /* move up and left */
2133 d1
= d1
+ t9
+ t2
- t8
;
2134 d2
= d2
+ t9
+ t5
- t8
;
2138 do /* rest of top right quadrant */
2140 /* draw 4 points using symmetry */
2141 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
+ y
, msg
->x
+ x
, msg
->y
+ y
);
2142 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
- y
, msg
->x
+ x
, msg
->y
- y
);
2144 x
--; /* always move left here */
2146 if (d2
< 0) /* move up and left */
2150 d2
= d2
+ t9
+ t5
- t8
;
2152 else /* move straight left */
2160 ReturnVoid("BitMap::FillEllipse");
2163 /*****************************************************************************************
2166 moHidd_BitMap_DrawPolygon
2169 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg);
2171 VOID HIDD_BM_DrawPolygon (OOP_Object *obj, OOP_Object *gc, UWORD n, WORD *coords);
2174 hidd.graphics.bitmap
2177 Draws a hollow polygon from the list of coordinates in coords[].
2178 The function does not clip the polygon against the drawing area.
2181 obj - A bitmap to draw on
2182 gc - A GC object to use for drawing
2183 n - number of coordinate pairs
2184 coords - array of n (x, y) coordinates in pixels
2190 This method is not used by the system and considered reserved.
2202 *****************************************************************************************/
2204 VOID
BM__Hidd_BitMap__DrawPolygon(OOP_Class
*cl
, OOP_Object
*obj
,
2205 struct pHidd_BitMap_DrawPolygon
*msg
)
2208 OOP_Object
*gc
= msg
->gc
;
2211 EnterFunc(bug("BitMap::DrawPolygon()"));
2213 for(i
= 2; i
< (2 * msg
->n
); i
= i
+ 2)
2215 HIDD_BM_DrawLine(obj
, gc
, msg
->coords
[i
- 2], msg
->coords
[i
- 1],
2216 msg
->coords
[i
], msg
->coords
[i
+ 1]);
2220 ReturnVoid("BitMap::DrawPolygon");
2223 /*****************************************************************************************
2226 moHidd_BitMap_FillPolygon
2229 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg);
2231 VOID HIDD_BM_FillPolygon (OOP_Object *obj, OOP_Object *gc, UWORD n, WORD *coords);
2234 hidd.graphics.bitmap
2237 This method was initially designed for drawing solid polygons, however it was never
2238 used and implemented. At the moment it is considered reserved, its synopsis and
2239 semantics may change in future.
2242 obj - A bitmap to draw on
2243 gc - A GC object to use for drawing
2244 n - number of coordinate pairs
2245 coords - array of n (x, y) coordinates in pixels
2255 Never used and implemented
2263 *****************************************************************************************/
2265 VOID
BM__Hidd_BitMap__FillPolygon(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawPolygon
*msg
)
2267 D(bug("Sorry, FillPolygon() not implemented yet in bitmap baseclass\n"));
2270 /*****************************************************************************************
2273 moHidd_BitMap_DrawText
2276 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2278 VOID HIDD_BM_DrawText (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2279 STRPTR text, UWORD length);
2282 hidd.graphics.bitmap
2285 Draws the first length characters of text at (x, y).
2286 The function does not clip the text against the drawing area.
2289 obj - A bitmap to draw on
2290 gc - A GC object to use for drawing and font specification
2291 x, y - Position to start drawing in pixels. The x
2292 coordinate is relativ to the left side of the
2294 The y coordinate is relative to the baseline of the font.
2295 text - Pointer to a Latin 1 string
2296 length - Number of characters to draw
2302 At the moment text drawing is processed entirely by graphics.library
2303 using BltTemplate(), which in turn uses moHodd_BitMap_PutTemplate.
2304 This method is considered obsolete.
2309 The default implementation in the base class does not process styles,
2310 color and alpha-blended fonts.
2318 *****************************************************************************************/
2320 VOID
BM__Hidd_BitMap__DrawText(OOP_Class
*cl
, OOP_Object
*obj
,
2321 struct pHidd_BitMap_DrawText
*msg
)
2324 OOP_Object
*gc
= msg
->gc
;
2325 struct TextFont
*font
= GC_FONT(gc
);
2326 UBYTE
*charPatternPtr
= font
->tf_CharData
;
2327 UWORD modulo
= font
->tf_Modulo
;
2329 UBYTE ch
; /* current character to print */
2330 WORD fx
, fx2
, fy
, fw
; /* position and length of character in the */
2331 /* character bitmap */
2332 WORD xMem
= msg
->x
; /* position in bitmap */
2333 WORD yMem
= msg
->y
- font
->tf_Baseline
;
2337 EnterFunc(bug("BitMap::DrawText()"));
2339 for(i
= 0; i
< msg
->length
; i
++)
2343 if((ch
< font
->tf_LoChar
) || (ch
> font
->tf_HiChar
))
2345 ch
= font
->tf_HiChar
- font
->tf_LoChar
+ 1;
2349 ch
= ch
- font
->tf_LoChar
;
2352 if(font
->tf_Flags
& FPF_PROPORTIONAL
)
2354 xMem
= xMem
+ ((UWORD
*) font
->tf_CharKern
)[ch
];
2357 charLog
= ((ULONG
*) font
->tf_CharLoc
)[ch
];
2358 fx2
= charLog
>> 16; /* x position of character pattern in character bitmap */
2359 fw
= (UWORD
) charLog
; /* width of character pattern in character bitmap */
2363 for(fy
= 0; fy
< font
->tf_YSize
; fy
++)
2367 for(fx
= fx2
; fx
< fw
+ fx2
; fx
++)
2369 if(*(charPatternPtr
+ fx
/ 8 + fy
* modulo
) & (128 >> (fx
% 8)))
2371 HIDD_BM_DrawPixel(obj
, msg
->gc
, x
, y
);
2379 if(font
->tf_Flags
& FPF_PROPORTIONAL
)
2381 xMem
= xMem
+ ((UWORD
*) font
->tf_CharSpace
)[ch
];
2385 xMem
= xMem
+ font
->tf_XSize
;
2389 ReturnVoid("BitMap::DrawText");
2392 /*****************************************************************************************
2395 moHidd_BitMap_FillText
2398 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2400 VOID HIDD_BM_FillText (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2401 STRPTR text, UWORD length);
2404 hidd.graphics.bitmap
2407 Historically this method was designed to draw a text with background.
2408 It was never implemented.
2410 Currently this method is considered reserved. Its synopsis and semantics
2411 may change in future.
2414 obj - A bitmap to draw on
2415 gc - A GC object to use for drawing
2416 x, y - Position to start drawing in pixels. The x
2417 coordinate is relative to the left side of the
2419 The y coordinate is relative to the baseline of the font.
2420 text - Pointer to a Latin 1 string
2421 length - Number of characters to draw
2437 *****************************************************************************************/
2439 VOID
BM__Hidd_BitMap__FillText(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawText
*msg
)
2441 D(bug("Sorry, FillText() not implemented yet in bitmap baseclass\n"));
2444 /*****************************************************************************************
2447 moHidd_BitMap_FillSpan
2450 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2453 hidd.graphics.bitmap
2456 Reserved, never implemented method. The definition will change in future.
2475 *****************************************************************************************/
2477 VOID
BM__Hidd_BitMap__FillSpan(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawText
*msg
)
2479 D(bug("Sorry, FillSpan() not implemented yet\n"));
2482 /*****************************************************************************************
2488 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_Clear *msg);
2490 VOID HIDD_BM_Clear (OOP_Object *obj, OOP_Object *gc);
2493 hidd.graphics.bitmap
2496 Sets all pixels of the drawing area to the background color.
2499 obj - A bitmap to clear.
2500 gc - A GC object, specifies background color value
2505 This method is not used by the system and considered reserved. However it can
2506 be useful for display driver's own needs.
2511 Default implementation in the base class sets all pixels to zero color instead of
2512 the background color from GC
2520 *****************************************************************************************/
2522 VOID
BM__Hidd_BitMap__Clear(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_Clear
*msg
)
2524 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
2528 EnterFunc(bug("BitMap::Clear()\n"));
2530 OOP_GetAttr(obj
, aHidd_BitMap_Width
, &width
);
2531 OOP_GetAttr(obj
, aHidd_BitMap_Height
, &height
);
2533 for(y
= 0; y
< height
; y
++)
2535 for(x
= 0; x
< width
; x
++)
2537 HIDD_BM_PutPixel(obj
, x
, y
, 0);
2541 ReturnVoid("BitMap::Clear");
2544 /****************************************************************************************/
2546 static LONG
inline getpixfmtbpp(OOP_Class
*cl
, OOP_Object
*o
, HIDDT_StdPixFmt stdpf
)
2548 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
2550 struct HIDDBitMapData
*data
;
2553 data
= OOP_INST_DATA(cl
, o
);
2557 case vHidd_StdPixFmt_Native
:
2558 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_BytesPerPixel
, &bpp
);
2561 case vHidd_StdPixFmt_Native32
:
2562 bpp
= sizeof (HIDDT_Pixel
);
2566 pf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, stdpf
);
2570 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", stdpf
));
2574 OOP_GetAttr(pf
, aHidd_PixFmt_BytesPerPixel
, &bpp
);
2582 /*****************************************************************************************
2585 moHidd_BitMap_GetImage
2588 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_GetImage *msg);
2590 VOID HIDD_BM_GetImage (OOP_Object *obj, UBYTE *pixels, ULONG modulo, WORD x, WORD y,
2591 WORD width, WORD height, HIDDT_StdPixFmt pixFmt);
2594 hidd.graphics.bitmap
2619 *****************************************************************************************/
2621 VOID
BM__Hidd_BitMap__GetImage(OOP_Class
*cl
, OOP_Object
*o
,
2622 struct pHidd_BitMap_GetImage
*msg
)
2625 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
2626 APTR ppixarray
= &pixarray
;
2628 struct HIDDBitMapData
*data
;
2630 data
= OOP_INST_DATA(cl
, o
);
2632 EnterFunc(bug("BitMap::GetImage(x=%d, y=%d, width=%d, height=%d)\n"
2633 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
2636 bpp
= getpixfmtbpp(cl
, o
, msg
->pixFmt
);
2639 D(bug("!!! INVALID PIXFMT IN BitMap::GetImage(): %d !!!\n", msg
->pixFmt
));
2646 case vHidd_StdPixFmt_Native
:
2647 case vHidd_StdPixFmt_Native32
:
2648 for (y
= 0; y
< msg
->height
; y
++)
2650 for (x
= 0; x
< msg
->width
; x
++)
2652 register HIDDT_Pixel pix
;
2654 pix
= HIDD_BM_GetPixel(o
, x
+ msg
->x
, y
+ msg
->y
);
2663 *((UWORD
*)pixarray
) = pix
;
2669 pixarray
[0] = (pix
>> 16) & 0xFF;
2670 pixarray
[1] = (pix
>> 8) & 0xFF;
2671 pixarray
[2] = pix
& 0xFF;
2673 pixarray
[0] = pix
& 0xFF;
2674 pixarray
[1] = (pix
>> 8) & 0xFF;
2675 pixarray
[2] = (pix
>> 16) & 0xFF;
2681 *(ULONG
*)pixarray
= pix
;
2688 pixarray
+= (msg
->modulo
- msg
->width
* bpp
);
2696 APTR buf
, srcPixels
;
2698 dstpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
2700 buf
= srcPixels
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
2703 for(y
= 0; y
< msg
->height
; y
++)
2712 vHidd_StdPixFmt_Native
);
2714 HIDD_BM_ConvertPixels(o
,
2716 (HIDDT_PixelFormat
*)data
->prot
.pixfmt
,
2719 (HIDDT_PixelFormat
*)dstpf
,
2731 } /* switch(msg->pixFmt) */
2733 ReturnVoid("BitMap::GetImage");
2736 /*****************************************************************************************
2739 moHidd_BitMap_PutImage
2742 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutImage *msg);
2744 VOID HIDD_BM_PutImage (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
2745 WORD x, WORD y, WORD width, WORD height, HIDDT_StdPixFmt pixFmt);
2748 hidd.graphics.bitmap
2774 *****************************************************************************************/
2776 VOID
BM__Hidd_BitMap__PutImage(OOP_Class
*cl
, OOP_Object
*o
,
2777 struct pHidd_BitMap_PutImage
*msg
)
2780 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
2781 APTR ppixarray
= &pixarray
;
2784 struct HIDDBitMapData
*data
;
2785 OOP_Object
*gc
= msg
->gc
;
2787 data
= OOP_INST_DATA(cl
, o
);
2789 EnterFunc(bug("BitMap::PutImage(x=%d, y=%d, width=%d, height=%d)\n"
2790 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
2792 if (msg
->width
<= 0 || msg
->height
<= 0)
2795 bpp
= getpixfmtbpp(cl
, o
, msg
->pixFmt
);
2798 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", msg
->pixFmt
));
2804 case vHidd_StdPixFmt_Native
:
2805 case vHidd_StdPixFmt_Native32
:
2807 /* Preserve old fg pen */
2810 for (y
= 0; y
< msg
->height
; y
++)
2812 for (x
= 0; x
< msg
->width
; x
++)
2814 register HIDDT_Pixel pix
= 0;
2819 pix
= *((UBYTE
*)pixarray
);
2824 pix
= *((UWORD
*)pixarray
);
2830 pix
= ((UBYTE
*)pixarray
)[0] << 16;
2831 pix
|= ((UBYTE
*)pixarray
)[1] << 8;
2832 pix
|= ((UBYTE
*)pixarray
)[2];
2834 pix
= ((UBYTE
*)pixarray
)[2] << 16;
2835 pix
|= ((UBYTE
*)pixarray
)[1] << 8;
2836 pix
|= ((UBYTE
*)pixarray
)[0];
2842 pix
= *((ULONG
*)pixarray
); pixarray
+= 4;
2849 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->x
, y
+ msg
->y
);
2851 pixarray
+= (msg
->modulo
- msg
->width
* bpp
);
2860 APTR buf
, destPixels
;
2862 srcpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
2864 buf
= destPixels
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
2867 for(y
= 0; y
< msg
->height
; y
++)
2869 HIDD_BM_ConvertPixels(o
,
2871 (HIDDT_PixelFormat
*)srcpf
,
2874 (HIDDT_PixelFormat
*)data
->prot
.pixfmt
,
2888 vHidd_StdPixFmt_Native
);
2895 } /* switch(msg->pixFmt) */
2897 ReturnVoid("BitMap::PutImage");
2900 /****************************************************************************************/
2903 __attribute__((always_inline
, const)) do_alpha(int a
, int v
)
2906 return ((tmp
<<8) + tmp
+ 32768)>>16;
2911 #define RGB32_DECOMPOSE(red, green, blue, pix) \
2912 red = ((pix) & 0x00FF0000) >> 16; \
2913 green = ((pix) & 0x0000FF00) >> 8; \
2914 blue = ((pix) & 0x000000FF);
2916 #define ARGB32_ALPHA(pix) ((pix) & 0xFF000000)
2918 #define ARGB32_DECOMPOSE(alpha, red, green, blue, pix) \
2919 alpha = ((pix) & 0xFF000000) >> 24; \
2920 red = ((pix) & 0x00FF0000) >> 16; \
2921 green = ((pix) & 0x0000FF00) >> 8; \
2922 blue = ((pix) & 0x000000FF);
2924 #define ARGB32_COMPOSE(red, green, blue, old) (((old) & 0xFF000000) + ((red) << 16) + ((green) << 8) + (blue))
2928 #define RGB32_DECOMPOSE(red, green, blue, pix) \
2929 red = (pix & 0x0000FF00) >> 8; \
2930 green = (pix & 0x00FF0000) >> 16; \
2931 blue = (pix & 0xFF000000) >> 24
2933 #define ARGB32_ALPHA(pix) ((pix) & 0x000000FF)
2935 #define ARGB32_DECOMPOSE(alpha, red, green, blue, pix) \
2936 alpha = (pix & 0x000000FF); \
2937 red = (pix & 0x0000FF00) >> 8; \
2938 green = (pix & 0x00FF0000) >> 16; \
2939 blue = (pix & 0xFF000000) >> 24
2941 #define ARGB32_COMPOSE(red, green, blue, old) (((blue) << 24) + ((green) << 16) + ((red) << 8) + ((old) & 0x000000FF))
2945 /*****************************************************************************************
2948 moHidd_BitMap_PutAlphaImage
2951 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutAlphaImage *msg);
2953 VOID HIDD_BM_PutAlphaImage (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
2954 WORD x, WORD y, WORD width, WORD height);
2957 hidd.graphics.bitmap
2960 Perform an alpha-blending operation between a bitmap and ARGB pixel array.
2963 obj - A bitmap to operate on
2964 gc - A GC object, internally needed to perform the operation. All its attributes
2966 pixels - A pointer to an array of pixels
2967 modulo - Number of bytes per row in pixel array
2968 x, y - Top-left corner of affected bitmap's region
2969 width - Width of the modified rectangle.
2970 height - Height of the modified rectangle.
2976 Do not rely on 'gc' parameter being valid when implementing this method in own
2977 display driver. This parameter is actually obsolete, and will be set to NULL in
2978 future AROS versions. Current base class implementation ignores it.
2988 *****************************************************************************************/
2998 * 1. Merge buffered and slow versions of PutAlphaImage(), use the same processing algorithm
2999 * (convert array's pixels to bitmap's format, not vice versa)
3000 * 2. Make DoBufferedOperation() public, to be used for cybergraphics.library/ProcessPixelArray()
3001 * implementation, and for some other functions in graphics.library and cybergraphics.library,
3002 * currently using own implementation of pixel buffer.
3003 * 3. Reuse the new code for other buffered operations (currently using old macros).
3006 static void PutAlphaImageBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct paib_data
*data
)
3010 for (y
= 0; y
< height
; y
++)
3012 ULONG
*pixarray
= data
->pixels
;
3014 for (x
= 0; x
< width
; x
++)
3018 ULONG src_red
, src_green
, src_blue
, src_alpha
;
3019 ULONG dst_red
, dst_green
, dst_blue
;
3021 srcpix
= *pixarray
++;
3023 if (ARGB32_ALPHA(srcpix
) == ARGB32_ALPHA(0xFFFFFFFF))
3027 else if (ARGB32_ALPHA(srcpix
) != 0)
3029 ARGB32_DECOMPOSE(src_alpha
, src_red
, src_green
, src_blue
, srcpix
);
3032 RGB32_DECOMPOSE(dst_red
, dst_green
, dst_blue
, destpix
);
3034 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
3035 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
3036 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
3038 xbuf
[x
] = ARGB32_COMPOSE(dst_red
, dst_green
, dst_blue
, destpix
);
3043 data
->pixels
+= data
->modulo
;
3047 VOID
BM__Hidd_BitMap__PutAlphaImage(OOP_Class
*cl
, OOP_Object
*o
,
3048 struct pHidd_BitMap_PutAlphaImage
*msg
)
3051 struct paib_data data
= {msg
->pixels
, msg
->modulo
};
3053 EnterFunc(bug("BitMap::PutAlphaImage(x=%d, y=%d, width=%d, height=%d)\n"
3054 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3056 if (msg
->width
<= 0 || msg
->height
<= 0)
3059 if (!DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, TRUE
, vHidd_StdPixFmt_ARGB32
,
3060 (VOID_FUNC
)PutAlphaImageBuffered
, &data
))
3062 /* Buffered method failed, use slow pixel-by-pixel method */
3063 for (y
= msg
->y
; y
< msg
->y
+ msg
->height
; y
++)
3065 ULONG
*pixarray
= data
.pixels
;
3067 for (x
= msg
->x
; x
< msg
->x
+ msg
->width
; x
++)
3069 HIDDT_Pixel destpix
;
3072 LONG src_red
, src_green
, src_blue
, src_alpha
;
3073 LONG dst_red
, dst_green
, dst_blue
;
3075 destpix
= HIDD_BM_GetPixel(o
, x
, y
);
3076 HIDD_BM_UnmapPixel(o
, destpix
, &col
);
3078 srcpix
= *pixarray
++;
3079 ARGB32_DECOMPOSE(src_alpha
, src_red
, src_green
, src_blue
, srcpix
);
3081 dst_red
= col
.red
>> 8;
3082 dst_green
= col
.green
>> 8;
3083 dst_blue
= col
.blue
>> 8;
3085 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
3086 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
3087 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
3089 col
.red
= dst_red
<< 8;
3090 col
.green
= dst_green
<< 8;
3091 col
.blue
= dst_blue
<< 8;
3093 HIDD_BM_PutPixel(o
, x
, y
, HIDD_BM_MapColor(o
, &col
));
3095 } /* for(x = msg->x; x < msg->x + msg->width; x++) */
3097 data
.pixels
+= msg
->modulo
;
3099 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
3101 ReturnVoid("BitMap::PutAlphaImage");
3104 /*****************************************************************************************
3107 moHidd_BitMap_PutTemplate
3110 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutTemplate *msg);
3112 VOID HIDD_BM_PutTemplate (OOP_Object *obj, OOP_Object *gc, UBYTE *masktemplate, ULONG modulo,
3113 WORD srcx, WORD x, WORD y, WORD width, WORD height, BOOL inverttemplate);
3116 hidd.graphics.bitmap
3119 Apply a single-bit mask to the given portion of the bitmap. Pixels set to 1 in the mask will be filled
3120 by foreground color. Pixels set to 0 in the mask will be filled by background color or left unchanged,
3121 according to the following GC attributes:
3122 Foreground - a foreground color
3123 Background - a background color
3124 DrawMode - if set to Invert, foreground and background colors will be ignored. Instead,
3125 pixels which are set to 1 in the mask, will be inverted. Other pixels will be
3127 ColorExpansion - if set to Transparent, only pixels which are set to 1 in the mask, will be modified.
3128 Other pixels will not be changed (background color will be ignored).
3131 obj - A bitmap to draw on
3132 gc - A GC object, holding operation parameters
3133 masktemplate - A pointer to a bit mask
3134 modulo - Number of bytes per line in the mask
3135 srcx - Horizontal offset of the mask
3136 x, y - Top-left corner of the bitmap's region to affect
3137 width - Width of the affected region
3138 height - Height of the affected region
3139 inverttemplate - If set to TRUE, bit mask will be interpreted in inverted form
3154 *****************************************************************************************/
3166 static void JAM1TemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ptb_data
*data
)
3170 for (y
= 0; y
< height
; y
++)
3172 ULONG mask
= data
->bitmask
;
3173 UWORD
*array
= data
->bitarray
;
3174 UWORD bitword
= AROS_BE2WORD(*array
);
3176 for (x
= 0; x
< width
; x
++)
3178 if ((bitword
& mask
) == (data
->invert
& mask
))
3186 bitword
= AROS_BE2WORD(*array
);
3191 data
->bitarray
+= data
->modulo
;
3195 static void ComplementTemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ptb_data
*data
)
3199 for (y
= 0; y
< height
; y
++)
3201 ULONG mask
= data
->bitmask
;
3202 UWORD
*array
= data
->bitarray
;
3203 UWORD bitword
= AROS_BE2WORD(*array
);
3205 for (x
= 0; x
< width
; x
++)
3207 if ((bitword
& mask
) == (data
->invert
& mask
))
3215 bitword
= AROS_BE2WORD(*array
);
3220 data
->bitarray
+= data
->modulo
;
3224 static void JAM2TemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ptb_data
*data
)
3228 for (y
= 0; y
< height
; y
++)
3230 ULONG mask
= data
->bitmask
;
3231 UWORD
*array
= data
->bitarray
;
3232 UWORD bitword
= AROS_BE2WORD(*array
);
3234 for (x
= 0; x
< width
; x
++)
3236 if ((bitword
& mask
) == (data
->invert
& mask
))
3246 bitword
= AROS_BE2WORD(*array
);
3251 data
->bitarray
+= data
->modulo
;
3255 VOID
BM__Hidd_BitMap__PutTemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTemplate
*msg
)
3257 OOP_Object
*gc
= msg
->gc
;
3259 void (*op
)(ULONG
*, UWORD
, UWORD
, UWORD
, struct ptb_data
*);
3260 struct ptb_data data
;
3262 EnterFunc(bug("BitMap::PutTemplate(x=%d, y=%d, width=%d, height=%d)\n"
3263 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3265 if (msg
->width
<= 0 || msg
->height
<= 0)
3268 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
3270 op
= JAM1TemplateBuffered
;
3272 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
3274 op
= ComplementTemplateBuffered
;
3278 op
= JAM2TemplateBuffered
;
3282 data
.bitarray
= msg
->masktemplate
+ ((msg
->srcx
/ 16) * 2);
3283 data
.bitmask
= 0x8000 >> (msg
->srcx
& 0xF);
3284 data
.modulo
= msg
->modulo
;
3285 data
.fg
= GC_FG(msg
->gc
);
3286 data
.bg
= GC_BG(msg
->gc
);
3287 data
.invert
= msg
->inverttemplate
? 0 : 0xFFFF;
3289 DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, get
, vHidd_StdPixFmt_Native32
, (VOID_FUNC
)op
, &data
);
3291 /* TODO: write fallback */
3293 ReturnVoid("BitMap::PutTemplate");
3296 /*****************************************************************************************
3299 moHidd_BitMap_PutAlphaTemplate
3302 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutAlphaTemplate *msg);
3304 VOID HIDD_BM_PutAlphaTemplate (OOP_Object *obj, OOP_Object *gc, UBYTE *alpha, ULONG modulo,
3305 WORD x, WORD y, WORD width, WORD height, BOOL invertalpha);
3308 hidd.graphics.bitmap
3311 Perform a drawing with current foreground color, using 8-bit alpha channel mask. The following
3312 GC attributes are considered:
3313 Foreground - a foreground color
3314 Background - a background color
3315 DrawMode - if set to Invert, foreground and background colors will be ignored. Instead,
3316 pixels, for which alpha channel value is greater than 127, will be inverted.
3317 Other pixels will be left unchanged.
3318 ColorExpansion - if set to Opaque, alpha blending will happen between foreground and background
3319 colors, instead of between foreground color and old bitmap contents.
3322 obj - A bitmap to draw on
3323 gc - A GC object specifying drawing parameters
3324 alpha - A pointer to an 8-bit per pixel alpha channel mask
3325 modulo - Number of bytes per line in the mask
3326 x, y - Top-left corner of the affected bitmap's region
3327 width - Width of the affected bitmap's region
3328 height - Height of the affected bitmap's region
3329 invertalpha - If set to TRUE, alpha mask values will be treated in inverted form
3344 *****************************************************************************************/
3350 LONG a_red
, a_green
, a_blue
;
3351 LONG b_red
, b_green
, b_blue
;
3355 static void JAM1AlphaTemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct patb_data
*data
)
3359 for (y
= 0; y
< height
; y
++)
3361 UBYTE
*pixarray
= data
->pixarray
;
3363 for (x
= 0; x
< width
; x
++)
3365 LONG dst_red
, dst_green
, dst_blue
, alpha
;
3367 alpha
= (*pixarray
++) ^ data
->invert
;
3368 RGB32_DECOMPOSE(dst_red
, dst_green
, dst_blue
, xbuf
[x
]);
3370 dst_red
+= do_alpha(alpha
, data
->a_red
- dst_red
);
3371 dst_green
+= do_alpha(alpha
, data
->a_green
- dst_green
);
3372 dst_blue
+= do_alpha(alpha
, data
->a_blue
- dst_blue
);
3374 xbuf
[x
] = ARGB32_COMPOSE(dst_red
, dst_green
, dst_blue
, 0);
3378 data
->pixarray
+= data
->modulo
;
3382 static void ComplementAlphaTemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct patb_data
*data
)
3386 for (y
= 0; y
< height
; y
++)
3388 UBYTE
*pixarray
= data
->pixarray
;
3390 for (x
= 0; x
< width
; x
++)
3392 UBYTE alpha
= (*pixarray
++) ^ data
->invert
;
3399 data
->pixarray
+= data
->modulo
;
3403 static void JAM2AlphaTemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct patb_data
*data
)
3407 for (y
= 0; y
< height
; y
++)
3409 UBYTE
*pixarray
= data
->pixarray
;
3411 for (x
= 0; x
< width
; x
++)
3413 LONG dst_red
, dst_green
, dst_blue
, alpha
;
3415 alpha
= (*pixarray
++) ^ data
->invert
;
3417 dst_red
= data
->b_red
+ ((data
->a_red
- data
->b_red
) * alpha
) / 256;
3418 dst_green
= data
->b_green
+ ((data
->a_green
- data
->b_green
) * alpha
) / 256;
3419 dst_blue
= data
->b_blue
+ ((data
->a_blue
- data
->b_blue
) * alpha
) / 256;
3421 xbuf
[x
] = ARGB32_COMPOSE(dst_red
, dst_green
, dst_blue
, 0);
3425 data
->pixarray
+= data
->modulo
;
3429 VOID
BM__Hidd_BitMap__PutAlphaTemplate(OOP_Class
*cl
, OOP_Object
*o
,
3430 struct pHidd_BitMap_PutAlphaTemplate
*msg
)
3432 OOP_Object
*gc
= msg
->gc
;
3434 void (*op
)(ULONG
*, UWORD
, UWORD
, UWORD
, struct patb_data
*);
3435 struct patb_data data
;
3438 EnterFunc(bug("BitMap::PutAlphaTemplate(x=%d, y=%d, width=%d, height=%d)\n"
3439 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3441 if (msg
->width
<= 0 || msg
->height
<= 0)
3444 HIDD_BM_UnmapPixel(o
, GC_FG(gc
), &color
);
3445 data
.a_red
= color
.red
>> 8;
3446 data
.a_green
= color
.green
>> 8;
3447 data
.a_blue
= color
.blue
>> 8;
3449 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
3451 op
= JAM1AlphaTemplateBuffered
;
3453 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
3455 op
= ComplementAlphaTemplateBuffered
;
3459 op
= JAM2AlphaTemplateBuffered
;
3462 HIDD_BM_UnmapPixel(o
, GC_BG(gc
), &color
);
3463 data
.b_red
= color
.red
>> 8;
3464 data
.b_green
= color
.green
>> 8;
3465 data
.b_blue
= color
.blue
>> 8;
3468 data
.pixarray
= msg
->alpha
;
3469 data
.modulo
= msg
->modulo
;
3470 data
.invert
= msg
->invertalpha
? 255 : 0;
3472 DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, get
, vHidd_StdPixFmt_ARGB32
, (VOID_FUNC
)op
, &data
);
3474 /* TODO: write fallback */
3476 ReturnVoid("BitMap::PutAlphaTemplate");
3479 /*****************************************************************************************
3482 moHidd_BitMap_PutPattern
3485 VOID OOP_DoMethod(OOP_Object *o, struct pHidd_BitMap_PutPattern *msg);
3487 VOID HIDD_BM_PutPattern(OOP_Object *obj, OOP_Object *gc, UBYTE *pattern,
3488 WORD patternsrcx, WORD patternsrcy, WORD patternheight, WORD patterndepth,
3489 HIDDT_PixelLUT *patternlut, BOOL invertpattern, UBYTE *mask,
3490 ULONG maskmodulo, WORD masksrcx, WORD x, WORD y,
3491 WORD width, WORD height);
3494 hidd.graphics.bitmap
3499 obj - A bitmap to draw on
3500 gc - A GC object to use for drawing
3528 *****************************************************************************************/
3537 UWORD patternheight
;
3547 static void JAM1PatternBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
)
3551 for (y
= 0; y
< height
; y
++)
3553 UWORD pmask
= data
->patmask
;
3554 UWORD mmask
= data
->maskmask
;
3555 UWORD
*parray
= data
->patarray
+ ((y
+ starty
+ data
->patternsrcy
- data
->desty
) % data
->patternheight
);
3556 UWORD patword
= AROS_BE2WORD(*parray
);
3557 UWORD
*marray
= data
->maskarray
;
3558 UWORD maskword
= marray
? AROS_BE2WORD(*marray
) : 0xFFFF;
3560 for (x
= 0; x
< width
; x
++)
3562 if (maskword
& mmask
)
3564 if ((patword
& pmask
) == (data
->invert
& pmask
))
3575 maskword
= AROS_BE2WORD(*marray
);
3586 if (data
->maskarray
)
3587 data
->maskarray
+= data
->maskmodulo
;
3592 static void ComplementPatternBuffered(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
)
3609 if ((patword
& pmask
) == (data
->invert
& pmask
))
3620 maskword
= AROS_BE2WORD(*marray
);
3631 if (data
->maskarray
)
3632 data
->maskarray
+= data
->maskmodulo
;
3637 static void JAM2PatternBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
)
3641 for (y
= 0; y
< height
; y
++)
3643 UWORD pmask
= data
->patmask
;
3644 UWORD mmask
= data
->maskmask
;
3645 UWORD
*parray
= data
->patarray
+ ((y
+ starty
+ data
->patternsrcy
- data
->desty
) % data
->patternheight
);
3646 UWORD patword
= AROS_BE2WORD(*parray
);
3647 UWORD
*marray
= data
->maskarray
;
3648 UWORD maskword
= marray
? AROS_BE2WORD(*marray
) : 0xFFFF;
3650 for (x
= 0; x
< width
; x
++)
3652 if (maskword
& mmask
)
3654 if ((patword
& pmask
) == (data
->invert
& pmask
))
3667 maskword
= AROS_BE2WORD(*marray
);
3678 if (data
->maskarray
)
3679 data
->maskarray
+= data
->maskmodulo
;
3684 static void ColorPatternBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
)
3688 for (y
= 0; y
< height
; y
++)
3690 UWORD pmask
= data
->patmask
;
3691 UWORD mmask
= data
->maskmask
;
3692 UWORD
*parray
= data
->patarray
+ ((y
+ starty
+ data
->patternsrcy
- data
->desty
) % data
->patternheight
);
3693 UWORD patword
= AROS_BE2WORD(*parray
);
3694 UWORD
*marray
= data
->maskarray
;
3695 UWORD maskword
= marray
? AROS_BE2WORD(*marray
) : 0xFFFF;
3697 for (x
= 0; x
< width
; x
++)
3699 if (maskword
& mmask
)
3702 ULONG pixel
= (patword
& pmask
) ? 1 : 0; /* CHECKME: Shouldn't we handle INVERSVID here too ? */
3704 for (plane
= 1; plane
< data
->patterndepth
; plane
++)
3706 UWORD
*_parray
= parray
+ plane
* data
->patternheight
;
3707 UWORD _patword
= AROS_BE2WORD(*_parray
);
3709 if (_patword
& pmask
)
3710 pixel
|= 1L << plane
;
3713 if (data
->patternlut
)
3714 pixel
= data
->patternlut
[pixel
];
3726 maskword
= AROS_BE2WORD(*marray
);
3737 if (data
->maskarray
)
3738 data
->maskarray
+= data
->maskmodulo
;
3743 VOID
BM__Hidd_BitMap__PutPattern(OOP_Class
*cl
, OOP_Object
*o
,
3744 struct pHidd_BitMap_PutPattern
*msg
)
3746 void (*op
)(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
);
3748 struct ppb_data data
;
3750 DPUTPATTERN(bug("BitMap::PutPattern(x=%d, y=%d, width=%d, height=%d)\n",
3751 msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3753 if (msg
->width
<= 0 || msg
->height
<= 0)
3756 if (msg
->patterndepth
> 1)
3758 DPUTPATTERN(bug("[PutPattern] Color\n"));
3759 op
= ColorPatternBuffered
;
3762 else if (GC_COLEXP(msg
->gc
) == vHidd_GC_ColExp_Transparent
)
3764 DPUTPATTERN(bug("[PutPattern] JAM1\n"));
3765 op
= JAM1PatternBuffered
;
3767 else if (GC_DRMD(msg
->gc
) == vHidd_GC_DrawMode_Invert
)
3769 DPUTPATTERN(bug("[PutPattern] Complement\n"));
3770 op
= ComplementPatternBuffered
;
3774 DPUTPATTERN(bug("[PutPattern] JAM2\n"));
3775 op
= JAM2PatternBuffered
;
3779 data
.patarray
= (UWORD
*)msg
->pattern
;
3780 data
.patmask
= 0x8000 >> (msg
->patternsrcx
& 0xF);
3781 data
.maskarray
= msg
->mask
;
3782 data
.patternlut
= msg
->patternlut
? msg
->patternlut
->pixels
: NULL
;
3783 data
.patternsrcy
= msg
->patternsrcy
;
3784 data
.desty
= msg
->y
;
3785 data
.patternheight
= msg
->patternheight
;
3786 data
.patterndepth
= msg
->patterndepth
;
3787 data
.maskmodulo
= msg
->maskmodulo
;
3788 data
.fg
= GC_FG(msg
->gc
);
3789 data
.bg
= GC_BG(msg
->gc
);
3790 data
.invert
= msg
->invertpattern
? 0 : 0xFFFF;
3794 data
.maskarray
+= (msg
->masksrcx
/ 16) * 2;
3795 data
.maskmask
= 0x8000 >> (msg
->masksrcx
& 0xF);
3799 data
.maskmask
= 0xFFFF;
3801 DPUTPATTERN(bug("[PutPattern] MaskArray 0x%p, MaskMask 0x%04X\n", data
.maskarray
, data
.maskmask
));
3803 DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, get
, vHidd_StdPixFmt_Native32
, (VOID_FUNC
)op
, &data
);
3805 /* TODO: Write fallback */
3807 ReturnVoid("BitMap::PutPattern");
3810 /*****************************************************************************************
3813 moHidd_BitMap_PutImageLUT
3816 VOID OOP_DoMethod(OOP_Object *o, struct pHidd_BitMap_PutImageLUT *msg);
3818 VOID HIDD_BM_PutImageLUT (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
3819 WORD x, WORD y, WORD width, WORD height, HIDDT_PixelLUT *pixlut);
3822 hidd.graphics.bitmap
3848 *****************************************************************************************/
3850 VOID
BM__Hidd_BitMap__PutImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
3851 struct pHidd_BitMap_PutImageLUT
*msg
)
3854 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
3855 HIDDT_PixelLUT
*pixlut
= msg
->pixlut
;
3856 HIDDT_Pixel
*lut
= pixlut
? pixlut
->pixels
: NULL
;
3857 HIDDT_Pixel
*linebuf
;
3858 OOP_Object
*gc
= msg
->gc
;
3860 EnterFunc(bug("BitMap::PutImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
3861 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3863 if (msg
->width
<= 0 || msg
->height
<= 0)
3866 linebuf
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
3868 for(y
= 0; y
< msg
->height
; y
++)
3874 for(x
= 0; x
< msg
->width
; x
++)
3876 linebuf
[x
] = lut
[pixarray
[x
]];
3881 for(x
= 0; x
< msg
->width
; x
++)
3883 linebuf
[x
] = pixarray
[x
];
3886 pixarray
+= msg
->modulo
;
3896 vHidd_StdPixFmt_Native32
);
3898 } /* if (linebuf) */
3903 /* Preserve old fg pen */
3908 for(x
= 0; x
< msg
->width
; x
++)
3910 GC_FG(gc
) = lut
[pixarray
[x
]];
3911 HIDD_BM_DrawPixel(o
, gc
, msg
->x
+ x
, msg
->y
+ y
);
3916 for(x
= 0; x
< msg
->width
; x
++)
3918 GC_FG(gc
) = pixarray
[x
];
3919 HIDD_BM_DrawPixel(o
, gc
, msg
->x
+ x
, msg
->y
+ y
);
3924 pixarray
+= msg
->modulo
;
3926 } /* if (linebuf) else ... */
3928 } /* for(y = 0; y < msg->height; y++) */
3932 ReturnVoid("BitMap::PutImageLUT");
3934 /*****************************************************************************************
3937 moHidd_BitMap_PutTranspImageLUT
3940 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutTranspImageLUT *msg);
3942 VOID HIDD_BM_PutTranspImageLUT (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels,
3943 ULONG modulo, WORD x, WORD y, WORD width, WORD height,
3944 HIDDT_PixelLUT *pixlut, UBYTE transparent);
3947 hidd.graphics.bitmap
3950 Copy an array of 8-bit LUT pixels to the bitmap at the specified position making
3951 one of colors transparent.
3953 Pixels are converted to bitmap's native format using either user-supplied LUT (if
3954 given) or bitmap's own colormap.
3956 Draw mode of the supplied GC is ignored, the operation is always bulk copy.
3959 obj - A bitmap to draw image on
3960 gc - A GC used for drawing
3961 pixels - A pointer to source pixel array
3962 modulo - Total number of bytes per line in the source array
3963 x, y - Top-left corner of the destination rectangle
3964 width - Width of the image to draw
3965 height - Height of the image to draw
3966 pixlut - An optional pointer to a LUT to use. NULL means using bitmap's
3967 own colormap (if available)
3968 transparent - Value of pixels in the source array which will be made
3984 *****************************************************************************************/
3986 #undef csd /* Bad hack, but there's no other way */
3993 struct class_static_data
*csd
;
3998 static void PutTranspImageLUTBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ptilb_data
*data
)
4000 struct class_static_data
*csd
= data
->csd
;
4003 for (y
= 0; y
< height
; y
++)
4005 UBYTE
*pixarray
= data
->pixarray
;
4009 for (x
= 0; x
< width
; x
++)
4011 UBYTE pix
= *pixarray
++;
4013 if (pix
!= data
->transparent
)
4014 xbuf
[x
] = data
->lut
[pix
];
4020 for (x
= 0; x
< width
; x
++)
4022 UBYTE pix
= *pixarray
++;
4024 if (pix
!= data
->transparent
)
4027 pix
= HIDD_CM_GetPixel(data
->colmap
, pix
);
4036 data
->pixarray
+= data
->modulo
;
4040 VOID
BM__Hidd_BitMap__PutTranspImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
4041 struct pHidd_BitMap_PutTranspImageLUT
*msg
)
4043 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
4044 struct ptilb_data userdata
=
4054 EnterFunc(bug("BitMap::PutTranspImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
4055 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
4057 if (msg
->width
<= 0 || msg
->height
<= 0)
4061 userdata
.lut
= msg
->pixlut
->pixels
;
4063 DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, TRUE
, vHidd_StdPixFmt_Native32
,
4064 (VOID_FUNC
)PutTranspImageLUTBuffered
, &userdata
);
4066 /* TODO: Write fallback */
4068 ReturnVoid("BitMap::PutTranspImageLUT");
4073 /*****************************************************************************************
4076 moHidd_BitMap_GetImageLUT
4079 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_GetImageLUT *msg);
4081 VOID HIDD_BM_GetImageLUT (OOP_Object *obj, UBYTE *pixels, ULONG modulo, WORD x, WORD y,
4082 WORD width, WORD height, HIDDT_PixelLUT *pixlut);
4085 hidd.graphics.bitmap
4110 *****************************************************************************************/
4112 VOID
BM__Hidd_BitMap__GetImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
4113 struct pHidd_BitMap_GetImageLUT
*msg
)
4116 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
4117 HIDDT_PixelLUT
*pixlut
= msg
->pixlut
;
4118 HIDDT_Pixel
*lut
= pixlut
? pixlut
->pixels
: NULL
;
4119 HIDDT_Pixel
*linebuf
;
4121 EnterFunc(bug("BitMap::GetImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
4122 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
4124 linebuf
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
4126 for(y
= 0; y
< msg
->height
; y
++)
4137 vHidd_StdPixFmt_Native32
);
4140 /* FIXME: This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway */
4141 for(x
= 0; x
< msg
->width
; x
++)
4143 pixarray
[x
] = (UBYTE
)linebuf
[x
];
4148 for(x
= 0; x
< msg
->width
; x
++)
4150 pixarray
[x
] = (UBYTE
)linebuf
[x
];
4153 pixarray
+= msg
->modulo
;
4155 } /* if (linebuf) */
4160 /* FIXME: This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway */
4161 for(x
= 0; x
< msg
->width
; x
++)
4163 pixarray
[x
] = (UBYTE
)HIDD_BM_GetPixel(o
, msg
->x
+ x
, msg
->y
+ y
);
4168 for(x
= 0; x
< msg
->width
; x
++)
4170 pixarray
[x
] = (UBYTE
)HIDD_BM_GetPixel(o
, msg
->x
+ x
, msg
->y
+ y
);
4174 pixarray
+= msg
->modulo
;
4176 } /* if (linebuf) else ... */
4178 } /* for(y = 0; y < msg->height; y++) */
4182 ReturnVoid("BitMap::GetImageLUT");
4185 /*****************************************************************************************
4188 moHidd_BitMap_BlitColorExpansion
4191 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BlitColorExpansion *msg);
4193 VOID HIDD_BM_BlitColorExpansion (OOP_Object *obj, OOP_Object *gc, OOP_Object *srcBitMap,
4194 WORD srcX, WORD srcY, WORD destX, WORD destY,
4195 UWORD width, UWORD height);
4198 hidd.graphics.bitmap
4201 Perform a color expansion of the mask in srcBitMap according to foreground and background
4202 colors and expansion mode specified by the supplied GC. Pixels which are set to zero in
4203 the mask bitmap will be either painted by background (in opaque mode) or left without
4204 change (in transparent mode). Pixels which are set to nonzero in the mask will be painted
4205 by foreground color.
4207 The result of expansion is blitted onto the destination bitmap accorging to GC's draw mode.
4210 obj - A bitmap to draw on
4211 gc - A GC object to use for drawing
4212 srcBitMap - A bitmap object containing mask image.
4213 srcX, srcY - A top-left coordinate of the used rectangle in the source bitmap
4214 destX, destY - A top-left coordinate of the destination rectangle to draw in
4215 width, height - A size of the rectangle to blit
4221 This method was previously used by graphics.library/Text() to draw fonts with no
4222 styles specified. Currently graphics.library always uses BltTemplate() and this
4223 method is considered obsolete.
4233 *****************************************************************************************/
4235 VOID
BM__Hidd_BitMap__BlitColorExpansion(OOP_Class
*cl
, OOP_Object
*o
,
4236 struct pHidd_BitMap_BlitColorExpansion
*msg
)
4243 OOP_Object
*gc
= msg
->gc
;
4245 EnterFunc(bug("BitMap::BlitColorExpansion(srcBM=%p, srcX=%d, srcY=%d, destX=%d, destY=%d, width=%d, height=%d)\n",
4246 msg
->srcBitMap
, msg
->srcX
, msg
->srcY
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
));
4248 cemd
= GC_COLEXP(gc
);
4252 /* bug("------------- Blit_ColExp: (%d, %d, %d, %d, %d, %d) cemd=%d, fg=%p, bg=%p -------------\n"
4253 , msg->srcX, msg->srcY, msg->destX, msg->destY, msg->width, msg->height
4256 for (y
= 0; y
< msg
->height
; y
++)
4258 for (x
= 0; x
< msg
->width
; x
++)
4262 /* Pixel value is either 0 or 1 for BM of depth 1 */
4263 is_set
= HIDD_BM_GetPixel(msg
->srcBitMap
, x
+ msg
->srcX
, y
+ msg
->srcY
);
4273 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->destX
, y
+ msg
->destY
);
4277 if (cemd
& vHidd_GC_ColExp_Opaque
)
4279 /* Write bixel with BG pen */
4281 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->destX
, y
+ msg
->destY
);
4282 /* Reset to FG pen */
4288 } /* for (each x) */
4292 } /* for ( each y ) */
4295 ReturnVoid("BitMap::BlitColorExpansion");
4298 /*****************************************************************************************
4301 moHidd_BitMap_BytesPerLine
4304 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BytesPerLine *msg);
4306 ULONG HIDD_BM_BytesPerLine(OOP_Object *obj, HIDDT_StdPixFmt pixFmt, UWORD width);
4309 hidd.graphics.bitmap
4312 This method is currently not used and reserved.
4331 *****************************************************************************************/
4333 ULONG
BM__Hidd_BitMap__BytesPerLine(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_BytesPerLine
*msg
)
4338 switch (msg
->pixFmt
)
4340 case vHidd_StdPixFmt_Native32
:
4341 bpl
= sizeof (HIDDT_Pixel
) * msg
->width
;
4344 case vHidd_StdPixFmt_Native
:
4346 struct HIDDBitMapData
*data
;
4348 data
= OOP_INST_DATA(cl
, o
);
4350 bpl
= ((HIDDT_PixelFormat
*)data
->prot
.pixfmt
)->bytes_per_pixel
* msg
->width
;
4357 struct HIDDBitMapData
*data
;
4359 data
= OOP_INST_DATA(cl
, o
);
4361 pf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
4365 D(bug("!!! COULD NOT GET STD PIXFMT IN BitMap::BytesPerLine() !!!\n"));
4369 bpl
= ((HIDDT_PixelFormat
*)pf
)->bytes_per_pixel
* msg
->width
;
4381 /****************************************************************************************/
4384 This makes it easier to create a subclass of the graphics hidd.
4385 It is only allowed to use this method in the p_RootNew method of a
4389 /****************************************************************************************/
4391 IPTR
BM__Root__Set(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_Set
*msg
)
4393 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
4394 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
4395 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
4396 struct TagItem
*tag
, *tstate
;
4398 WORD xoffset
, yoffset
;
4400 if (data
->framebuffer
)
4403 * If this is a framebuffer, we can process ModeID change.
4404 * We do it before parsing the rest of tags, because here we retrieve
4405 * defaults for new bitmap parameters (size and pixelformat).
4406 * They can be overridden by other tags. For example we can imagine
4407 * a hardware scrollable framebuffer whose width and height are larger
4408 * than visible part.
4410 HIDDT_ModeID modeid
= GetTagData(aHidd_BitMap_ModeID
, vHidd_ModeID_Invalid
, msg
->attrList
);
4411 OOP_Object
*sync
, *pixfmt
;
4413 if (HIDD_Gfx_GetMode(data
->gfxhidd
, modeid
, &sync
, &pixfmt
))
4415 data
->modeid
= modeid
;
4417 * Set defaults based on the ModeID.
4418 * They can be overriden lated, in SetBitMapTags.
4420 data
->width
= OOP_GET(sync
, aHidd_Sync_HDisp
);
4421 data
->height
= OOP_GET(sync
, aHidd_Sync_VDisp
);
4422 data
->bytesPerRow
= GetBytesPerRow(data
, CSD(cl
));
4423 data
->prot
.pixfmt
= pixfmt
;
4427 /* Bad ModeID given, request rejected */
4431 /* Process the rest of tags. */
4432 BM__Hidd_BitMap__SetBitMapTags(cl
, obj
, msg
->attrList
);
4437 * This is not a framebuffer.
4438 * We can modify size data (CHECKME: is it really used anywhere ?)
4439 * and also we can scroll (makes sense only if this is displayable
4440 * bitmap in mirrored framebuffer mode.
4442 BM__Hidd_BitMap__SetBitMapTags(cl
, obj
, msg
->attrList
);
4445 * And now we process position change.
4446 * One trick: we store our 'display' rectangle in bitmap's coordinates.
4447 * In other words, these are screen coordinates relative to bitmap, not
4448 * bitmap's ones relative to screen. As a result, we have to invert the sign.
4449 * This is done in order to simplify calculations in UpdateBitMap method of
4450 * graphics base class. It needs to perform intersection of update rectangle
4451 * with display rectangle, and they need to be in the same coordinate system
4452 * in order to be able to do this.
4453 * Update operation is performance-critical, so we perform this conversion
4454 * for display rectangle here.
4456 xoffset
= data
->display
.MinX
;
4457 yoffset
= data
->display
.MinY
;
4458 tstate
= msg
->attrList
;
4459 while ((tag
= NextTagItem(&tstate
)))
4461 Hidd_BitMap_Switch(tag
->ti_Tag
, idx
)
4463 case aoHidd_BitMap_LeftEdge
:
4464 xoffset
= tag
->ti_Data
;
4467 * Our bitmap cannot be smaller than display size because of fakegfx.hidd
4468 * limitations (it can't place cursor beyond bitmap edges). Otherwise Intuition
4469 * will provide strange user experience (mouse cursor will disappear)
4471 if (xoffset
>= (WORD
)data
->displayWidth
)
4472 xoffset
= data
->displayWidth
- 1;
4473 else if (xoffset
<= (WORD
)-data
->width
)
4474 xoffset
= -(data
->width
- 1);
4476 D(bug("[BitMap] xoffset requested %ld, got %d\n", -tag
->ti_Data
, xoffset
));
4479 case aoHidd_BitMap_TopEdge
:
4480 /* Only offsets that ensure at least some of the bitmap is
4482 yoffset
= tag
->ti_Data
;
4483 if (yoffset
>= (WORD
)data
->displayHeight
)
4484 yoffset
= data
->displayHeight
- 1;
4485 else if (yoffset
<= (WORD
)-data
->height
)
4486 yoffset
= -(data
->height
- 1);
4488 D(bug("[BitMap] yoffset requested %ld, got %d\n", -tag
->ti_Data
, yoffset
));
4493 if ((xoffset
!= data
->display
.MinX
) || (yoffset
!= data
->display
.MinY
))
4495 ObtainSemaphore(&data
->lock
);
4497 data
->display
.MinX
= xoffset
;
4498 data
->display
.MinY
= yoffset
;
4499 data
->display
.MaxX
= xoffset
+ data
->displayWidth
;
4500 data
->display
.MaxY
= yoffset
+ data
->displayHeight
;
4504 GFX__Hidd_Gfx__UpdateFB(CSD(cl
)->gfxhiddclass
, data
->gfxhidd
,
4505 obj
, data
->display
.MinX
, data
->display
.MinY
,
4506 0, 0, data
->displayWidth
, data
->displayHeight
);
4509 ReleaseSemaphore(&data
->lock
);
4513 /* There's no superclass above us */
4517 /*****************************************************************************************
4520 moHidd_BitMap_SetColorMap
4523 OOP_Object * OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetColorMap *msg);
4525 OOP_Object * HIDD_BM_SetColorMap(OOP_Object *obj, OOP_Object *colorMap);
4528 hidd.graphics.bitmap
4548 *****************************************************************************************/
4550 OOP_Object
*BM__Hidd_BitMap__SetColorMap(OOP_Class
*cl
, OOP_Object
*o
,
4551 struct pHidd_BitMap_SetColorMap
*msg
)
4553 struct HIDDBitMapData
*data
;
4556 data
= OOP_INST_DATA(cl
, o
);
4559 data
->colmap
= msg
->colorMap
;
4564 /*****************************************************************************************
4567 moHidd_BitMap_MapColor
4570 HIDDT_Pixel OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_MapColor *msg);
4572 HIDDT_Pixel HIDD_BM_MapColor(OOP_Object *obj, HIDDT_Color *color);
4575 hidd.graphics.bitmap
4595 *****************************************************************************************/
4597 /* We only care about magnitudes here, so we don't
4598 * have to perform the square root operation to get
4599 * the real distance.
4601 static ULONG
colorDistance(HIDDT_Color
*a
, HIDDT_Color
*b
)
4603 #define SQR(x) ((x) * (x))
4604 return SQR((int)a
->red
- (int)b
->red
) +
4605 SQR((int)a
->blue
- (int)b
->blue
) +
4606 SQR((int)a
->green
- (int)b
->green
) +
4607 SQR((int)a
->alpha
- (int)b
->alpha
);
4611 HIDDT_Pixel
BM__Hidd_BitMap__MapColor(OOP_Class
*cl
, OOP_Object
*o
,
4612 struct pHidd_BitMap_MapColor
*msg
)
4614 HIDDT_PixelFormat
*pf
= BM_PIXFMT(o
);
4616 HIDDT_Pixel red
= msg
->color
->red
;
4617 HIDDT_Pixel green
= msg
->color
->green
;
4618 HIDDT_Pixel blue
= msg
->color
->blue
;
4619 HIDDT_Pixel alpha
= msg
->color
->alpha
;
4621 /* This code assumes that sizeof(HIDDT_Pixel) is a multiple of sizeof(col->#?),
4622 which should be true for most (all?) systems. I have never heard
4623 of any system with for example 3 byte types.
4626 if (IS_TRUECOLOR(pf
))
4628 if (HIDD_PF_SWAPPIXELBYTES(pf
))
4630 /* FIXME: BM__Hidd_BitMap__MapColor assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats */
4632 HIDDT_Pixel pixel
= MAP_RGBA(red
, green
, blue
, alpha
, pf
);
4634 msg
->color
->pixval
= SWAPBYTES_WORD(pixel
);
4638 msg
->color
->pixval
= MAP_RGBA(red
, green
, blue
, alpha
, pf
);
4643 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
4645 HIDDT_ColorLUT
*cmap
;
4647 ULONG best_ndx
= ~0, best_dist
= ~0;
4649 cmap
= (HIDDT_ColorLUT
*)data
->colmap
;
4650 ctab
= cmap
->colors
;
4651 /* Search for the best match in the color table */
4652 for (i
= 0; i
< cmap
->entries
; i
++) {
4655 dist
= colorDistance(&ctab
[i
], msg
->color
);
4656 if (dist
< best_dist
) {
4662 if (best_dist
!= ~0)
4663 msg
->color
->pixval
= ctab
[best_ndx
].pixval
;
4666 return msg
->color
->pixval
;
4669 /*****************************************************************************************
4672 moHidd_BitMap_UnmapPixel
4675 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_UnmapPixel *msg);
4677 VOID HIDD_BM_UnmapPixel(OOP_Object *obj, HIDDT_Pixel pixel, HIDDT_Color *color);
4680 hidd.graphics.bitmap
4701 *****************************************************************************************/
4703 VOID
BM__Hidd_BitMap__UnmapPixel(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_UnmapPixel
*msg
)
4706 HIDDT_PixelFormat
*pf
= BM_PIXFMT(o
);
4708 if (IS_TRUECOLOR(pf
))
4710 HIDDT_Pixel pixel
= msg
->pixel
;
4712 if (HIDD_PF_SWAPPIXELBYTES(pf
))
4714 /* FIXME: bitmap_unmappixel assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats */
4715 pixel
= SWAPBYTES_WORD(pixel
);
4718 msg
->color
->red
= RED_COMP (pixel
, pf
);
4719 msg
->color
->green
= GREEN_COMP (pixel
, pf
);
4720 msg
->color
->blue
= BLUE_COMP (pixel
, pf
);
4721 msg
->color
->alpha
= ALPHA_COMP (pixel
, pf
);
4725 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
4726 HIDDT_ColorLUT
*clut
;
4728 clut
= (HIDDT_ColorLUT
*)data
->colmap
;
4732 /* FIXME: Use CLUT shift and CLUT mask here */
4733 if (msg
->pixel
< 0 || msg
->pixel
>= clut
->entries
)
4736 *msg
->color
= clut
->colors
[msg
->pixel
];
4740 /* Unnecessary, but... */
4741 msg
->color
->pixval
= msg
->pixel
;
4744 /*****************************************************************************************
4747 moHidd_BitMap_ObtainDirectAccess
4750 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_ObtainDirectAccess *msg);
4752 BOOL HIDD_BM_ObtainDirectAccess(OOP_Object *obj, UBYTE **addressReturn,
4753 ULONG *widthReturn, ULONG *heightReturn,
4754 ULONG *bankSizeReturn, ULONG *memSizeReturn);
4757 hidd.graphics.bitmap
4782 *****************************************************************************************/
4784 BOOL
BM__Hidd_BitMap__ObtainDirectAccess(OOP_Class
*cl
, OOP_Object
*o
,
4785 struct pHidd_BitMap_ObtainDirectAccess
*msg
)
4787 /* Default implementation of direct access funcs. Just return FALSE */
4791 /*****************************************************************************************
4794 moHidd_BitMap_ReleaseDirectAccess
4797 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_ReleaseDirectAccess *msg);
4799 VOID HIDD_BM_ReleaseDirectAccess(OOP_Object *obj);
4802 hidd.graphics.bitmap
4821 *****************************************************************************************/
4823 VOID
BM__Hidd_BitMap__ReleaseDirectAccess(OOP_Class
*cl
, OOP_Object
*o
,
4824 struct pHidd_BitMap_ReleaseDirectAccess
*msg
)
4826 D(bug("!!! BitMap BaseClasse ReleaseDirectAccess() called !!!\n"));
4827 D(bug("!!! This should never happen and is probably due to a buggy implementation in the subclass !!!\n"));
4832 /*****************************************************************************************
4835 moHidd_BitMap_BitMapScale
4838 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BitMapScale * msg);
4840 VOID HIDD_BM_BitMapScale(OOP_Object *obj, OOP_Object *src, OOP_Object *dest,
4841 struct BitScaleArgs * bsa, OOP_Object *gc);
4844 hidd.graphics.bitmap
4867 *****************************************************************************************/
4869 VOID
BM__Hidd_BitMap__BitMapScale(OOP_Class
* cl
, OOP_Object
*o
,
4870 struct pHidd_BitMap_BitMapScale
* msg
)
4872 struct BitScaleArgs
*bsa
= msg
->bsa
;
4873 ULONG
*srcbuf
, *dstbuf
;
4877 UWORD ys
= bsa
->bsa_SrcY
;
4878 UWORD xs
= bsa
->bsa_SrcX
;
4879 UWORD dyd
= bsa
->bsa_DestHeight
;
4880 UWORD dxd
= bsa
->bsa_DestWidth
;
4883 UWORD dxs
= bsa
->bsa_SrcWidth
;
4884 UWORD dys
= bsa
->bsa_SrcHeight
;
4885 LONG accuyd
= - (dys
>> 1);
4886 LONG accuxd
= - (dxs
>> 1);
4889 if ((srcbuf
= AllocVec(bsa
->bsa_SrcWidth
* sizeof(ULONG
), 0)) == NULL
)
4892 if ((dstbuf
= AllocVec(bsa
->bsa_DestWidth
* sizeof(ULONG
), 0)) == NULL
) {
4897 if ((linepattern
= (UWORD
*) AllocVec(bsa
->bsa_DestWidth
* sizeof(UWORD
), 0)) == NULL
) {
4904 while (count
< bsa
->bsa_DestWidth
) {
4906 while (accuxd
> accuxs
) {
4911 linepattern
[count
] = xs
;
4916 count
= bsa
->bsa_DestY
;
4917 while (count
< bsa
->bsa_DestHeight
+ bsa
->bsa_DestY
) {
4919 while (accuyd
> accuys
) {
4924 if (srcline
!= ys
) {
4925 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
);
4928 for (x
= 0; x
< bsa
->bsa_DestWidth
; x
++)
4929 dstbuf
[x
] = srcbuf
[linepattern
[x
]];
4932 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
);
4937 FreeVec(linepattern
);
4943 /*****************************************************************************************
4946 moHidd_BitMap_SetRGBConversionFunction
4949 HIDDT_RGBConversionFunction
4950 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetRGBConversionFunction *msg);
4952 HIDDT_RGBConversionFunction
4953 HIDD_BM_SetRGBConversionFunction(OOP_Object *obj, HIDDT_StdPixFmt srcPixFmt,
4954 HIDDT_StdPixFmt dstPixFmt,
4955 HIDDT_RGBConversionFunction function);
4958 hidd.graphics.bitmap
4976 *****************************************************************************************/
4978 HIDDT_RGBConversionFunction
BM__Hidd_BitMap__SetRGBConversionFunction(OOP_Class
* cl
, OOP_Object
*o
,
4979 struct pHidd_BitMap_SetRGBConversionFunction
* msg
)
4981 HIDDT_RGBConversionFunction old
;
4983 if ((msg
->srcPixFmt
< FIRST_RGB_STDPIXFMT
) ||
4984 (msg
->dstPixFmt
< FIRST_RGB_STDPIXFMT
) ||
4985 (msg
->srcPixFmt
> LAST_RGB_STDPIXFMT
) ||
4986 (msg
->dstPixFmt
> LAST_RGB_STDPIXFMT
))
4988 return (HIDDT_RGBConversionFunction
)-1;
4992 ObtainSemaphore(&CSD(cl
)->rgbconvertfuncs_sem
);
4993 old
= CSD(cl
)->rgbconvertfuncs
[msg
->srcPixFmt
- FIRST_RGB_STDPIXFMT
][msg
->dstPixFmt
- FIRST_RGB_STDPIXFMT
];
4994 CSD(cl
)->rgbconvertfuncs
[msg
->srcPixFmt
- FIRST_RGB_STDPIXFMT
][msg
->dstPixFmt
- FIRST_RGB_STDPIXFMT
] = msg
->function
;
4995 ReleaseSemaphore(&CSD(cl
)->rgbconvertfuncs_sem
);
5001 /*****************************************************************************************
5004 moHidd_BitMap_UpdateRect
5007 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_UpdateRect *msg);
5009 VOID HIDD_BM_UpdateRect(OOP_Object *obj, WORD x, WORD y, WORD width, WORD height);
5012 hidd.graphics.bitmap
5015 Update displayed image of the given rectangle.
5017 Some drivers (like VGA and VESA) may work not with VRAM directly, but with a mirrored
5018 copy of it. Usually it is done in case if VRAM reading is slow. This method is called
5019 by the system after it completes any drawing operation, in order to make sure that
5020 changes made are visible on the actual screen. If your driver uses mirroring, this method
5021 should copy the given rectangle (at least) from the mirror buffer to the actual VRAM.
5023 This method is also called after changing currently visible bitmap (after moHidd_Gfx_Show
5024 method call) in order to allow the mirroring driver to refresh the screen after current bitmap
5025 changed. Note that moHidd_Gfx_ShowViewPorts is very different and moHidd_BitMap_UpdateRect
5026 will not be called if it succeeded!
5029 obj - an object whose image to refresh
5030 x, y - A top-left edge of the rectangle to refresh
5031 width - Width of the rectangle to refresh
5032 height - Height of the rectangle to refresh
5038 This method is called also on offscreen bitmaps. You should track visible state of your bitmap
5039 and ignore these calls if it's not currently visible on the screen.
5049 *****************************************************************************************/
5051 VOID
BM__Hidd_BitMap__UpdateRect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_UpdateRect
*msg
)
5053 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
5055 DUPDATE(bug("[BitMap] UpdateRect(0x%p, %d, %d, %d, %d)\n", o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
));
5058 * We check data->visible twice in order to avoid unnecessary locking
5059 * when our bitmap is not on display (it may be not displayable at all).
5060 * However the second check is still needed in order to make sure that
5061 * this bitmap is still on display, because we could be preempted between
5062 * the test and ObtainSemaphoreShared() by concurrently running Show() call.
5063 * We use shared lock because it's safe to have two concurrently running
5064 * updates even on the same region.
5068 ObtainSemaphoreShared(&data
->lock
);
5073 * Complete update rectangle.
5074 * Display rectangle is already in bitmap's coordinates.
5076 UWORD srcX
= msg
->x
;
5077 UWORD srcY
= msg
->y
;
5078 UWORD xLimit
= srcX
+ msg
->width
;
5079 UWORD yLimit
= srcY
+ msg
->height
;
5081 /* Intersect rectangles */
5082 if (data
->display
.MinX
> srcX
)
5083 srcX
= data
->display
.MinX
;
5084 if (data
->display
.MinY
> srcY
)
5085 srcY
= data
->display
.MinY
;
5086 if (data
->display
.MaxX
< xLimit
)
5087 xLimit
= data
->display
.MaxX
;
5088 if (data
->display
.MaxY
< yLimit
)
5089 yLimit
= data
->display
.MaxY
;
5091 /* Update the intersection region, if any */
5092 if ((xLimit
> srcX
) && (yLimit
> srcY
))
5094 GFX__Hidd_Gfx__UpdateFB(CSD(cl
)->gfxhiddclass
, data
->gfxhidd
,
5096 srcX
- data
->display
.MinX
, srcY
- data
->display
.MinY
,
5097 xLimit
- srcX
, yLimit
- srcY
);
5101 ReleaseSemaphore(&data
->lock
);
5105 /****************************************************************************************/
5108 * Private methods follow.
5109 * They are implemented as non-virtual, for speed up.
5112 /* This is a private form of Set method. Doesn't need a standard message. */
5113 void BM__Hidd_BitMap__SetBitMapTags(OOP_Class
*cl
, OOP_Object
*o
, struct TagItem
*bitMapTags
)
5115 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
5116 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
5117 struct TagItem
*tag
;
5119 while ((tag
= NextTagItem(&bitMapTags
)))
5123 if (IS_BITMAP_ATTR(tag
->ti_Tag
, idx
))
5127 case aoHidd_BitMap_Width
:
5128 data
->width
= tag
->ti_Data
;
5131 case aoHidd_BitMap_Height
:
5132 data
->height
= tag
->ti_Data
;
5135 case aoHidd_BitMap_BytesPerRow
:
5136 data
->bytesPerRow
= tag
->ti_Data
;
5139 case aoHidd_BitMap_Compositable
:
5140 data
->compositable
= tag
->ti_Data
;
5141 if (data
->compositable
)
5143 HIDDT_ModeID compositmodeid
;
5144 struct Library
*OOPBase
= csd
->cs_OOPBase
;
5148 OOP_GetAttr(data
->friend, aHidd_BitMap_ModeID
, &compositmodeid
);
5151 compositmodeid
= data
->modeid
;
5153 if (compositmodeid
== vHidd_ModeID_Invalid
)
5155 data
->compositable
= FALSE
;
5159 OOP_Object
*sync
, *pf
;
5161 if (!HIDD_Gfx_GetMode(data
->gfxhidd
, compositmodeid
, &sync
, &pf
))
5163 data
->compositable
= FALSE
;
5167 /* Get display size from the modeid */
5168 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &data
->displayWidth
);
5169 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &data
->displayHeight
);
5170 data
->display
.MaxX
= data
->displayWidth
;
5171 data
->display
.MaxY
= data
->displayHeight
;
5173 D(bug("[BitMap] Bitmap %dx%d, display %dx%d\n",
5174 data
->width
, data
->height
,
5175 data
->displayWidth
, data
->displayHeight
));
5185 * Updates bitmap's pixelformat.
5186 * Used from within planarbm subclass, and would be extremely dangerous to expose
5187 * as setable aHidd_BitMap_PixFmt, so implemented as a separate method.
5189 void BM__Hidd_BitMap__SetPixFmt(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*pf
)
5191 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
5193 /* Already a pixfmt registered? */
5194 if (data
->pf_registered
)
5195 GFX__Hidd_Gfx__ReleasePixFmt(CSD(cl
)->gfxhiddclass
, data
->prot
.pixfmt
);
5197 /* Remember the new pixelformat */
5198 data
->prot
.pixfmt
= pf
;
5201 * This pixelformat was obtained using GFX__Hidd_Gfx__RegisterPixFmt().
5202 * It increases number of pixfmt users, so we'll need to release it when
5203 * not used any more.
5205 data
->pf_registered
= TRUE
;
5209 * Change visible state of the bitmap.
5210 * Used in mirrored framebuffer mode. Actually needed because
5211 * of semaphore barrier, which makes sure that bitmap state does
5212 * not change during scrolling or updating operation. Prevents possibilities
5213 * of screen corruption during concurrently running scrolling with Show.
5215 void BM__Hidd_BitMap__SetVisible(OOP_Class
*cl
, OOP_Object
*o
, BOOL val
)
5217 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
5219 ObtainSemaphore(&data
->lock
);
5220 data
->visible
= val
;
5221 ReleaseSemaphore(&data
->lock
);