2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
5 Desc: Gfx BitMap class implementation.
9 /****************************************************************************************/
11 #include "gfx_debug.h"
13 #include <aros/debug.h>
14 #include <proto/exec.h>
15 #include <proto/utility.h>
16 #include <proto/oop.h>
17 #include <exec/memory.h>
18 #include <utility/tagitem.h>
20 #include <oop/static_mid.h>
21 #include <graphics/text.h>
22 #include <graphics/scale.h>
28 #include "gfx_intern.h"
30 /****************************************************************************************/
32 #define POINT_OUTSIDE_CLIP(gc, x, y) \
33 ( (x) < GC_CLIPX1(gc) \
34 || (x) > GC_CLIPX2(gc) \
35 || (y) < GC_CLIPY1(gc) \
36 || (y) > GC_CLIPY2(gc) )
38 /*****************************************************************************************
47 Every display driver should implement at least one bitmap class for displayable
50 Normally this class doesn't need to have public ID. In order to use it the driver
51 should pass class pointer as aoHidd_BitMap_ClassPtr value to the graphics base class
52 in its moHidd_Gfx_CreateObject implementation.
54 BitMap base class is in C++ terminology a pure virtual
55 baseclass. It will not allocate any bitmap data at all;
56 that is up to the subclass to do.
58 The main task of the BitMap baseclass is to store some information about the bitmap
59 like its size and pixelformat. A pixelformat is an object of private class which
60 stores the actual information about the format.
62 There are two ways that we can find out the pixfmt in our moHidd_Gfx_CreateObject
66 The tags will contain a modeid.
67 One can use this modeid to get a pointer to an
68 already registered pixfmt.
70 Non-displayable bitmap -
71 The aoHidd_BitMap_StdPixFmt or aoHidd_BitMap_Friend attribute will always be
74 *****************************************************************************************/
76 #define PIXBUFBYTES 16384
78 static BOOL
DoBufferedOperation(OOP_Class
*cl
, OOP_Object
*o
, UWORD startx
, UWORD starty
, UWORD width
, UWORD height
,
79 BOOL getimage
, HIDDT_StdPixFmt stdpf
, VOID_FUNC operation
, void *userdata
)
81 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
82 ULONG bytesperline
= width
* sizeof(ULONG
);
83 UWORD buflines
= PIXBUFBYTES
/ 4; /* Remove slow division */
85 UWORD endy
= starty
+ height
;
91 else if (buflines
> height
)
94 bufsize
= buflines
* bytesperline
;
95 buf
= AllocMem(bufsize
, MEMF_PUBLIC
);
96 if (!buf
&& (buflines
> 1))
98 /* Try to allocate single-line buffer */
100 bufsize
= bytesperline
;
101 buf
= AllocMem(bufsize
, MEMF_PUBLIC
);
106 for (y
= starty
; y
< endy
; y
+= buflines
)
108 if (y
+ buflines
> endy
)
110 /* This prevents overflow on last pass, buffer may be used only partially */
116 /* For some operations this can be optimized away */
117 HIDD_BM_GetImage(o
, buf
, bytesperline
, startx
, y
, width
, buflines
, stdpf
);
120 operation(buf
, y
, width
, buflines
, userdata
);
122 HIDD_BM_PutImage(o
, data
->gc
, buf
, bytesperline
, startx
, y
, width
, buflines
, stdpf
);
125 FreeMem(buf
, bufsize
);
129 /*****************************************************************************************
141 Specifies bitmap width in pixels.
143 Setting this attribute does not cause actual bitmap resize, just updates the information
144 about it. Use this only from within subclasses only if you know what you do. For example
145 SDL hosted driver sets it when framebufer changes the resolution.
158 *****************************************************************************************/
160 /*****************************************************************************************
172 Specifies bitmap height in pixels.
174 Setting this attribute does not cause actual bitmap resize, just updates the information
175 about it. Use this only from within subclasses only if you know what you do. For example
176 SDL hosted driver sets it when framebufer changes the resolution.
189 *****************************************************************************************/
191 /*****************************************************************************************
194 aoHidd_BitMap_Displayable
203 The bitmap is displayable. A displayable bitmap is always managed by a display
204 driver and must have valid display mode ID specification.
206 If this attribute is not supplied during bitmap creation, its value defaults
220 *****************************************************************************************/
222 /*****************************************************************************************
225 aoHidd_BitMap_Visible
234 Check if the bitmap is currently visible on screen
241 Not all display drivers implement this attribute. No AROS components currently rely
247 Some drivers may choose to have this attribute internally setable. Do not rely on it
248 in any way and do not attempt to set it manually from within applications, this will
249 not do any nice things.
251 *****************************************************************************************/
253 /*****************************************************************************************
256 aoHidd_BitMap_IsLinearMem
265 Check if the bitmap provides linear memory access. This means that bitmap's
266 pixelbuffer is directly addressable by the CPU.
268 Bitmaps with no linear memory may implement moHidd_BitMap_ObtainDirectAccess,
269 but this means that this method will rely on mirrored buffer. In such a case
270 the user must call moHidd_BitMap_UpdateRect after modifying bitmap's contents.
273 Used by cybergraphics.library/GetCyberMapAttr() for providing CYBRMATTR_ISLINEARMEM
279 Currently no display drivers implement this attribute despite many native mode
280 drivers actually provide linear memory.
283 moHidd_BitMap_ObtainDirectAccess, moHidd_BitMap_ReleaseDirectAccess,
284 moHidd_BitMap_UpdateRect
288 *****************************************************************************************/
290 /*****************************************************************************************
293 aoHidd_BitMap_BytesPerRow
302 Specify or query number of bytes per row in the bitmap storage buffer.
304 Setting this attribute doesn't actually cause changing buffer layout, just updates
305 the information about it. Use this only from within subclasses and only if you
306 exactly know why you do this.
308 Specifying this attribute during object creation overrides the value calculated
309 based on aoHidd_BitMap_Width and aoHidd_BitMap_Align values. Useful for wrapping
310 own buffers into bitmap objects, for example, in conjunction with
311 aoHidd_ChunkyBM_Buffer.
314 The returned value includes possible padding needed for alignment.
325 *****************************************************************************************/
327 /*****************************************************************************************
330 aoHidd_BitMap_ColorMap
339 Return associated colormap (palette) object.
341 By default only displayable bitmaps have colormaps. However a colormap can be attached
342 to any bitmap using moHidd_BitMap_SetColors or moHidd_BitMap_SetColorMap.
344 Note that manual attaching of a colormap to a nondisplayable bitmap may cause undesired
345 side-effects on graphics.library behavior. It's better not to do this at all. The system
346 knows what it does better than you.
355 moHidd_BitMap_SetColorMap, moHidd_BitMap_SetColors.
359 *****************************************************************************************/
361 /*****************************************************************************************
373 Specify a friend bitmap. The bitmap will be allocated so that it
374 is optimized for blitting to this bitmap.
376 Display drivers may query this attribute and then query friend bitmap
377 for anything they want (like pixelformat, mode ID, etc).
379 Note that explicit specification of mode ID and/or standard pixelformat
380 should override defaults provided by friend bitmap (i.e. actually breaking
393 *****************************************************************************************/
395 /*****************************************************************************************
398 aoHidd_BitMap_GfxHidd
407 Specify display driver object this bitmap was created with.
409 Normally the user doesn't have to supply this attribute. Instead you should use
410 driver's moHidd_Gfx_CreateObject method in order to create bitmaps. In this case
411 aoHidd_BitMap_GfxHidd attribute will be provided by graphics driver base class
412 with the correct value.
414 It is illegal to manually create bitmap objects with no driver associated.
415 graphics.library maintains at least a memory driver for nondisplayable
416 bitmaps in system RAM without any acceleration.
425 CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
429 *****************************************************************************************/
431 /*****************************************************************************************
434 aoHidd_BitMap_StdPixFmt
437 [I..], HIDDT_StdPixFmt
443 Specify standard pixelformat code (one of vHidd_StdPixFmt_... values) for the
446 Values less than num_Hidd_PseudoStdPixFmt are illegal for this attribute.
448 The bitmap class itself ignores this attribute. It is processed by
449 CLID_Hidd_Gfx/moHidd_Gfx_CreateObject method in order to look up a corresponding
450 pixelformat object in the system's database.
453 Bitmaps with this attribute set should be created as RAM bitmaps with direct CPU
454 access. It is not recommended to replace them with, for example, virtual surfaces on
455 hosted AROS. Such bitmaps are expected to be directly addressable and breaking
456 this may cause undesired side effects.
463 aoHidd_BitMap_PixFmt, CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
466 Currently all display drivers omit specifying own bitmap class for bitmaps with this
467 attribute set, letting base class (actually memory driver) to select an appropriate
468 class for it. This way it ends up in a bitmap of CLID_Hidd_ChunkyBM or CLID_Hidd_PlanarBM
469 class. It is recommended to follow this rule. It's not prohibited, however, to do some
470 adjustments to the bitmap (like alignment) in order to optimize blitting to/from it.
471 In fact if the display driver was asked to create such a bitmap, this means that
472 the standard bitmap is being created as a friend of some bitmap which was allocated
473 using this driver. This way the bitmap is expected to be friendly to this driver.
475 *****************************************************************************************/
477 /*****************************************************************************************
489 Specify or query pixelformat descriptor object associated with the bitmap.
491 Every bitmap has some associated pixelformat object. Pixelformat objects are
492 shared data storages, so many bitmaps may refer to the same pixelformat objects.
495 This attribute is internally specified during bitmap creation, but it's illegal
496 to do this for the user. CreateObject method of graphics driver performs an explicit
497 check against this. It's up to graphics base classes to figure out its value.
507 *****************************************************************************************/
509 /*****************************************************************************************
521 Specify display mode ID for displayable bitmap.
523 A displayable bitmap must have this attribute supplied with valid value. A nondisplayable
524 one may miss it, however it may remember it if it was created as a friend of displayable
525 one. This way you may create another displayable bitmap as a friend of nondisplayable
526 one which in turn is a friend of displayable one.
528 This attribute can be set on a framebuffer bitmap. Doing so means an explicit request
529 for the driver to change current display mode on the hardware. Dependent parameters
530 (width, height and pixelformat) will be automatically adjusted, if not explicitly
531 specified in the attributes list.
534 If the given ModeID is not supported, the operation causes an error. You can check
535 for this by checking return value of OOP_SetAttrs() function. It will be TRUE in
536 case of success and FALSE upon failure. In case of failure none of bitmap attributes
547 *****************************************************************************************/
549 /*****************************************************************************************
552 aoHidd_BitMap_ClassPtr
561 Explicitly specify bitmap's class pointer.
563 This attribute is not actually a bitmap's attribute. Your display driver class can
564 supply it to base class' moHidd_Gfx_CreateObject method in order to select a class on
565 which to call OOP_NewObject().
567 If neither this attribute nor aoHidd_BitMap_ClassID attribute is provided for
568 moHidd_Gfx_CreateObject, graphics base class will do its best in order to find out the
569 correct class based on aoHidd_StdPixFmt attribute value or friend bitmap.
572 If a friend bitmap is given, the new bitmap will have the same class, if your driver
573 doesn't override it by supplying explicit class specification (using either
574 aoHidd_BitMap_ClassPtr or aoHidd_BitMap_ClassID attribute).
581 aoHidd_BitMap_ClassID, CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
585 *****************************************************************************************/
587 /*****************************************************************************************
590 aoHidd_BitMap_ClassID
599 Explicitly specify bitmap's class ID.
601 The purpose of this attribute is to let graphics driver base class to select a class
602 on which to call OOP_NewObject() in its moHidd_Gfx_CreateObject implementation.
604 If neither this attribute nor aoHidd_BitMap_ClassPtr attribute is provided for
605 moHidd_Gfx_CreateObject, graphics base class will do its best in order to find out the
606 correct class based on aoHidd_StdPixFmt attribute value or aoHidd_BitMap_ClassPtr value
614 The pointer to a given class will not be remembered as aoHidd_BitMap_ClassPtr value.
617 aoHidd_BitMap_ClassPtr, CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
621 *****************************************************************************************/
623 /*****************************************************************************************
626 aoHidd_BitMap_PixFmtTags
635 Private, very obsolete and currently has no function. Considered reserved.
647 *****************************************************************************************/
649 /*****************************************************************************************
652 aoHidd_BitMap_FrameBuffer
661 Specifies that the bitmap is a framebuffer bitmap.
663 A detailed description of a framebuffer is given in CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
664 and in CLID_Hidd_Gfx/moHidd_Gfx_Show documentation.
666 Specifying this attribute causes also implicit setting of aoHidd_BitMap_Displayable
679 *****************************************************************************************/
681 /*****************************************************************************************
684 aoHidd_BitMap_LeftEdge
693 Controls horizontal position of a scrollable screen bitmap.
695 Size of displayable bitmaps may differ from actual screen size. In this case the
696 bitmap can be scrolled around the whole display area. If the bitmap is larger than
697 the display, only its part can be visible.
699 Setting this attribute causes changing left origin point of the bitmap. The value
700 of this attribute represents an offset from the physical edge of the display to the
701 logical edge of the bitmap. This means that if a large bitmap scrolls to the left in
702 order to reveal its right part, the offset will be negative. If the bitmap scrolls
703 to the left (possibly revealing another bitmap behind it), the offset will be positive.
705 It's up to the display driver to set scroll limits. If the value of the attribute
706 becomes unacceptable for any reason, the driver should adjust it and provide the real
707 resulting value back.
710 Implementing screen scrolling does not enforce to implement screen composition, despite
711 the composition is really based on scrolling (in case of composition scrolling a bitmap
712 off-display is expected to reveal another bitmap behind it instead of empty space).
719 aoHidd_BitMap_TopEdge
722 Base class will always provide zero value for this attribute and ignore all attempts
723 to set it. This means that by default bitmaps don't scroll and this needs explicit
724 implementation in the display driver.
726 *****************************************************************************************/
728 /*****************************************************************************************
731 aoHidd_BitMap_TopEdge
740 Controls vertical position of a scrollable screen bitmap.
742 Size of displayable bitmaps may differ from actual screen size. In this case the
743 bitmap can be scrolled around the whole display area. If the bitmap is larger than
744 the display, only its part can be visible.
746 Setting this attribute causes changing top origin point of the bitmap. The value
747 of this attribute represents an offset from the physical edge of the display to the
748 logical edge of the bitmap. This means that if a large bitmap scrolls upwards in
749 order to reveal its bottom part, the offset will be negative. If the bitmap scrolls
750 downwards (possibly revealing another bitmap behind it), the offset will be positive.
752 It's up to the display driver to set scroll limits. If the value of the attribute
753 becomes unacceptable for any reason, the driver should adjust it and provide the real
754 resulting value back.
757 Implementing screen scrolling does not enforce to implement screen composition, despite
758 the composition is really based on scrolling (in case of composition scrolling a bitmap
759 off-display is expected to reveal another bitmap behind it instead of empty space).
769 *****************************************************************************************/
771 /*****************************************************************************************
783 Specify number of pixels to align bitmap data width to.
785 This attribute can be added in order to enforce alignment needed for example by
786 blitting hardware. It will have an impact on default aoHidd_BitMap_BytesPerRow
789 Direct specification of aoHidd_BitMap_BytesPerRow attribute overrides any value
793 Default value of this attribute is 16. This alignment is required by graphics.library
794 for AmigaOS(tm) compatibility reasons.
801 aoHidd_BitMap_BytesPerRow
805 *****************************************************************************************/
807 /*****************************************************************************************
819 Specify or query the actual bitmap depth.
821 This a convenience attribute to simplify handling planar bitmaps, whose actual depth
822 may vary. Default implementation in base class simply returns depth of bitmap's
823 pixelformat, and is ignored during initialization. Planar bitmap class returns the
824 actual depth here. If your specific bitmap class also operates on bitmaps with variable
825 depths, you need to implement this attribute in it.
837 *****************************************************************************************/
839 /****************************************************************************************/
844 * Calculate suggested bytes per row value based on bitmap's default alignment
845 * and pixelformat's bytes per pixel value.
847 static ULONG
GetBytesPerRow(struct HIDDBitMapData
*data
, struct class_static_data
*csd
)
849 struct Library
*OOPBase
= csd
->cs_OOPBase
;
850 UWORD align
= data
->align
- 1;
851 UWORD width
= (data
->width
+ align
) & ~align
;
852 IPTR bytesperpixel
, stdpf
;
854 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_BytesPerPixel
, &bytesperpixel
);
855 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_StdPixFmt
, &stdpf
);
857 if (stdpf
== vHidd_StdPixFmt_Plane
)
860 * Planar format actually have 8 pixels per one byte.
861 * However bytesperpixel == 1 for them. Perhaps this should
868 return width
* bytesperpixel
;
874 OOP_Object
*BM__Root__New(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_New
*msg
)
876 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
877 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
879 EnterFunc(bug("BitMap::New()\n"));
881 obj
= (OOP_Object
*)OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
) msg
);
885 struct TagItem colmap_tags
[] =
887 { aHidd_ColorMap_NumEntries
, 16 },
890 struct TagItem
*tag
, *tstate
;
892 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
894 /* Set some default values */
895 data
->modeid
= vHidd_ModeID_Invalid
;
898 data
->compositable
= FALSE
;
900 tstate
= msg
->attrList
;
901 while ((tag
= NextTagItem(&tstate
)))
905 if (IS_BITMAP_ATTR(tag
->ti_Tag
, idx
))
909 case aoHidd_BitMap_BMStruct
:
910 data
->bmstruct
= (struct BitMap
*)tag
->ti_Data
;
913 case aoHidd_BitMap_Width
:
914 data
->width
= tag
->ti_Data
;
917 case aoHidd_BitMap_Height
:
918 data
->height
= tag
->ti_Data
;
921 case aoHidd_BitMap_Align
:
922 data
->align
= tag
->ti_Data
;
925 case aoHidd_BitMap_BytesPerRow
:
926 data
->bytesPerRow
= tag
->ti_Data
;
929 case aoHidd_BitMap_GfxHidd
:
930 data
->gfxhidd
= (OOP_Object
*)tag
->ti_Data
;
933 case aoHidd_BitMap_Friend
:
934 data
->friend = (OOP_Object
*)tag
->ti_Data
;
937 case aoHidd_BitMap_Displayable
:
938 data
->displayable
= tag
->ti_Data
;
941 case aoHidd_BitMap_Compositable
:
942 data
->compositable
= tag
->ti_Data
;
945 case aoHidd_BitMap_FrameBuffer
:
946 data
->framebuffer
= tag
->ti_Data
;
949 case aoHidd_BitMap_ModeID
:
950 data
->modeid
= tag
->ti_Data
;
953 case aoHidd_BitMap_PixFmt
:
954 data
->prot
.pixfmt
= (OOP_Object
*)tag
->ti_Data
;
960 /* aoHidd_BitMap_GfxHidd is mandatory */
963 D(bug("!!!! BM CLASS DID NOT GET GFX HIDD !!!\n"));
964 D(bug("!!!! The reason for this is that the gfxhidd subclass CreateObject() method\n"));
965 D(bug("!!!! has not left it to the baseclass to actually create the object,\n"));
966 D(bug("!!!! but rather done it itself. This MUST be corrected in the gfxhidd subclass\n"));
971 /* FrameBuffer implies Displayable */
972 if (data
->framebuffer
)
973 data
->displayable
= TRUE
;
975 if (ok
&& (data
->displayable
|| data
->compositable
))
977 HIDDT_ModeID bmmodeid
= data
->modeid
;
979 /* We should always get modeid, but we check anyway */
980 if ((data
->compositable
) && (data
->friend))
982 OOP_GetAttr(data
->friend, aHidd_BitMap_ModeID
, &bmmodeid
);
983 D(bug("!!! BitMap:New() Using Friends ModeID - 0x%08X !!!\n", bmmodeid
));
986 if (bmmodeid
== vHidd_ModeID_Invalid
)
988 D(bug("!!! BitMap:New() NO VALID MODEID SPECIFIED FOR DISPLAYABLE BITMAP !!!\n"));
989 data
->compositable
= ok
= FALSE
;
993 OOP_Object
*sync
, *pf
;
995 if (!HIDD_Gfx_GetMode(data
->gfxhidd
, bmmodeid
, &sync
, &pf
))
997 D(bug("!!! BitMap::New() RECEIVED INVALID MODEID 0x%08X\n", bmmodeid
));
998 data
->compositable
= ok
= FALSE
;
1002 /* Get display size from the modeid */
1003 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &data
->displayWidth
);
1004 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &data
->displayHeight
);
1005 data
->display
.MaxX
= data
->displayWidth
;
1006 data
->display
.MaxY
= data
->displayHeight
;
1008 /* Update the missing bitmap data */
1010 data
->width
= data
->displayWidth
;
1012 data
->height
= data
->displayHeight
;
1014 D(bug("[BitMap] Bitmap %dx%d, display %dx%d\n",
1015 data
->width
, data
->height
,
1016 data
->displayWidth
, data
->displayHeight
));
1018 if (!data
->prot
.pixfmt
)
1020 /* The PixFmt is allready registered and locked in the PixFmt database */
1021 data
->prot
.pixfmt
= pf
;
1029 /* * PixFmt will be NULL in case of e.g. planarbm late initialization. */
1030 if (data
->prot
.pixfmt
)
1032 ULONG bytesPerRow
= GetBytesPerRow(data
, CSD(cl
));
1034 if (data
->bytesPerRow
)
1036 /* If we have user-supplied BytesPerRow value, make sure it's suitable */
1037 if (data
->bytesPerRow
< bytesPerRow
)
1042 /* Otherwise we have what we calculated */
1043 data
->bytesPerRow
= bytesPerRow
;
1050 InitSemaphore(&data
->lock
);
1052 /* Cache default GC */
1053 OOP_GetAttr(data
->gfxhidd
, aHidd_Gfx_DefaultGC
, (IPTR
*)&data
->gc
);
1056 * Initialize the direct method calling.
1057 * We don't check against errors because our base class contains all
1060 #if USE_FAST_PUTPIXEL
1061 data
->putpixel
= OOP_GetMethod(obj
, HiddBitMapBase
+ moHidd_BitMap_PutPixel
, &data
->putpixel_Class
);
1063 #if USE_FAST_GETPIXEL
1064 data
->getpixel
= OOP_GetMethod(obj
, HiddBitMapBase
+ moHidd_BitMap_GetPixel
, &data
->getpixel_Class
);
1066 #if USE_FAST_DRAWPIXEL
1067 data
->drawpixel
= OOP_GetMethod(obj
, HiddBitMapBase
+ moHidd_BitMap_DrawPixel
, &data
->drawpixel_Class
);
1071 * Try to create the colormap.
1073 * stegerg: Only add a ColorMap for a visible bitmap (screen). This
1074 * is important because one can create for example a bitmap
1075 * in PIXFMT_LUT8 without friend bitmap and then copy this
1076 * bitmap to a 16 bit screen. During copy the screen bitmap
1077 * CLUT must be used, which would not happen if our PIXFMT_LUT8
1078 * also had a colormap itself because then bltbitmap would use the
1079 * colormap of the PIXFMT_LUT8 bitmap as lookup, which in this
1080 * case would just cause everything to become black in the
1081 * destination (screen) bitmap, because noone ever sets up the
1082 * colormap of the PIXFMT_LUT8 bitmap
1084 * sonic: CHECKME: Why does the colormap always have 16 colors? May be calculate this
1085 * based on depth ? The colormap auto-enlarges itself if SetColors method requests
1086 * missing entries, but is it so good?
1089 if (data
->displayable
)
1091 data
->colmap
= OOP_NewObject(NULL
, CLID_Hidd_ColorMap
, colmap_tags
);
1092 if (NULL
== data
->colmap
)
1100 ULONG dispose_mid
= OOP_GetMethodID(IID_Root
, moRoot_Dispose
);
1102 OOP_CoerceMethod(cl
, obj
, &dispose_mid
);
1107 } /* if (NULL != obj) */
1109 ReturnPtr("BitMap::New", OOP_Object
*, obj
);
1112 /****************************************************************************************/
1114 void BM__Root__Dispose(OOP_Class
*cl
, OOP_Object
*obj
, OOP_Msg
*msg
)
1116 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
1117 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
1119 EnterFunc(bug("BitMap::Dispose()\n"));
1121 if (NULL
!= data
->colmap
)
1122 OOP_DisposeObject(data
->colmap
);
1124 D(bug("Calling super\n"));
1126 /* Release the previously registered pixel format */
1127 if (data
->pf_registered
)
1128 GFXHIDD__Hidd_Gfx__ReleasePixFmt(CSD(cl
)->gfxhiddclass
, data
->prot
.pixfmt
);
1130 OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
) msg
);
1132 ReturnVoid("BitMap::Dispose");
1135 /****************************************************************************************/
1137 VOID
BM__Root__Get(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_Get
*msg
)
1139 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
1142 EnterFunc(bug("BitMap::Get() attrID: %i storage: %p\n", msg
->attrID
, msg
->storage
));
1144 if (IS_BITMAP_ATTR(msg
->attrID
, idx
))
1148 case aoHidd_BitMap_BMStruct
:
1149 *msg
->storage
= (IPTR
)data
->bmstruct
;
1152 case aoHidd_BitMap_Width
:
1153 *msg
->storage
= data
->width
;
1154 D(bug(" width: %i\n", data
->width
));
1157 case aoHidd_BitMap_Height
:
1158 *msg
->storage
= data
->height
;
1161 case aoHidd_BitMap_Depth
:
1163 * Generally our bitmaps have a fixed depth, which depends on pixelformat.
1164 * If this is not true for your bitmap, overload aoHidd_BitMap_Depth in your class.
1166 *msg
->storage
= ((HIDDT_PixelFormat
*)data
->prot
.pixfmt
)->depth
;
1169 case aoHidd_BitMap_Displayable
:
1170 *msg
->storage
= data
->displayable
;
1173 case aoHidd_BitMap_FrameBuffer
:
1174 *msg
->storage
= data
->framebuffer
;
1177 case aoHidd_BitMap_PixFmt
:
1178 *msg
->storage
= (IPTR
)data
->prot
.pixfmt
;
1181 case aoHidd_BitMap_Friend
:
1182 *msg
->storage
= (IPTR
)data
->friend;
1185 case aoHidd_BitMap_ColorMap
:
1186 *msg
->storage
= (IPTR
)data
->colmap
;
1189 case aoHidd_BitMap_GfxHidd
:
1190 *msg
->storage
= (IPTR
)data
->gfxhidd
;
1193 case aoHidd_BitMap_ModeID
:
1194 *msg
->storage
= data
->modeid
;
1197 case aoHidd_BitMap_Align
:
1198 *msg
->storage
= data
->align
;
1201 case aoHidd_BitMap_BytesPerRow
:
1202 *msg
->storage
= data
->bytesPerRow
;
1205 case aoHidd_BitMap_Visible
:
1206 /* Framebuffer is always visible */
1207 *msg
->storage
= data
->framebuffer
? TRUE
: data
->visible
;
1210 case aoHidd_BitMap_Compositable
:
1211 *msg
->storage
= (IPTR
)data
->compositable
;
1215 * The following two are stored with inverted sign!
1216 * Verbose explanation is in Set method.
1218 case aoHidd_BitMap_LeftEdge
:
1219 *msg
->storage
= -data
->display
.MinX
;
1222 case aoHidd_BitMap_TopEdge
:
1223 *msg
->storage
= -data
->display
.MinY
;
1226 D(default: bug("UNKNOWN ATTR IN BITMAP BASECLASS: %d\n", idx
);)
1230 OOP_DoSuperMethod(cl
, obj
, &msg
->mID
);
1231 ReturnVoid("BitMap::Get");
1234 /****************************************************************************************/
1236 #define UB(x) ((UBYTE *)x)
1238 /*****************************************************************************************
1241 moHidd_BitMap_SetColors
1244 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetColors *msg);
1246 BOOL HIDD_BM_SetColors (OOP_Object *obj, HIDDT_Color *colors,
1247 UWORD firstColor, UWORD numColors);
1253 Sets values for one or more colors in the colormap object associated with the
1256 The colormap will be created if it does not exist.
1258 Only ARGB values from the source array are taken into account. pixval member is
1259 updated with the real pixel value for every color.
1262 obj - A bitmap object whose colormap needs to be set
1263 colors - A pointer to source data array
1264 firstColor - Number of the first color to set
1265 numColors - Number of subsequent colors to set
1268 TRUE on success, FALSE in case of some error (like out of memory)
1277 CLID_Hidd_ColorMap/moHidd_ColorMap_SetColors
1281 *****************************************************************************************/
1283 BOOL
BM__Hidd_BitMap__SetColors(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_SetColors
*msg
)
1285 /* Copy the colors into the internal buffer */
1286 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
1287 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
1290 /* Subclass has initialized HIDDT_Color->pixelVal field and such.
1291 Just copy it into the colortab.
1294 if (NULL
== data
->colmap
)
1296 struct TagItem colmap_tags
[] =
1298 { aHidd_ColorMap_NumEntries
, 0 },
1302 colmap_tags
[0].ti_Data
= msg
->firstColor
+ msg
->numColors
;
1303 data
->colmap
= OOP_NewObject(NULL
, CLID_Hidd_ColorMap
, colmap_tags
);
1306 if (NULL
== data
->colmap
)
1311 /* Use the colormap class to set the colors */
1312 if (!HIDD_CM_SetColors(data
->colmap
, msg
->colors
,
1313 msg
->firstColor
, msg
->numColors
,
1319 /* We may need to duplicate changes on framebuffer if running in mirrored mode */
1322 ObtainSemaphoreShared(&data
->lock
);
1326 ret
= GFXHIDD__Hidd_Gfx__SetFBColors(CSD(cl
)->gfxhiddclass
, data
->gfxhidd
, msg
);
1329 ReleaseSemaphore(&data
->lock
);
1335 /*******************************************************************************
1338 moHidd_BitMap_PutPixel
1341 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutPixel *msg);
1343 VOID HIDD_BM_PutPixel(OOP_Object *obj, WORD x, WORD y,
1350 Sets a new color value for the pixel at (x,y). The actual color stored
1351 may be an approximation, due to the limited color depth or palette size
1352 of the bitmap. This function does not check the coordinates.
1355 obj - bitmap to write to.
1356 x, y - coordinates of the pixel to write.
1357 pixel - the pixel's new color value.
1372 *******************************************************************************/
1374 /* PutPixel must be implemented in a subclass */
1376 /*****************************************************************************************
1379 moHidd_BitMap_DrawPixel
1382 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPixel *msg);
1384 VOID HIDD_BM_DrawPixel(OOP_Object *obj, OOP_Object *gc, WORD x, WORD y);
1390 Changes the pixel at (x,y). The color of the pixel depends on the
1391 attributes of gc, eg. colors, drawmode, colormask etc.
1392 This function does not check the coordinates.
1395 obj - A bitmap to draw on
1396 gc - A GC (graphics context) object to use for drawing
1397 x, y - Coordinates of the pixel to draw
1413 - Support for shapeplane.
1416 *****************************************************************************************/
1418 VOID
BM__Hidd_BitMap__DrawPixel(OOP_Class
*cl
, OOP_Object
*obj
,
1419 struct pHidd_BitMap_DrawPixel
*msg
)
1421 HIDDT_Pixel src
, dest
, val
;
1422 HIDDT_DrawMode mode
;
1423 HIDDT_Pixel writeMask
;
1426 /* EnterFunc(bug("BitMap::DrawPixel() x: %i, y: %i\n", msg->x, msg->y));
1429 Example: Pixels whose bits are set to 0 in the colMask must be
1432 data->colMask = 001111
1436 writeMask = ~data->colMask & dest
1440 dest = data->fg && dest = 010100
1443 dest = dest & (writeMask | data->ColMask)
1444 = 010100 & (100000 | 001111)
1449 dest = dest | writeMask;
1460 #if OPTIMIZE_DRAWPIXEL_FOR_COPY
1461 if (vHidd_GC_DrawMode_Copy
== mode
&& GC_COLMASK(gc
) == ~0)
1468 dest
= GETPIXEL(cl
, obj
, msg
->x
, msg
->y
);
1469 writeMask
= ~GC_COLMASK(gc
) & dest
;
1473 if(mode
& 1) val
= ( src
& dest
);
1474 if(mode
& 2) val
= ( src
& ~dest
) | val
;
1475 if(mode
& 4) val
= (~src
& dest
) | val
;
1476 if(mode
& 8) val
= (~src
& ~dest
) | val
;
1478 val
= (val
& (writeMask
| GC_COLMASK(gc
) )) | writeMask
;
1482 PUTPIXEL(cl
, obj
, msg
->x
, msg
->y
, val
);
1485 /*****************************************************************************************
1488 moHidd_BitMap_DrawLine
1491 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPixel *msg);
1493 VOID HIDD_BM_DrawLine(OOP_Object *obj, OOP_Object *gc, WORD x1, WORD y1,
1500 Draws a line from (x1,y1) to (x2,y2) in the specified gc.
1501 The function does not clip the line against the drawing area.
1504 obj - A bitmap to draw on
1505 gc - A graphics context object to use
1506 x1,y1 - start point of the line in pixels
1507 x2,y2 - end point of the line in pixels
1521 Uses midpoint line ("Bresenham") algorithm([FOL90] 3.2.2)
1523 TODO Support for line pattern
1524 Optimize remove if t == 1 ...
1525 Implement better clipping: Should be no reason to calculate
1526 more than the part of the line that is inside the cliprect
1528 *****************************************************************************************/
1530 VOID BM__Hidd_BitMap__DrawLine
1532 OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawLine
*msg
1535 WORD dx
, dy
, incrE
, incrNE
, d
, x
, y
, s1
, s2
, t
, i
;
1536 WORD x1
, y1
, x2
, y2
;
1537 UWORD maskLine
; /* for line pattern */
1538 ULONG fg
; /* foreground pen */
1544 /* bug("BitMap::DrawLine()\n");
1545 */ EnterFunc(bug("BitMap::DrawLine() x1: %i, y1: %i x2: %i, y2: %i\n", msg
->x1
, msg
->y1
, msg
->x2
, msg
->y2
));
1548 doclip
= GC_DOCLIP(gc
);
1549 opaque
= (GC_COLEXP(gc
) & vHidd_GC_ColExp_Opaque
) ? TRUE
: FALSE
;
1552 maskLine
= 1 << GC_LINEPATCNT(gc
);
1556 /* If line is not inside cliprect, then just return */
1557 /* Normalize coords */
1558 if (msg
->x1
> msg
->x2
)
1560 x1
= msg
->x2
; x2
= msg
->x1
;
1564 x1
= msg
->x1
; x2
= msg
->x2
;
1567 if (msg
->y1
> msg
->y2
)
1569 y1
= msg
->y2
; y2
= msg
->y1
;
1573 y1
= msg
->y1
; y2
= msg
->y2
;
1576 if ( x1
> GC_CLIPX2(gc
)
1577 || x2
< GC_CLIPX1(gc
)
1578 || y1
> GC_CLIPY2(gc
)
1579 || y2
< GC_CLIPY1(gc
) )
1582 /* Line is not inside cliprect, so just return */
1596 Horizontal line drawing code.
1600 /* Don't swap coordinates if x2 < x1! Because of linepattern! */
1613 for(i
= x1
; i
!= x2
; i
+= dx
)
1615 /* Pixel inside ? */
1617 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, i
, y
))
1619 if(GC_LINEPAT(gc
) & maskLine
)
1621 HIDD_BM_DrawPixel(obj
, gc
, i
, y
);
1625 GC_FG(gc
) = GC_BG(gc
);
1626 HIDD_BM_DrawPixel(obj
, gc
, i
, y
);
1631 maskLine
= maskLine
>> 1;
1632 if (!maskLine
) maskLine
= 1L << 15;
1638 Vertical line drawing code.
1642 /* Don't swap coordinates if y2 < y1! Because of linepattern! */
1655 for(i
= y1
; i
!= y2
; i
+= dy
)
1657 /* Pixel inside ? */
1658 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, x
, i
))
1660 if(GC_LINEPAT(gc
) & maskLine
)
1662 HIDD_BM_DrawPixel(obj
, gc
, x
, i
);
1666 GC_FG(gc
) = GC_BG(gc
);
1667 HIDD_BM_DrawPixel(obj
, gc
, x
, i
);
1672 maskLine
= maskLine
>> 1;
1673 if (!maskLine
) maskLine
= 1L << 15;
1680 Generic line drawing code.
1682 /* Calculate slope */
1686 /* which direction? */
1687 if((x2
- x1
) > 0) s1
= 1; else s1
= - 1;
1688 if((y2
- y1
) > 0) s2
= 1; else s2
= - 1;
1690 /* change axes if dx < dy */
1703 d
= 2 * dy
- dx
; /* initial value of d */
1705 incrE
= 2 * dy
; /* Increment use for move to E */
1706 incrNE
= 2 * (dy
- dx
); /* Increment use for move to NE */
1710 for(i
= 0; i
<= dx
; i
++)
1712 /* Pixel inside ? */
1713 if (!doclip
|| !POINT_OUTSIDE_CLIP(gc
, x
, y
))
1715 if(GC_LINEPAT(gc
) & maskLine
)
1717 HIDD_BM_DrawPixel(obj
, gc
, x
, y
);
1721 GC_FG(gc
) = GC_BG(gc
);
1722 HIDD_BM_DrawPixel(obj
, gc
, x
, y
);
1747 maskLine
= maskLine
>> 1;
1748 if (!maskLine
) maskLine
= 1L << 15;
1753 ReturnVoid("BitMap::DrawLine ");
1756 /*****************************************************************************************
1759 moHidd_BitMap_DrawRect
1762 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawRect *msg);
1764 VOID HIDD_BM_DrawRect (OOP_Object *obj, OOP_Object *gc, WORD minX, WORD minY,
1765 WORD maxX, WORD maxY);
1771 Draws a hollow rectangle. minX and minY specifies the upper
1772 left corner of the rectangle. minY and maxY specifies the lower
1773 right corner of the rectangle.
1774 The function does not clip the rectangle against the drawing area.
1777 obj - A bitmap to draw on
1778 gc - A GC object to use for drawing
1779 minX, minY - upper left corner of the rectangle in pixels
1780 maxX, maxY - lower right corner of the rectangle in pixels
1786 This method is not used by the system and considered reserved.
1798 *****************************************************************************************/
1800 VOID
BM__Hidd_BitMap__DrawRect(OOP_Class
*cl
, OOP_Object
*obj
,
1801 struct pHidd_BitMap_DrawRect
*msg
)
1804 OOP_Object
*gc
= msg
->gc
;
1807 EnterFunc(bug("BitMap::DrawRect()"));
1809 if(msg
->minX
== msg
->maxX
) addX
= 0; else addX
= 1;
1810 if(msg
->minY
== msg
->maxY
) addY
= 0; else addY
= 1;
1812 HIDD_BM_DrawLine(obj
, gc
, msg
->minX
, msg
->minY
, msg
->maxX
, msg
->minY
);
1813 HIDD_BM_DrawLine(obj
, gc
, msg
->maxX
, msg
->minY
+ addY
, msg
->maxX
, msg
->maxY
);
1814 HIDD_BM_DrawLine(obj
, gc
, msg
->maxX
- addX
, msg
->maxY
, msg
->minX
, msg
->maxY
);
1815 HIDD_BM_DrawLine(obj
, gc
, msg
->minX
, msg
->maxY
- addY
, msg
->minX
, msg
->minY
+ addY
);
1818 ReturnVoid("BitMap::DrawRect");
1821 /*****************************************************************************************
1824 moHidd_BitMap_FillRect
1827 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawRect *msg);
1829 VOID HIDD_BM_FillRect (OOP_Object *obj, OOP_Object *gc, WORD minX, WORD minY,
1830 WORD maxX, WORD maxY);
1837 Draws a solid rectangle. minX and minY specifies the upper
1838 left corner of the rectangle. maxX and maxY specifies the lower
1839 right corner of the rectangle.
1840 The function does not clip the rectangle against the drawing area.
1843 obj - A bitmap to draw on
1844 gc - A GC object to use for drawing
1845 minX, minY - upper left corner of the rectangle in pixels
1846 maxX, maxY - lower right corner of the rectangle in pixels
1864 *****************************************************************************************/
1866 VOID
BM__Hidd_BitMap__FillRect(OOP_Class
*cl
, OOP_Object
*obj
,
1867 struct pHidd_BitMap_DrawRect
*msg
)
1869 OOP_Object
*gc
= msg
->gc
;
1873 EnterFunc(bug("BitMap::FillRect()"));
1875 linepat
= GC_LINEPAT(gc
);
1876 GC_LINEPAT(gc
) = ~0;
1878 for(; y
<= msg
->maxY
; y
++)
1880 HIDD_BM_DrawLine(obj
, gc
, msg
->minX
, y
, msg
->maxX
, y
);
1883 GC_LINEPAT(gc
) = linepat
;
1885 ReturnVoid("BitMap::FillRect");
1888 /*****************************************************************************************
1891 moHidd_BitMap_DrawEllipse
1894 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawEllipse *msg);
1896 VOID HIDD_BM_DrawEllipse (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
1903 Draws a hollow ellipse from the center point (x,y) with the radii
1904 rx and ry in the specified bitmap.
1905 The function does not clip the ellipse against the drawing area.
1908 obj - A bitmap to draw on
1909 gc - A GC object to use for drawing
1910 x,y - Coordinates of center point in pixels
1911 rx,ry - ry and ry radius in pixels
1921 Because of overflow the current code do not work with big
1922 values of rx and ry.
1931 *****************************************************************************************/
1933 /* TODO: Try to opimize clipping here */
1935 VOID
BM__Hidd_BitMap__DrawEllipse(OOP_Class
*cl
, OOP_Object
*obj
,
1936 struct pHidd_BitMap_DrawEllipse
*msg
)
1938 OOP_Object
*gc
= msg
->gc
;
1939 WORD x
= msg
->rx
, y
= 0; /* ellipse points */
1941 /* intermediate terms to speed up loop */
1942 LONG t1
= msg
->rx
* msg
->rx
, t2
= t1
<< 1, t3
= t2
<< 1;
1943 LONG t4
= msg
->ry
* msg
->ry
, t5
= t4
<< 1, t6
= t5
<< 1;
1944 LONG t7
= msg
->rx
* t5
, t8
= t7
<< 1, t9
= 0L;
1945 LONG d1
= t2
- t7
+ (t4
>> 1); /* error terms */
1946 LONG d2
= (t1
>> 1) - t8
+ t5
;
1948 APTR doclip
= GC_DOCLIP(gc
);
1951 EnterFunc(bug("BitMap::DrawEllipse()"));
1953 while (d2
< 0) /* till slope = -1 */
1955 /* draw 4 points using symmetry */
1960 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
+ y
))
1961 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1963 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
- y
))
1964 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1966 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
+ y
))
1967 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1969 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
- y
))
1970 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1975 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
1976 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
1977 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
1978 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
1981 y
++; /* always move up here */
1983 if (d1
< 0) /* move straight up */
1988 else /* move up and left */
1992 d1
= d1
+ t9
+ t2
- t8
;
1993 d2
= d2
+ t9
+ t5
- t8
;
1997 do /* rest of top right quadrant */
1999 /* draw 4 points using symmetry */
2004 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
+ y
))
2005 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
2007 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
+ x
, msg
->y
- y
))
2008 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
2010 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
+ y
))
2011 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
2013 if (!POINT_OUTSIDE_CLIP(gc
, msg
->x
- x
, msg
->y
- y
))
2014 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
2020 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
2021 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
2022 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
2023 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
2027 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
+ y
);
2028 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
+ x
, msg
->y
- y
);
2029 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
+ y
);
2030 HIDD_BM_DrawPixel(obj
, gc
, msg
->x
- x
, msg
->y
- y
);
2032 x
--; /* always move left here */
2034 if (d2
< 0) /* move up and left */
2038 d2
= d2
+ t9
+ t5
- t8
;
2040 else /* move straight left */
2048 ReturnVoid("BitMap::DrawEllipse");
2051 /*****************************************************************************************
2054 moHidd_BitMap_FillEllipse
2057 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawEllipse *msg);
2059 VOID HIDD_BM_FillEllipse (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2066 Draws a solid ellipse from the center point (x,y) with the radii
2067 rx and ry in the specified bitmap.
2068 The function does not clip the ellipse against the drawing area.
2071 obj - A bitmap to draw on
2072 gc - A GC object to use for drawing
2073 x,y - Coordinates of center point in pixels
2074 rx,ry - ry and ry radius in pixels
2080 This method is not used by the system and considered reserved.
2084 Because of overflow the current code do not work with big
2085 values of rx and ry.
2094 *****************************************************************************************/
2096 VOID
BM__Hidd_BitMap__FillEllipse(OOP_Class
*cl
, OOP_Object
*obj
,
2097 struct pHidd_BitMap_DrawEllipse
*msg
)
2100 OOP_Object
*gc
= msg
->gc
;
2101 WORD x
= msg
->rx
, y
= 0; /* ellipse points */
2103 /* intermediate terms to speed up loop */
2104 LONG t1
= msg
->rx
* msg
->rx
, t2
= t1
<< 1, t3
= t2
<< 1;
2105 LONG t4
= msg
->ry
* msg
->ry
, t5
= t4
<< 1, t6
= t5
<< 1;
2106 LONG t7
= msg
->rx
* t5
, t8
= t7
<< 1, t9
= 0L;
2107 LONG d1
= t2
- t7
+ (t4
>> 1); /* error terms */
2108 LONG d2
= (t1
>> 1) - t8
+ t5
;
2110 EnterFunc(bug("BitMap::FillEllipse()"));
2112 while (d2
< 0) /* till slope = -1 */
2114 /* draw 4 points using symmetry */
2115 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
+ y
, msg
->x
+ x
, msg
->y
+ y
);
2116 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
- y
, msg
->x
+ x
, msg
->y
- y
);
2118 y
++; /* always move up here */
2120 if (d1
< 0) /* move straight up */
2125 else /* move up and left */
2129 d1
= d1
+ t9
+ t2
- t8
;
2130 d2
= d2
+ t9
+ t5
- t8
;
2134 do /* rest of top right quadrant */
2136 /* draw 4 points using symmetry */
2137 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
+ y
, msg
->x
+ x
, msg
->y
+ y
);
2138 HIDD_BM_DrawLine(obj
, gc
, msg
->x
- x
, msg
->y
- y
, msg
->x
+ x
, msg
->y
- y
);
2140 x
--; /* always move left here */
2142 if (d2
< 0) /* move up and left */
2146 d2
= d2
+ t9
+ t5
- t8
;
2148 else /* move straight left */
2156 ReturnVoid("BitMap::FillEllipse");
2159 /*****************************************************************************************
2162 moHidd_BitMap_DrawPolygon
2165 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg);
2167 VOID HIDD_BM_DrawPolygon (OOP_Object *obj, OOP_Object *gc, UWORD n, WORD *coords);
2173 Draws a hollow polygon from the list of coordinates in coords[].
2174 The function does not clip the polygon against the drawing area.
2177 obj - A bitmap to draw on
2178 gc - A GC object to use for drawing
2179 n - number of coordinate pairs
2180 coords - array of n (x, y) coordinates in pixels
2186 This method is not used by the system and considered reserved.
2198 *****************************************************************************************/
2200 VOID
BM__Hidd_BitMap__DrawPolygon(OOP_Class
*cl
, OOP_Object
*obj
,
2201 struct pHidd_BitMap_DrawPolygon
*msg
)
2204 OOP_Object
*gc
= msg
->gc
;
2207 EnterFunc(bug("BitMap::DrawPolygon()"));
2209 for(i
= 2; i
< (2 * msg
->n
); i
= i
+ 2)
2211 HIDD_BM_DrawLine(obj
, gc
, msg
->coords
[i
- 2], msg
->coords
[i
- 1],
2212 msg
->coords
[i
], msg
->coords
[i
+ 1]);
2216 ReturnVoid("BitMap::DrawPolygon");
2219 /*****************************************************************************************
2222 moHidd_BitMap_FillPolygon
2225 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg);
2227 VOID HIDD_BM_FillPolygon (OOP_Object *obj, OOP_Object *gc, UWORD n, WORD *coords);
2233 This method was initially designed for drawing solid polygons, however it was never
2234 used and implemented. At the moment it is considered reserved, its synopsis and
2235 semantics may change in future.
2238 obj - A bitmap to draw on
2239 gc - A GC object to use for drawing
2240 n - number of coordinate pairs
2241 coords - array of n (x, y) coordinates in pixels
2251 Never used and implemented
2259 *****************************************************************************************/
2261 VOID
BM__Hidd_BitMap__FillPolygon(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawPolygon
*msg
)
2263 D(bug("Sorry, FillPolygon() not implemented yet in bitmap baseclass\n"));
2266 /*****************************************************************************************
2269 moHidd_BitMap_DrawText
2272 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2274 VOID HIDD_BM_DrawText (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2275 STRPTR text, UWORD length);
2281 Draws the first length characters of text at (x, y).
2282 The function does not clip the text against the drawing area.
2285 obj - A bitmap to draw on
2286 gc - A GC object to use for drawing and font specification
2287 x, y - Position to start drawing in pixels. The x
2288 coordinate is relativ to the left side of the
2290 The y coordinate is relative to the baseline of the font.
2291 text - Pointer to a Latin 1 string
2292 length - Number of characters to draw
2298 At the moment text drawing is processed entirely by graphics.library
2299 using BltTemplate(), which in turn uses moHodd_BitMap_PutTemplate.
2300 This method is considered obsolete.
2305 The default implementation in the base class does not process styles,
2306 color and alpha-blended fonts.
2314 *****************************************************************************************/
2316 VOID
BM__Hidd_BitMap__DrawText(OOP_Class
*cl
, OOP_Object
*obj
,
2317 struct pHidd_BitMap_DrawText
*msg
)
2320 OOP_Object
*gc
= msg
->gc
;
2321 struct TextFont
*font
= GC_FONT(gc
);
2322 UBYTE
*charPatternPtr
= font
->tf_CharData
;
2323 UWORD modulo
= font
->tf_Modulo
;
2325 UBYTE ch
; /* current character to print */
2326 WORD fx
, fx2
, fy
, fw
; /* position and length of character in the */
2327 /* character bitmap */
2328 WORD xMem
= msg
->x
; /* position in bitmap */
2329 WORD yMem
= msg
->y
- font
->tf_Baseline
;
2333 EnterFunc(bug("BitMap::DrawText()"));
2335 for(i
= 0; i
< msg
->length
; i
++)
2339 if((ch
< font
->tf_LoChar
) || (ch
> font
->tf_HiChar
))
2341 ch
= font
->tf_HiChar
- font
->tf_LoChar
+ 1;
2345 ch
= ch
- font
->tf_LoChar
;
2348 if(font
->tf_Flags
& FPF_PROPORTIONAL
)
2350 xMem
= xMem
+ ((UWORD
*) font
->tf_CharKern
)[ch
];
2353 charLog
= ((ULONG
*) font
->tf_CharLoc
)[ch
];
2354 fx2
= charLog
>> 16; /* x position of character pattern in character bitmap */
2355 fw
= (UWORD
) charLog
; /* width of character pattern in character bitmap */
2359 for(fy
= 0; fy
< font
->tf_YSize
; fy
++)
2363 for(fx
= fx2
; fx
< fw
+ fx2
; fx
++)
2365 if(*(charPatternPtr
+ fx
/ 8 + fy
* modulo
) & (128 >> (fx
% 8)))
2367 HIDD_BM_DrawPixel(obj
, msg
->gc
, x
, y
);
2375 if(font
->tf_Flags
& FPF_PROPORTIONAL
)
2377 xMem
= xMem
+ ((UWORD
*) font
->tf_CharSpace
)[ch
];
2381 xMem
= xMem
+ font
->tf_XSize
;
2385 ReturnVoid("BitMap::DrawText");
2388 /*****************************************************************************************
2391 moHidd_BitMap_FillText
2394 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2396 VOID HIDD_BM_FillText (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2397 STRPTR text, UWORD length);
2403 Historically this method was designed to draw a text with background.
2404 It was never implemented.
2406 Currently this method is considered reserved. Its synopsis and semantics
2407 may change in future.
2410 obj - A bitmap to draw on
2411 gc - A GC object to use for drawing
2412 x, y - Position to start drawing in pixels. The x
2413 coordinate is relative to the left side of the
2415 The y coordinate is relative to the baseline of the font.
2416 text - Pointer to a Latin 1 string
2417 length - Number of characters to draw
2433 *****************************************************************************************/
2435 VOID
BM__Hidd_BitMap__FillText(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawText
*msg
)
2437 D(bug("Sorry, FillText() not implemented yet in bitmap baseclass\n"));
2440 /*****************************************************************************************
2443 moHidd_BitMap_FillSpan
2446 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2452 Reserved, never implemented method. The definition will change in future.
2471 *****************************************************************************************/
2473 VOID
BM__Hidd_BitMap__FillSpan(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_DrawText
*msg
)
2475 D(bug("Sorry, FillSpan() not implemented yet\n"));
2478 /*****************************************************************************************
2484 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_Clear *msg);
2486 VOID HIDD_BM_Clear (OOP_Object *obj, OOP_Object *gc);
2492 Sets all pixels of the drawing area to the background color.
2495 obj - A bitmap to clear.
2496 gc - A GC object, specifies background color value
2501 This method is not used by the system and considered reserved. However it can
2502 be useful for display driver's own needs.
2507 Default implementation in the base class sets all pixels to zero color instead of
2508 the background color from GC
2516 *****************************************************************************************/
2518 VOID
BM__Hidd_BitMap__Clear(OOP_Class
*cl
, OOP_Object
*obj
, struct pHidd_BitMap_Clear
*msg
)
2520 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
2524 EnterFunc(bug("BitMap::Clear()\n"));
2526 OOP_GetAttr(obj
, aHidd_BitMap_Width
, &width
);
2527 OOP_GetAttr(obj
, aHidd_BitMap_Height
, &height
);
2529 for(y
= 0; y
< height
; y
++)
2531 for(x
= 0; x
< width
; x
++)
2533 HIDD_BM_PutPixel(obj
, x
, y
, 0);
2537 ReturnVoid("BitMap::Clear");
2540 /****************************************************************************************/
2542 static LONG
inline getpixfmtbpp(OOP_Class
*cl
, OOP_Object
*o
, HIDDT_StdPixFmt stdpf
)
2544 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
2546 struct HIDDBitMapData
*data
;
2549 data
= OOP_INST_DATA(cl
, o
);
2553 case vHidd_StdPixFmt_Native
:
2554 OOP_GetAttr(data
->prot
.pixfmt
, aHidd_PixFmt_BytesPerPixel
, &bpp
);
2557 case vHidd_StdPixFmt_Native32
:
2558 bpp
= sizeof (HIDDT_Pixel
);
2562 pf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, stdpf
);
2566 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", stdpf
));
2570 OOP_GetAttr(pf
, aHidd_PixFmt_BytesPerPixel
, &bpp
);
2578 /*****************************************************************************************
2581 moHidd_BitMap_GetImage
2584 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_GetImage *msg);
2586 VOID HIDD_BM_GetImage (OOP_Object *obj, UBYTE *pixels, ULONG modulo, WORD x, WORD y,
2587 WORD width, WORD height, HIDDT_StdPixFmt pixFmt);
2615 *****************************************************************************************/
2617 VOID
BM__Hidd_BitMap__GetImage(OOP_Class
*cl
, OOP_Object
*o
,
2618 struct pHidd_BitMap_GetImage
*msg
)
2621 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
2622 APTR ppixarray
= &pixarray
;
2624 struct HIDDBitMapData
*data
;
2626 data
= OOP_INST_DATA(cl
, o
);
2628 EnterFunc(bug("BitMap::GetImage(x=%d, y=%d, width=%d, height=%d)\n"
2629 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
2632 bpp
= getpixfmtbpp(cl
, o
, msg
->pixFmt
);
2635 D(bug("!!! INVALID PIXFMT IN BitMap::GetImage(): %d !!!\n", msg
->pixFmt
));
2642 case vHidd_StdPixFmt_Native
:
2643 case vHidd_StdPixFmt_Native32
:
2644 for (y
= 0; y
< msg
->height
; y
++)
2646 for (x
= 0; x
< msg
->width
; x
++)
2648 register HIDDT_Pixel pix
;
2650 pix
= HIDD_BM_GetPixel(o
, x
+ msg
->x
, y
+ msg
->y
);
2659 *((UWORD
*)pixarray
) = pix
;
2665 pixarray
[0] = (pix
>> 16) & 0xFF;
2666 pixarray
[1] = (pix
>> 8) & 0xFF;
2667 pixarray
[2] = pix
& 0xFF;
2669 pixarray
[0] = pix
& 0xFF;
2670 pixarray
[1] = (pix
>> 8) & 0xFF;
2671 pixarray
[2] = (pix
>> 16) & 0xFF;
2677 *(ULONG
*)pixarray
= pix
;
2684 pixarray
+= (msg
->modulo
- msg
->width
* bpp
);
2692 APTR buf
, srcPixels
;
2694 dstpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
2696 buf
= srcPixels
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
2699 for(y
= 0; y
< msg
->height
; y
++)
2708 vHidd_StdPixFmt_Native
);
2710 HIDD_BM_ConvertPixels(o
,
2712 (HIDDT_PixelFormat
*)data
->prot
.pixfmt
,
2715 (HIDDT_PixelFormat
*)dstpf
,
2727 } /* switch(msg->pixFmt) */
2729 ReturnVoid("BitMap::GetImage");
2732 /*****************************************************************************************
2735 moHidd_BitMap_PutImage
2738 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutImage *msg);
2740 VOID HIDD_BM_PutImage (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
2741 WORD x, WORD y, WORD width, WORD height, HIDDT_StdPixFmt pixFmt);
2770 *****************************************************************************************/
2772 VOID
BM__Hidd_BitMap__PutImage(OOP_Class
*cl
, OOP_Object
*o
,
2773 struct pHidd_BitMap_PutImage
*msg
)
2776 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
2777 APTR ppixarray
= &pixarray
;
2780 struct HIDDBitMapData
*data
;
2781 OOP_Object
*gc
= msg
->gc
;
2783 data
= OOP_INST_DATA(cl
, o
);
2785 EnterFunc(bug("BitMap::PutImage(x=%d, y=%d, width=%d, height=%d)\n"
2786 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
2788 if (msg
->width
<= 0 || msg
->height
<= 0)
2791 bpp
= getpixfmtbpp(cl
, o
, msg
->pixFmt
);
2794 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", msg
->pixFmt
));
2800 case vHidd_StdPixFmt_Native
:
2801 case vHidd_StdPixFmt_Native32
:
2803 /* Preserve old fg pen */
2806 for (y
= 0; y
< msg
->height
; y
++)
2808 for (x
= 0; x
< msg
->width
; x
++)
2810 register HIDDT_Pixel pix
= 0;
2815 pix
= *((UBYTE
*)pixarray
);
2820 pix
= *((UWORD
*)pixarray
);
2826 pix
= ((UBYTE
*)pixarray
)[0] << 16;
2827 pix
|= ((UBYTE
*)pixarray
)[1] << 8;
2828 pix
|= ((UBYTE
*)pixarray
)[2];
2830 pix
= ((UBYTE
*)pixarray
)[2] << 16;
2831 pix
|= ((UBYTE
*)pixarray
)[1] << 8;
2832 pix
|= ((UBYTE
*)pixarray
)[0];
2838 pix
= *((ULONG
*)pixarray
); pixarray
+= 4;
2845 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->x
, y
+ msg
->y
);
2847 pixarray
+= (msg
->modulo
- msg
->width
* bpp
);
2856 APTR buf
, destPixels
;
2858 srcpf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
2860 buf
= destPixels
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
2863 for(y
= 0; y
< msg
->height
; y
++)
2865 HIDD_BM_ConvertPixels(o
,
2867 (HIDDT_PixelFormat
*)srcpf
,
2870 (HIDDT_PixelFormat
*)data
->prot
.pixfmt
,
2884 vHidd_StdPixFmt_Native
);
2891 } /* switch(msg->pixFmt) */
2893 ReturnVoid("BitMap::PutImage");
2896 /****************************************************************************************/
2899 __attribute__((always_inline
, const)) do_alpha(int a
, int v
)
2902 return ((tmp
<<8) + tmp
+ 32768)>>16;
2907 #define RGB32_DECOMPOSE(red, green, blue, pix) \
2908 red = ((pix) & 0x00FF0000) >> 16; \
2909 green = ((pix) & 0x0000FF00) >> 8; \
2910 blue = ((pix) & 0x000000FF);
2912 #define ARGB32_ALPHA(pix) ((pix) & 0xFF000000)
2914 #define ARGB32_DECOMPOSE(alpha, red, green, blue, pix) \
2915 alpha = ((pix) & 0xFF000000) >> 24; \
2916 red = ((pix) & 0x00FF0000) >> 16; \
2917 green = ((pix) & 0x0000FF00) >> 8; \
2918 blue = ((pix) & 0x000000FF);
2920 #define ARGB32_COMPOSE(red, green, blue, old) (((old) & 0xFF000000) + ((red) << 16) + ((green) << 8) + (blue))
2924 #define RGB32_DECOMPOSE(red, green, blue, pix) \
2925 red = (pix & 0x0000FF00) >> 8; \
2926 green = (pix & 0x00FF0000) >> 16; \
2927 blue = (pix & 0xFF000000) >> 24
2929 #define ARGB32_ALPHA(pix) ((pix) & 0x000000FF)
2931 #define ARGB32_DECOMPOSE(alpha, red, green, blue, pix) \
2932 alpha = (pix & 0x000000FF); \
2933 red = (pix & 0x0000FF00) >> 8; \
2934 green = (pix & 0x00FF0000) >> 16; \
2935 blue = (pix & 0xFF000000) >> 24
2937 #define ARGB32_COMPOSE(red, green, blue, old) (((blue) << 24) + ((green) << 16) + ((red) << 8) + ((old) & 0x000000FF))
2941 /*****************************************************************************************
2944 moHidd_BitMap_PutAlphaImage
2947 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutAlphaImage *msg);
2949 VOID HIDD_BM_PutAlphaImage (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
2950 WORD x, WORD y, WORD width, WORD height);
2956 Perform an alpha-blending operation between a bitmap and ARGB pixel array.
2959 obj - A bitmap to operate on
2960 gc - A GC object, internally needed to perform the operation. All its attributes
2962 pixels - A pointer to an array of pixels
2963 modulo - Number of bytes per row in pixel array
2964 x, y - Top-left corner of affected bitmap's region
2965 width - Width of the modified rectangle.
2966 height - Height of the modified rectangle.
2972 Do not rely on 'gc' parameter being valid when implementing this method in own
2973 display driver. This parameter is actually obsolete, and will be set to NULL in
2974 future AROS versions. Current base class implementation ignores it.
2984 *****************************************************************************************/
2994 * 1. Merge buffered and slow versions of PutAlphaImage(), use the same processing algorithm
2995 * (convert array's pixels to bitmap's format, not vice versa)
2996 * 2. Make DoBufferedOperation() public, to be used for cybergraphics.library/ProcessPixelArray()
2997 * implementation, and for some other functions in graphics.library and cybergraphics.library,
2998 * currently using own implementation of pixel buffer.
2999 * 3. Reuse the new code for other buffered operations (currently using old macros).
3002 static void PutAlphaImageBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct paib_data
*data
)
3006 for (y
= 0; y
< height
; y
++)
3008 ULONG
*pixarray
= data
->pixels
;
3010 for (x
= 0; x
< width
; x
++)
3014 ULONG src_red
, src_green
, src_blue
, src_alpha
;
3015 ULONG dst_red
, dst_green
, dst_blue
;
3017 srcpix
= *pixarray
++;
3019 if (ARGB32_ALPHA(srcpix
) == ARGB32_ALPHA(0xFFFFFFFF))
3023 else if (ARGB32_ALPHA(srcpix
) != 0)
3025 ARGB32_DECOMPOSE(src_alpha
, src_red
, src_green
, src_blue
, srcpix
);
3028 RGB32_DECOMPOSE(dst_red
, dst_green
, dst_blue
, destpix
);
3030 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
3031 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
3032 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
3034 xbuf
[x
] = ARGB32_COMPOSE(dst_red
, dst_green
, dst_blue
, destpix
);
3039 data
->pixels
+= data
->modulo
;
3043 VOID
BM__Hidd_BitMap__PutAlphaImage(OOP_Class
*cl
, OOP_Object
*o
,
3044 struct pHidd_BitMap_PutAlphaImage
*msg
)
3047 struct paib_data data
= {msg
->pixels
, msg
->modulo
};
3049 EnterFunc(bug("BitMap::PutAlphaImage(x=%d, y=%d, width=%d, height=%d)\n"
3050 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3052 if (msg
->width
<= 0 || msg
->height
<= 0)
3055 if (!DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, TRUE
, vHidd_StdPixFmt_ARGB32
,
3056 (VOID_FUNC
)PutAlphaImageBuffered
, &data
))
3058 /* Buffered method failed, use slow pixel-by-pixel method */
3059 for (y
= msg
->y
; y
< msg
->y
+ msg
->height
; y
++)
3061 ULONG
*pixarray
= data
.pixels
;
3063 for (x
= msg
->x
; x
< msg
->x
+ msg
->width
; x
++)
3065 HIDDT_Pixel destpix
;
3068 LONG src_red
, src_green
, src_blue
, src_alpha
;
3069 LONG dst_red
, dst_green
, dst_blue
;
3071 destpix
= HIDD_BM_GetPixel(o
, x
, y
);
3072 HIDD_BM_UnmapPixel(o
, destpix
, &col
);
3074 srcpix
= *pixarray
++;
3075 ARGB32_DECOMPOSE(src_alpha
, src_red
, src_green
, src_blue
, srcpix
);
3077 dst_red
= col
.red
>> 8;
3078 dst_green
= col
.green
>> 8;
3079 dst_blue
= col
.blue
>> 8;
3081 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
3082 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
3083 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
3085 col
.red
= dst_red
<< 8;
3086 col
.green
= dst_green
<< 8;
3087 col
.blue
= dst_blue
<< 8;
3089 HIDD_BM_PutPixel(o
, x
, y
, HIDD_BM_MapColor(o
, &col
));
3091 } /* for(x = msg->x; x < msg->x + msg->width; x++) */
3093 data
.pixels
+= msg
->modulo
;
3095 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
3097 ReturnVoid("BitMap::PutAlphaImage");
3100 /*****************************************************************************************
3103 moHidd_BitMap_PutTemplate
3106 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutTemplate *msg);
3108 VOID HIDD_BM_PutTemplate (OOP_Object *obj, OOP_Object *gc, UBYTE *masktemplate, ULONG modulo,
3109 WORD srcx, WORD x, WORD y, WORD width, WORD height, BOOL inverttemplate);
3115 Apply a single-bit mask to the given portion of the bitmap. Pixels set to 1 in the mask will be filled
3116 by foreground color. Pixels set to 0 in the mask will be filled by background color or left unchanged,
3117 according to the following GC attributes:
3118 Foreground - a foreground color
3119 Background - a background color
3120 DrawMode - if set to Invert, foreground and background colors will be ignored. Instead,
3121 pixels which are set to 1 in the mask, will be inverted. Other pixels will be
3123 ColorExpansion - if set to Transparent, only pixels which are set to 1 in the mask, will be modified.
3124 Other pixels will not be changed (background color will be ignored).
3127 obj - A bitmap to draw on
3128 gc - A GC object, holding operation parameters
3129 masktemplate - A pointer to a bit mask
3130 modulo - Number of bytes per line in the mask
3131 srcx - Horizontal offset of the mask
3132 x, y - Top-left corner of the bitmap's region to affect
3133 width - Width of the affected region
3134 height - Height of the affected region
3135 inverttemplate - If set to TRUE, bit mask will be interpreted in inverted form
3150 *****************************************************************************************/
3162 static void JAM1TemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ptb_data
*data
)
3166 for (y
= 0; y
< height
; y
++)
3168 ULONG mask
= data
->bitmask
;
3169 UWORD
*array
= data
->bitarray
;
3170 UWORD bitword
= AROS_BE2WORD(*array
);
3172 for (x
= 0; x
< width
; x
++)
3174 if ((bitword
& mask
) == (data
->invert
& mask
))
3182 bitword
= AROS_BE2WORD(*array
);
3187 data
->bitarray
+= data
->modulo
;
3191 static void ComplementTemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ptb_data
*data
)
3195 for (y
= 0; y
< height
; y
++)
3197 ULONG mask
= data
->bitmask
;
3198 UWORD
*array
= data
->bitarray
;
3199 UWORD bitword
= AROS_BE2WORD(*array
);
3201 for (x
= 0; x
< width
; x
++)
3203 if ((bitword
& mask
) == (data
->invert
& mask
))
3211 bitword
= AROS_BE2WORD(*array
);
3216 data
->bitarray
+= data
->modulo
;
3220 static void JAM2TemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ptb_data
*data
)
3224 for (y
= 0; y
< height
; y
++)
3226 ULONG mask
= data
->bitmask
;
3227 UWORD
*array
= data
->bitarray
;
3228 UWORD bitword
= AROS_BE2WORD(*array
);
3230 for (x
= 0; x
< width
; x
++)
3232 if ((bitword
& mask
) == (data
->invert
& mask
))
3242 bitword
= AROS_BE2WORD(*array
);
3247 data
->bitarray
+= data
->modulo
;
3251 VOID
BM__Hidd_BitMap__PutTemplate(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_PutTemplate
*msg
)
3253 OOP_Object
*gc
= msg
->gc
;
3255 void (*op
)(ULONG
*, UWORD
, UWORD
, UWORD
, struct ptb_data
*);
3256 struct ptb_data data
;
3258 EnterFunc(bug("BitMap::PutTemplate(x=%d, y=%d, width=%d, height=%d)\n"
3259 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3261 if (msg
->width
<= 0 || msg
->height
<= 0)
3264 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
3266 op
= JAM1TemplateBuffered
;
3268 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
3270 op
= ComplementTemplateBuffered
;
3274 op
= JAM2TemplateBuffered
;
3278 data
.bitarray
= msg
->masktemplate
+ ((msg
->srcx
/ 16) * 2);
3279 data
.bitmask
= 0x8000 >> (msg
->srcx
& 0xF);
3280 data
.modulo
= msg
->modulo
;
3281 data
.fg
= GC_FG(msg
->gc
);
3282 data
.bg
= GC_BG(msg
->gc
);
3283 data
.invert
= msg
->inverttemplate
? 0 : 0xFFFF;
3285 DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, get
, vHidd_StdPixFmt_Native32
, (VOID_FUNC
)op
, &data
);
3287 /* TODO: write fallback */
3289 ReturnVoid("BitMap::PutTemplate");
3292 /*****************************************************************************************
3295 moHidd_BitMap_PutAlphaTemplate
3298 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutAlphaTemplate *msg);
3300 VOID HIDD_BM_PutAlphaTemplate (OOP_Object *obj, OOP_Object *gc, UBYTE *alpha, ULONG modulo,
3301 WORD x, WORD y, WORD width, WORD height, BOOL invertalpha);
3307 Perform a drawing with current foreground color, using 8-bit alpha channel mask. The following
3308 GC attributes are considered:
3309 Foreground - a foreground color
3310 Background - a background color
3311 DrawMode - if set to Invert, foreground and background colors will be ignored. Instead,
3312 pixels, for which alpha channel value is greater than 127, will be inverted.
3313 Other pixels will be left unchanged.
3314 ColorExpansion - if set to Opaque, alpha blending will happen between foreground and background
3315 colors, instead of between foreground color and old bitmap contents.
3318 obj - A bitmap to draw on
3319 gc - A GC object specifying drawing parameters
3320 alpha - A pointer to an 8-bit per pixel alpha channel mask
3321 modulo - Number of bytes per line in the mask
3322 x, y - Top-left corner of the affected bitmap's region
3323 width - Width of the affected bitmap's region
3324 height - Height of the affected bitmap's region
3325 invertalpha - If set to TRUE, alpha mask values will be treated in inverted form
3340 *****************************************************************************************/
3346 LONG a_red
, a_green
, a_blue
;
3347 LONG b_red
, b_green
, b_blue
;
3351 static void JAM1AlphaTemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct patb_data
*data
)
3355 for (y
= 0; y
< height
; y
++)
3357 UBYTE
*pixarray
= data
->pixarray
;
3359 for (x
= 0; x
< width
; x
++)
3361 LONG dst_red
, dst_green
, dst_blue
, alpha
;
3363 alpha
= (*pixarray
++) ^ data
->invert
;
3364 RGB32_DECOMPOSE(dst_red
, dst_green
, dst_blue
, xbuf
[x
]);
3366 dst_red
+= do_alpha(alpha
, data
->a_red
- dst_red
);
3367 dst_green
+= do_alpha(alpha
, data
->a_green
- dst_green
);
3368 dst_blue
+= do_alpha(alpha
, data
->a_blue
- dst_blue
);
3370 xbuf
[x
] = ARGB32_COMPOSE(dst_red
, dst_green
, dst_blue
, 0);
3374 data
->pixarray
+= data
->modulo
;
3378 static void ComplementAlphaTemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct patb_data
*data
)
3382 for (y
= 0; y
< height
; y
++)
3384 UBYTE
*pixarray
= data
->pixarray
;
3386 for (x
= 0; x
< width
; x
++)
3388 UBYTE alpha
= (*pixarray
++) ^ data
->invert
;
3395 data
->pixarray
+= data
->modulo
;
3399 static void JAM2AlphaTemplateBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct patb_data
*data
)
3403 for (y
= 0; y
< height
; y
++)
3405 UBYTE
*pixarray
= data
->pixarray
;
3407 for (x
= 0; x
< width
; x
++)
3409 LONG dst_red
, dst_green
, dst_blue
, alpha
;
3411 alpha
= (*pixarray
++) ^ data
->invert
;
3413 dst_red
= data
->b_red
+ ((data
->a_red
- data
->b_red
) * alpha
) / 256;
3414 dst_green
= data
->b_green
+ ((data
->a_green
- data
->b_green
) * alpha
) / 256;
3415 dst_blue
= data
->b_blue
+ ((data
->a_blue
- data
->b_blue
) * alpha
) / 256;
3417 xbuf
[x
] = ARGB32_COMPOSE(dst_red
, dst_green
, dst_blue
, 0);
3421 data
->pixarray
+= data
->modulo
;
3425 VOID
BM__Hidd_BitMap__PutAlphaTemplate(OOP_Class
*cl
, OOP_Object
*o
,
3426 struct pHidd_BitMap_PutAlphaTemplate
*msg
)
3428 OOP_Object
*gc
= msg
->gc
;
3430 void (*op
)(ULONG
*, UWORD
, UWORD
, UWORD
, struct patb_data
*);
3431 struct patb_data data
;
3434 EnterFunc(bug("BitMap::PutAlphaTemplate(x=%d, y=%d, width=%d, height=%d)\n"
3435 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3437 if (msg
->width
<= 0 || msg
->height
<= 0)
3440 HIDD_BM_UnmapPixel(o
, GC_FG(gc
), &color
);
3441 data
.a_red
= color
.red
>> 8;
3442 data
.a_green
= color
.green
>> 8;
3443 data
.a_blue
= color
.blue
>> 8;
3445 if (GC_COLEXP(gc
) == vHidd_GC_ColExp_Transparent
)
3447 op
= JAM1AlphaTemplateBuffered
;
3449 else if (GC_DRMD(gc
) == vHidd_GC_DrawMode_Invert
)
3451 op
= ComplementAlphaTemplateBuffered
;
3455 op
= JAM2AlphaTemplateBuffered
;
3458 HIDD_BM_UnmapPixel(o
, GC_BG(gc
), &color
);
3459 data
.b_red
= color
.red
>> 8;
3460 data
.b_green
= color
.green
>> 8;
3461 data
.b_blue
= color
.blue
>> 8;
3464 data
.pixarray
= msg
->alpha
;
3465 data
.modulo
= msg
->modulo
;
3466 data
.invert
= msg
->invertalpha
? 255 : 0;
3468 DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, get
, vHidd_StdPixFmt_ARGB32
, (VOID_FUNC
)op
, &data
);
3470 /* TODO: write fallback */
3472 ReturnVoid("BitMap::PutAlphaTemplate");
3475 /*****************************************************************************************
3478 moHidd_BitMap_PutPattern
3481 VOID OOP_DoMethod(OOP_Object *o, struct pHidd_BitMap_PutPattern *msg);
3483 VOID HIDD_BM_PutPattern(OOP_Object *obj, OOP_Object *gc, UBYTE *pattern,
3484 WORD patternsrcx, WORD patternsrcy, WORD patternheight, WORD patterndepth,
3485 HIDDT_PixelLUT *patternlut, BOOL invertpattern, UBYTE *mask,
3486 ULONG maskmodulo, WORD masksrcx, WORD x, WORD y,
3487 WORD width, WORD height);
3495 obj - A bitmap to draw on
3496 gc - A GC object to use for drawing
3524 *****************************************************************************************/
3533 UWORD patternheight
;
3543 static void JAM1PatternBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
)
3547 for (y
= 0; y
< height
; y
++)
3549 UWORD pmask
= data
->patmask
;
3550 UWORD mmask
= data
->maskmask
;
3551 UWORD
*parray
= data
->patarray
+ ((y
+ starty
+ data
->patternsrcy
- data
->desty
) % data
->patternheight
);
3552 UWORD patword
= AROS_BE2WORD(*parray
);
3553 UWORD
*marray
= data
->maskarray
;
3554 UWORD maskword
= marray
? AROS_BE2WORD(*marray
) : 0xFFFF;
3556 for (x
= 0; x
< width
; x
++)
3558 if (maskword
& mmask
)
3560 if ((patword
& pmask
) == (data
->invert
& pmask
))
3571 maskword
= AROS_BE2WORD(*marray
);
3582 if (data
->maskarray
)
3583 data
->maskarray
+= data
->maskmodulo
;
3588 static void ComplementPatternBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
)
3592 for (y
= 0; y
< height
; y
++)
3594 UWORD pmask
= data
->patmask
;
3595 UWORD mmask
= data
->maskmask
;
3596 UWORD
*parray
= data
->patarray
+ ((y
+ starty
+ data
->patternsrcy
- data
->desty
) % data
->patternheight
);
3597 UWORD patword
= AROS_BE2WORD(*parray
);
3598 UWORD
*marray
= data
->maskarray
;
3599 UWORD maskword
= marray
? AROS_BE2WORD(*marray
) : 0xFFFF;
3601 for (x
= 0; x
< width
; x
++)
3603 if (maskword
& mmask
)
3605 if ((patword
& pmask
) == (data
->invert
& pmask
))
3616 maskword
= AROS_BE2WORD(*marray
);
3627 if (data
->maskarray
)
3628 data
->maskarray
+= data
->maskmodulo
;
3633 static void JAM2PatternBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
)
3637 for (y
= 0; y
< height
; y
++)
3639 UWORD pmask
= data
->patmask
;
3640 UWORD mmask
= data
->maskmask
;
3641 UWORD
*parray
= data
->patarray
+ ((y
+ starty
+ data
->patternsrcy
- data
->desty
) % data
->patternheight
);
3642 UWORD patword
= AROS_BE2WORD(*parray
);
3643 UWORD
*marray
= data
->maskarray
;
3644 UWORD maskword
= marray
? AROS_BE2WORD(*marray
) : 0xFFFF;
3646 for (x
= 0; x
< width
; x
++)
3648 if (maskword
& mmask
)
3650 if ((patword
& pmask
) == (data
->invert
& pmask
))
3663 maskword
= AROS_BE2WORD(*marray
);
3674 if (data
->maskarray
)
3675 data
->maskarray
+= data
->maskmodulo
;
3680 static void ColorPatternBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
)
3684 for (y
= 0; y
< height
; y
++)
3686 UWORD pmask
= data
->patmask
;
3687 UWORD mmask
= data
->maskmask
;
3688 UWORD
*parray
= data
->patarray
+ ((y
+ starty
+ data
->patternsrcy
- data
->desty
) % data
->patternheight
);
3689 UWORD patword
= AROS_BE2WORD(*parray
);
3690 UWORD
*marray
= data
->maskarray
;
3691 UWORD maskword
= marray
? AROS_BE2WORD(*marray
) : 0xFFFF;
3693 for (x
= 0; x
< width
; x
++)
3695 if (maskword
& mmask
)
3698 ULONG pixel
= (patword
& pmask
) ? 1 : 0; /* CHECKME: Shouldn't we handle INVERSVID here too ? */
3700 for (plane
= 1; plane
< data
->patterndepth
; plane
++)
3702 UWORD
*_parray
= parray
+ plane
* data
->patternheight
;
3703 UWORD _patword
= AROS_BE2WORD(*_parray
);
3705 if (_patword
& pmask
)
3706 pixel
|= 1L << plane
;
3709 if (data
->patternlut
)
3710 pixel
= data
->patternlut
[pixel
];
3722 maskword
= AROS_BE2WORD(*marray
);
3733 if (data
->maskarray
)
3734 data
->maskarray
+= data
->maskmodulo
;
3739 VOID
BM__Hidd_BitMap__PutPattern(OOP_Class
*cl
, OOP_Object
*o
,
3740 struct pHidd_BitMap_PutPattern
*msg
)
3742 void (*op
)(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ppb_data
*data
);
3744 struct ppb_data data
;
3746 DPUTPATTERN(bug("BitMap::PutPattern(x=%d, y=%d, width=%d, height=%d)\n",
3747 msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3749 if (msg
->width
<= 0 || msg
->height
<= 0)
3752 if (msg
->patterndepth
> 1)
3754 DPUTPATTERN(bug("[PutPattern] Color\n"));
3755 op
= ColorPatternBuffered
;
3758 else if (GC_COLEXP(msg
->gc
) == vHidd_GC_ColExp_Transparent
)
3760 DPUTPATTERN(bug("[PutPattern] JAM1\n"));
3761 op
= JAM1PatternBuffered
;
3763 else if (GC_DRMD(msg
->gc
) == vHidd_GC_DrawMode_Invert
)
3765 DPUTPATTERN(bug("[PutPattern] Complement\n"));
3766 op
= ComplementPatternBuffered
;
3770 DPUTPATTERN(bug("[PutPattern] JAM2\n"));
3771 op
= JAM2PatternBuffered
;
3775 data
.patarray
= (UWORD
*)msg
->pattern
;
3776 data
.patmask
= 0x8000 >> (msg
->patternsrcx
& 0xF);
3777 data
.maskarray
= msg
->mask
;
3778 data
.patternlut
= msg
->patternlut
? msg
->patternlut
->pixels
: NULL
;
3779 data
.patternsrcy
= msg
->patternsrcy
;
3780 data
.desty
= msg
->y
;
3781 data
.patternheight
= msg
->patternheight
;
3782 data
.patterndepth
= msg
->patterndepth
;
3783 data
.maskmodulo
= msg
->maskmodulo
;
3784 data
.fg
= GC_FG(msg
->gc
);
3785 data
.bg
= GC_BG(msg
->gc
);
3786 data
.invert
= msg
->invertpattern
? 0 : 0xFFFF;
3790 data
.maskarray
+= (msg
->masksrcx
/ 16) * 2;
3791 data
.maskmask
= 0x8000 >> (msg
->masksrcx
& 0xF);
3795 data
.maskmask
= 0xFFFF;
3797 DPUTPATTERN(bug("[PutPattern] MaskArray 0x%p, MaskMask 0x%04X\n", data
.maskarray
, data
.maskmask
));
3799 DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, get
, vHidd_StdPixFmt_Native32
, (VOID_FUNC
)op
, &data
);
3801 /* TODO: Write fallback */
3803 ReturnVoid("BitMap::PutPattern");
3806 /*****************************************************************************************
3809 moHidd_BitMap_PutImageLUT
3812 VOID OOP_DoMethod(OOP_Object *o, struct pHidd_BitMap_PutImageLUT *msg);
3814 VOID HIDD_BM_PutImageLUT (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
3815 WORD x, WORD y, WORD width, WORD height, HIDDT_PixelLUT *pixlut);
3844 *****************************************************************************************/
3846 VOID
BM__Hidd_BitMap__PutImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
3847 struct pHidd_BitMap_PutImageLUT
*msg
)
3850 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
3851 HIDDT_PixelLUT
*pixlut
= msg
->pixlut
;
3852 HIDDT_Pixel
*lut
= pixlut
? pixlut
->pixels
: NULL
;
3853 HIDDT_Pixel
*linebuf
;
3854 OOP_Object
*gc
= msg
->gc
;
3856 EnterFunc(bug("BitMap::PutImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
3857 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
3859 if (msg
->width
<= 0 || msg
->height
<= 0)
3862 linebuf
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
3864 for(y
= 0; y
< msg
->height
; y
++)
3870 for(x
= 0; x
< msg
->width
; x
++)
3872 linebuf
[x
] = lut
[pixarray
[x
]];
3877 for(x
= 0; x
< msg
->width
; x
++)
3879 linebuf
[x
] = pixarray
[x
];
3882 pixarray
+= msg
->modulo
;
3892 vHidd_StdPixFmt_Native32
);
3894 } /* if (linebuf) */
3899 /* Preserve old fg pen */
3904 for(x
= 0; x
< msg
->width
; x
++)
3906 GC_FG(gc
) = lut
[pixarray
[x
]];
3907 HIDD_BM_DrawPixel(o
, gc
, msg
->x
+ x
, msg
->y
+ y
);
3912 for(x
= 0; x
< msg
->width
; x
++)
3914 GC_FG(gc
) = pixarray
[x
];
3915 HIDD_BM_DrawPixel(o
, gc
, msg
->x
+ x
, msg
->y
+ y
);
3920 pixarray
+= msg
->modulo
;
3922 } /* if (linebuf) else ... */
3924 } /* for(y = 0; y < msg->height; y++) */
3928 ReturnVoid("BitMap::PutImageLUT");
3930 /*****************************************************************************************
3933 moHidd_BitMap_PutTranspImageLUT
3936 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutTranspImageLUT *msg);
3938 VOID HIDD_BM_PutTranspImageLUT (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels,
3939 ULONG modulo, WORD x, WORD y, WORD width, WORD height,
3940 HIDDT_PixelLUT *pixlut, UBYTE transparent);
3946 Copy an array of 8-bit LUT pixels to the bitmap at the specified position making
3947 one of colors transparent.
3949 Pixels are converted to bitmap's native format using either user-supplied LUT (if
3950 given) or bitmap's own colormap.
3952 Draw mode of the supplied GC is ignored, the operation is always bulk copy.
3955 obj - A bitmap to draw image on
3956 gc - A GC used for drawing
3957 pixels - A pointer to source pixel array
3958 modulo - Total number of bytes per line in the source array
3959 x, y - Top-left corner of the destination rectangle
3960 width - Width of the image to draw
3961 height - Height of the image to draw
3962 pixlut - An optional pointer to a LUT to use. NULL means using bitmap's
3963 own colormap (if available)
3964 transparent - Value of pixels in the source array which will be made
3980 *****************************************************************************************/
3982 #undef csd /* Bad hack, but there's no other way */
3989 struct class_static_data
*csd
;
3994 static void PutTranspImageLUTBuffered(ULONG
*xbuf
, UWORD starty
, UWORD width
, UWORD height
, struct ptilb_data
*data
)
3996 struct class_static_data
*csd
= data
->csd
;
3999 for (y
= 0; y
< height
; y
++)
4001 UBYTE
*pixarray
= data
->pixarray
;
4005 for (x
= 0; x
< width
; x
++)
4007 UBYTE pix
= *pixarray
++;
4009 if (pix
!= data
->transparent
)
4010 xbuf
[x
] = data
->lut
[pix
];
4016 for (x
= 0; x
< width
; x
++)
4018 UBYTE pix
= *pixarray
++;
4020 if (pix
!= data
->transparent
)
4023 pix
= HIDD_CM_GetPixel(data
->colmap
, pix
);
4032 data
->pixarray
+= data
->modulo
;
4036 VOID
BM__Hidd_BitMap__PutTranspImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
4037 struct pHidd_BitMap_PutTranspImageLUT
*msg
)
4039 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
4040 struct ptilb_data userdata
=
4050 EnterFunc(bug("BitMap::PutTranspImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
4051 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
4053 if (msg
->width
<= 0 || msg
->height
<= 0)
4057 userdata
.lut
= msg
->pixlut
->pixels
;
4059 DoBufferedOperation(cl
, o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
, TRUE
, vHidd_StdPixFmt_Native32
,
4060 (VOID_FUNC
)PutTranspImageLUTBuffered
, &userdata
);
4062 /* TODO: Write fallback */
4064 ReturnVoid("BitMap::PutTranspImageLUT");
4069 /*****************************************************************************************
4072 moHidd_BitMap_GetImageLUT
4075 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_GetImageLUT *msg);
4077 VOID HIDD_BM_GetImageLUT (OOP_Object *obj, UBYTE *pixels, ULONG modulo, WORD x, WORD y,
4078 WORD width, WORD height, HIDDT_PixelLUT *pixlut);
4106 *****************************************************************************************/
4108 VOID
BM__Hidd_BitMap__GetImageLUT(OOP_Class
*cl
, OOP_Object
*o
,
4109 struct pHidd_BitMap_GetImageLUT
*msg
)
4112 UBYTE
*pixarray
= (UBYTE
*)msg
->pixels
;
4113 HIDDT_PixelLUT
*pixlut
= msg
->pixlut
;
4114 HIDDT_Pixel
*lut
= pixlut
? pixlut
->pixels
: NULL
;
4115 HIDDT_Pixel
*linebuf
;
4117 EnterFunc(bug("BitMap::GetImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
4118 , msg
->x
, msg
->y
, msg
->width
, msg
->height
));
4120 linebuf
= AllocVec(msg
->width
* sizeof(HIDDT_Pixel
), MEMF_PUBLIC
);
4122 for(y
= 0; y
< msg
->height
; y
++)
4133 vHidd_StdPixFmt_Native32
);
4136 /* FIXME: This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway */
4137 for(x
= 0; x
< msg
->width
; x
++)
4139 pixarray
[x
] = (UBYTE
)linebuf
[x
];
4144 for(x
= 0; x
< msg
->width
; x
++)
4146 pixarray
[x
] = (UBYTE
)linebuf
[x
];
4149 pixarray
+= msg
->modulo
;
4151 } /* if (linebuf) */
4156 /* FIXME: This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway */
4157 for(x
= 0; x
< msg
->width
; x
++)
4159 pixarray
[x
] = (UBYTE
)HIDD_BM_GetPixel(o
, msg
->x
+ x
, msg
->y
+ y
);
4164 for(x
= 0; x
< msg
->width
; x
++)
4166 pixarray
[x
] = (UBYTE
)HIDD_BM_GetPixel(o
, msg
->x
+ x
, msg
->y
+ y
);
4170 pixarray
+= msg
->modulo
;
4172 } /* if (linebuf) else ... */
4174 } /* for(y = 0; y < msg->height; y++) */
4178 ReturnVoid("BitMap::GetImageLUT");
4181 /*****************************************************************************************
4184 moHidd_BitMap_BlitColorExpansion
4187 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BlitColorExpansion *msg);
4189 VOID HIDD_BM_BlitColorExpansion (OOP_Object *obj, OOP_Object *gc, OOP_Object *srcBitMap,
4190 WORD srcX, WORD srcY, WORD destX, WORD destY,
4191 UWORD width, UWORD height);
4197 Perform a color expansion of the mask in srcBitMap according to foreground and background
4198 colors and expansion mode specified by the supplied GC. Pixels which are set to zero in
4199 the mask bitmap will be either painted by background (in opaque mode) or left without
4200 change (in transparent mode). Pixels which are set to nonzero in the mask will be painted
4201 by foreground color.
4203 The result of expansion is blitted onto the destination bitmap accorging to GC's draw mode.
4206 obj - A bitmap to draw on
4207 gc - A GC object to use for drawing
4208 srcBitMap - A bitmap object containing mask image.
4209 srcX, srcY - A top-left coordinate of the used rectangle in the source bitmap
4210 destX, destY - A top-left coordinate of the destination rectangle to draw in
4211 width, height - A size of the rectangle to blit
4217 This method was previously used by graphics.library/Text() to draw fonts with no
4218 styles specified. Currently graphics.library always uses BltTemplate() and this
4219 method is considered obsolete.
4229 *****************************************************************************************/
4231 VOID
BM__Hidd_BitMap__BlitColorExpansion(OOP_Class
*cl
, OOP_Object
*o
,
4232 struct pHidd_BitMap_BlitColorExpansion
*msg
)
4239 OOP_Object
*gc
= msg
->gc
;
4241 EnterFunc(bug("BitMap::BlitColorExpansion(srcBM=%p, srcX=%d, srcY=%d, destX=%d, destY=%d, width=%d, height=%d)\n",
4242 msg
->srcBitMap
, msg
->srcX
, msg
->srcY
, msg
->destX
, msg
->destY
, msg
->width
, msg
->height
));
4244 cemd
= GC_COLEXP(gc
);
4248 /* bug("------------- Blit_ColExp: (%d, %d, %d, %d, %d, %d) cemd=%d, fg=%p, bg=%p -------------\n"
4249 , msg->srcX, msg->srcY, msg->destX, msg->destY, msg->width, msg->height
4252 for (y
= 0; y
< msg
->height
; y
++)
4254 for (x
= 0; x
< msg
->width
; x
++)
4258 /* Pixel value is either 0 or 1 for BM of depth 1 */
4259 is_set
= HIDD_BM_GetPixel(msg
->srcBitMap
, x
+ msg
->srcX
, y
+ msg
->srcY
);
4269 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->destX
, y
+ msg
->destY
);
4273 if (cemd
& vHidd_GC_ColExp_Opaque
)
4275 /* Write bixel with BG pen */
4277 HIDD_BM_DrawPixel(o
, gc
, x
+ msg
->destX
, y
+ msg
->destY
);
4278 /* Reset to FG pen */
4284 } /* for (each x) */
4288 } /* for ( each y ) */
4291 ReturnVoid("BitMap::BlitColorExpansion");
4294 /*****************************************************************************************
4297 moHidd_BitMap_BytesPerLine
4300 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BytesPerLine *msg);
4302 ULONG HIDD_BM_BytesPerLine(OOP_Object *obj, HIDDT_StdPixFmt pixFmt, UWORD width);
4308 This method is currently not used and reserved.
4327 *****************************************************************************************/
4329 ULONG
BM__Hidd_BitMap__BytesPerLine(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_BytesPerLine
*msg
)
4334 switch (msg
->pixFmt
)
4336 case vHidd_StdPixFmt_Native32
:
4337 bpl
= sizeof (HIDDT_Pixel
) * msg
->width
;
4340 case vHidd_StdPixFmt_Native
:
4342 struct HIDDBitMapData
*data
;
4344 data
= OOP_INST_DATA(cl
, o
);
4346 bpl
= ((HIDDT_PixelFormat
*)data
->prot
.pixfmt
)->bytes_per_pixel
* msg
->width
;
4353 struct HIDDBitMapData
*data
;
4355 data
= OOP_INST_DATA(cl
, o
);
4357 pf
= HIDD_Gfx_GetPixFmt(data
->gfxhidd
, msg
->pixFmt
);
4361 D(bug("!!! COULD NOT GET STD PIXFMT IN BitMap::BytesPerLine() !!!\n"));
4365 bpl
= ((HIDDT_PixelFormat
*)pf
)->bytes_per_pixel
* msg
->width
;
4377 /****************************************************************************************/
4380 This makes it easier to create a subclass of the graphics hidd.
4381 It is only allowed to use this method in the p_RootNew method of a
4385 /****************************************************************************************/
4387 IPTR
BM__Root__Set(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_Set
*msg
)
4389 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
4390 struct Library
*OOPBase
= CSD(cl
)->cs_OOPBase
;
4391 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, obj
);
4392 struct TagItem
*tag
, *tstate
;
4394 WORD xoffset
, yoffset
;
4396 if (data
->framebuffer
)
4399 * If this is a framebuffer, we can process ModeID change.
4400 * We do it before parsing the rest of tags, because here we retrieve
4401 * defaults for new bitmap parameters (size and pixelformat).
4402 * They can be overridden by other tags. For example we can imagine
4403 * a hardware scrollable framebuffer whose width and height are larger
4404 * than visible part.
4406 HIDDT_ModeID modeid
= GetTagData(aHidd_BitMap_ModeID
, vHidd_ModeID_Invalid
, msg
->attrList
);
4407 OOP_Object
*sync
, *pixfmt
;
4409 if (HIDD_Gfx_GetMode(data
->gfxhidd
, modeid
, &sync
, &pixfmt
))
4411 data
->modeid
= modeid
;
4413 * Set defaults based on the ModeID.
4414 * They can be overriden lated, in SetBitMapTags.
4416 data
->width
= OOP_GET(sync
, aHidd_Sync_HDisp
);
4417 data
->height
= OOP_GET(sync
, aHidd_Sync_VDisp
);
4418 data
->bytesPerRow
= GetBytesPerRow(data
, CSD(cl
));
4419 data
->prot
.pixfmt
= pixfmt
;
4423 /* Bad ModeID given, request rejected */
4427 /* Process the rest of tags. */
4428 BM__Hidd_BitMap__SetBitMapTags(cl
, obj
, msg
->attrList
);
4433 * This is not a framebuffer.
4434 * We can modify size data (CHECKME: is it really used anywhere ?)
4435 * and also we can scroll (makes sense only if this is displayable
4436 * bitmap in mirrored framebuffer mode.
4438 BM__Hidd_BitMap__SetBitMapTags(cl
, obj
, msg
->attrList
);
4441 * And now we process position change.
4442 * One trick: we store our 'display' rectangle in bitmap's coordinates.
4443 * In other words, these are screen coordinates relative to bitmap, not
4444 * bitmap's ones relative to screen. As a result, we have to invert the sign.
4445 * This is done in order to simplify calculations in UpdateBitMap method of
4446 * graphics base class. It needs to perform intersection of update rectangle
4447 * with display rectangle, and they need to be in the same coordinate system
4448 * in order to be able to do this.
4449 * Update operation is performance-critical, so we perform this conversion
4450 * for display rectangle here.
4452 xoffset
= data
->display
.MinX
;
4453 yoffset
= data
->display
.MinY
;
4454 tstate
= msg
->attrList
;
4455 while ((tag
= NextTagItem(&tstate
)))
4457 Hidd_BitMap_Switch(tag
->ti_Tag
, idx
)
4459 case aoHidd_BitMap_LeftEdge
:
4460 xoffset
= tag
->ti_Data
;
4463 * Our bitmap cannot be smaller than display size because of fakegfx.hidd
4464 * limitations (it can't place cursor beyond bitmap edges). Otherwise Intuition
4465 * will provide strange user experience (mouse cursor will disappear)
4467 if (xoffset
>= (WORD
)data
->displayWidth
)
4468 xoffset
= data
->displayWidth
- 1;
4469 else if (xoffset
<= (WORD
)-data
->width
)
4470 xoffset
= -(data
->width
- 1);
4472 D(bug("[BitMap] xoffset requested %ld, got %d\n", -tag
->ti_Data
, xoffset
));
4475 case aoHidd_BitMap_TopEdge
:
4476 /* Only offsets that ensure at least some of the bitmap is
4478 yoffset
= tag
->ti_Data
;
4479 if (yoffset
>= (WORD
)data
->displayHeight
)
4480 yoffset
= data
->displayHeight
- 1;
4481 else if (yoffset
<= (WORD
)-data
->height
)
4482 yoffset
= -(data
->height
- 1);
4484 D(bug("[BitMap] yoffset requested %ld, got %d\n", -tag
->ti_Data
, yoffset
));
4489 if ((xoffset
!= data
->display
.MinX
) || (yoffset
!= data
->display
.MinY
))
4491 ObtainSemaphore(&data
->lock
);
4493 data
->display
.MinX
= xoffset
;
4494 data
->display
.MinY
= yoffset
;
4495 data
->display
.MaxX
= xoffset
+ data
->displayWidth
;
4496 data
->display
.MaxY
= yoffset
+ data
->displayHeight
;
4500 GFXHIDD__Hidd_Gfx__UpdateFB(CSD(cl
)->gfxhiddclass
, data
->gfxhidd
,
4501 obj
, data
->display
.MinX
, data
->display
.MinY
,
4502 0, 0, data
->displayWidth
, data
->displayHeight
);
4505 ReleaseSemaphore(&data
->lock
);
4509 /* There's no superclass above us */
4513 /*****************************************************************************************
4516 moHidd_BitMap_SetColorMap
4519 OOP_Object * OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetColorMap *msg);
4521 OOP_Object * HIDD_BM_SetColorMap(OOP_Object *obj, OOP_Object *colorMap);
4544 *****************************************************************************************/
4546 OOP_Object
*BM__Hidd_BitMap__SetColorMap(OOP_Class
*cl
, OOP_Object
*o
,
4547 struct pHidd_BitMap_SetColorMap
*msg
)
4549 struct HIDDBitMapData
*data
;
4552 data
= OOP_INST_DATA(cl
, o
);
4555 data
->colmap
= msg
->colorMap
;
4560 /*****************************************************************************************
4563 moHidd_BitMap_MapColor
4566 HIDDT_Pixel OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_MapColor *msg);
4568 HIDDT_Pixel HIDD_BM_MapColor(OOP_Object *obj, HIDDT_Color *color);
4591 *****************************************************************************************/
4593 /* We only care about magnitudes here, so we don't
4594 * have to perform the square root operation to get
4595 * the real distance.
4597 static ULONG
colorDistance(HIDDT_Color
*a
, HIDDT_Color
*b
)
4599 #define SQR(x) ((x) * (x))
4600 return SQR((int)a
->red
- (int)b
->red
) +
4601 SQR((int)a
->blue
- (int)b
->blue
) +
4602 SQR((int)a
->green
- (int)b
->green
) +
4603 SQR((int)a
->alpha
- (int)b
->alpha
);
4607 HIDDT_Pixel
BM__Hidd_BitMap__MapColor(OOP_Class
*cl
, OOP_Object
*o
,
4608 struct pHidd_BitMap_MapColor
*msg
)
4610 HIDDT_PixelFormat
*pf
= BM_PIXFMT(o
);
4612 HIDDT_Pixel red
= msg
->color
->red
;
4613 HIDDT_Pixel green
= msg
->color
->green
;
4614 HIDDT_Pixel blue
= msg
->color
->blue
;
4615 HIDDT_Pixel alpha
= msg
->color
->alpha
;
4617 /* This code assumes that sizeof(HIDDT_Pixel) is a multiple of sizeof(col->#?),
4618 which should be true for most (all?) systems. I have never heard
4619 of any system with for example 3 byte types.
4622 if (IS_TRUECOLOR(pf
))
4624 if (HIDD_PF_SWAPPIXELBYTES(pf
))
4626 /* FIXME: BM__Hidd_BitMap__MapColor assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats */
4628 HIDDT_Pixel pixel
= MAP_RGBA(red
, green
, blue
, alpha
, pf
);
4630 msg
->color
->pixval
= SWAPBYTES_WORD(pixel
);
4634 msg
->color
->pixval
= MAP_RGBA(red
, green
, blue
, alpha
, pf
);
4639 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
4641 HIDDT_ColorLUT
*cmap
;
4643 ULONG best_ndx
= ~0, best_dist
= ~0;
4645 cmap
= (HIDDT_ColorLUT
*)data
->colmap
;
4646 ctab
= cmap
->colors
;
4647 /* Search for the best match in the color table */
4648 for (i
= 0; i
< cmap
->entries
; i
++) {
4651 dist
= colorDistance(&ctab
[i
], msg
->color
);
4652 if (dist
< best_dist
) {
4658 if (best_dist
!= ~0)
4659 msg
->color
->pixval
= ctab
[best_ndx
].pixval
;
4662 return msg
->color
->pixval
;
4665 /*****************************************************************************************
4668 moHidd_BitMap_UnmapPixel
4671 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_UnmapPixel *msg);
4673 VOID HIDD_BM_UnmapPixel(OOP_Object *obj, HIDDT_Pixel pixel, HIDDT_Color *color);
4697 *****************************************************************************************/
4699 VOID
BM__Hidd_BitMap__UnmapPixel(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_UnmapPixel
*msg
)
4702 HIDDT_PixelFormat
*pf
= BM_PIXFMT(o
);
4704 if (IS_TRUECOLOR(pf
))
4706 HIDDT_Pixel pixel
= msg
->pixel
;
4708 if (HIDD_PF_SWAPPIXELBYTES(pf
))
4710 /* FIXME: bitmap_unmappixel assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats */
4711 pixel
= SWAPBYTES_WORD(pixel
);
4714 msg
->color
->red
= RED_COMP (pixel
, pf
);
4715 msg
->color
->green
= GREEN_COMP (pixel
, pf
);
4716 msg
->color
->blue
= BLUE_COMP (pixel
, pf
);
4717 msg
->color
->alpha
= ALPHA_COMP (pixel
, pf
);
4721 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
4722 HIDDT_ColorLUT
*clut
;
4724 clut
= (HIDDT_ColorLUT
*)data
->colmap
;
4728 /* FIXME: Use CLUT shift and CLUT mask here */
4729 if (msg
->pixel
< 0 || msg
->pixel
>= clut
->entries
)
4732 *msg
->color
= clut
->colors
[msg
->pixel
];
4736 /* Unnecessary, but... */
4737 msg
->color
->pixval
= msg
->pixel
;
4740 /*****************************************************************************************
4743 moHidd_BitMap_ObtainDirectAccess
4746 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_ObtainDirectAccess *msg);
4748 BOOL HIDD_BM_ObtainDirectAccess(OOP_Object *obj, UBYTE **addressReturn,
4749 ULONG *widthReturn, ULONG *heightReturn,
4750 ULONG *bankSizeReturn, ULONG *memSizeReturn);
4778 *****************************************************************************************/
4780 BOOL
BM__Hidd_BitMap__ObtainDirectAccess(OOP_Class
*cl
, OOP_Object
*o
,
4781 struct pHidd_BitMap_ObtainDirectAccess
*msg
)
4783 /* Default implementation of direct access funcs. Just return FALSE */
4787 /*****************************************************************************************
4790 moHidd_BitMap_ReleaseDirectAccess
4793 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_ReleaseDirectAccess *msg);
4795 VOID HIDD_BM_ReleaseDirectAccess(OOP_Object *obj);
4817 *****************************************************************************************/
4819 VOID
BM__Hidd_BitMap__ReleaseDirectAccess(OOP_Class
*cl
, OOP_Object
*o
,
4820 struct pHidd_BitMap_ReleaseDirectAccess
*msg
)
4822 D(bug("!!! BitMap BaseClasse ReleaseDirectAccess() called !!!\n"));
4823 D(bug("!!! This should never happen and is probably due to a buggy implementation in the subclass !!!\n"));
4828 /*****************************************************************************************
4831 moHidd_BitMap_BitMapScale
4834 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BitMapScale * msg);
4836 VOID HIDD_BM_BitMapScale(OOP_Object *obj, OOP_Object *src, OOP_Object *dest,
4837 struct BitScaleArgs * bsa, OOP_Object *gc);
4863 *****************************************************************************************/
4865 VOID
BM__Hidd_BitMap__BitMapScale(OOP_Class
* cl
, OOP_Object
*o
,
4866 struct pHidd_BitMap_BitMapScale
* msg
)
4868 struct BitScaleArgs
*bsa
= msg
->bsa
;
4869 ULONG
*srcbuf
, *dstbuf
;
4873 UWORD ys
= bsa
->bsa_SrcY
;
4874 UWORD xs
= bsa
->bsa_SrcX
;
4875 UWORD dyd
= bsa
->bsa_DestHeight
;
4876 UWORD dxd
= bsa
->bsa_DestWidth
;
4879 UWORD dxs
= bsa
->bsa_SrcWidth
;
4880 UWORD dys
= bsa
->bsa_SrcHeight
;
4881 LONG accuyd
= - (dys
>> 1);
4882 LONG accuxd
= - (dxs
>> 1);
4885 if ((srcbuf
= AllocVec(bsa
->bsa_SrcWidth
* sizeof(ULONG
), 0)) == NULL
)
4888 if ((dstbuf
= AllocVec(bsa
->bsa_DestWidth
* sizeof(ULONG
), 0)) == NULL
) {
4893 if ((linepattern
= (UWORD
*) AllocVec(bsa
->bsa_DestWidth
* sizeof(UWORD
), 0)) == NULL
) {
4900 while (count
< bsa
->bsa_DestWidth
) {
4902 while (accuxd
> accuxs
) {
4907 linepattern
[count
] = xs
;
4912 count
= bsa
->bsa_DestY
;
4913 while (count
< bsa
->bsa_DestHeight
+ bsa
->bsa_DestY
) {
4915 while (accuyd
> accuys
) {
4920 if (srcline
!= ys
) {
4921 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
);
4924 for (x
= 0; x
< bsa
->bsa_DestWidth
; x
++)
4925 dstbuf
[x
] = srcbuf
[linepattern
[x
]];
4928 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
);
4933 FreeVec(linepattern
);
4939 /*****************************************************************************************
4942 moHidd_BitMap_SetRGBConversionFunction
4945 HIDDT_RGBConversionFunction
4946 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetRGBConversionFunction *msg);
4948 HIDDT_RGBConversionFunction
4949 HIDD_BM_SetRGBConversionFunction(OOP_Object *obj, HIDDT_StdPixFmt srcPixFmt,
4950 HIDDT_StdPixFmt dstPixFmt,
4951 HIDDT_RGBConversionFunction function);
4972 *****************************************************************************************/
4974 HIDDT_RGBConversionFunction
BM__Hidd_BitMap__SetRGBConversionFunction(OOP_Class
* cl
, OOP_Object
*o
,
4975 struct pHidd_BitMap_SetRGBConversionFunction
* msg
)
4977 HIDDT_RGBConversionFunction old
;
4979 if ((msg
->srcPixFmt
< FIRST_RGB_STDPIXFMT
) ||
4980 (msg
->dstPixFmt
< FIRST_RGB_STDPIXFMT
) ||
4981 (msg
->srcPixFmt
> LAST_RGB_STDPIXFMT
) ||
4982 (msg
->dstPixFmt
> LAST_RGB_STDPIXFMT
))
4984 return (HIDDT_RGBConversionFunction
)-1;
4988 ObtainSemaphore(&CSD(cl
)->rgbconvertfuncs_sem
);
4989 old
= CSD(cl
)->rgbconvertfuncs
[msg
->srcPixFmt
- FIRST_RGB_STDPIXFMT
][msg
->dstPixFmt
- FIRST_RGB_STDPIXFMT
];
4990 CSD(cl
)->rgbconvertfuncs
[msg
->srcPixFmt
- FIRST_RGB_STDPIXFMT
][msg
->dstPixFmt
- FIRST_RGB_STDPIXFMT
] = msg
->function
;
4991 ReleaseSemaphore(&CSD(cl
)->rgbconvertfuncs_sem
);
4997 /*****************************************************************************************
5000 moHidd_BitMap_UpdateRect
5003 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_UpdateRect *msg);
5005 VOID HIDD_BM_UpdateRect(OOP_Object *obj, WORD x, WORD y, WORD width, WORD height);
5011 Update displayed image of the given rectangle.
5013 Some drivers (like VGA and VESA) may work not with VRAM directly, but with a mirrored
5014 copy of it. Usually it is done in case if VRAM reading is slow. This method is called
5015 by the system after it completes any drawing operation, in order to make sure that
5016 changes made are visible on the actual screen. If your driver uses mirroring, this method
5017 should copy the given rectangle (at least) from the mirror buffer to the actual VRAM.
5019 This method is also called after changing currently visible bitmap (after moHidd_Gfx_Show
5020 method call) in order to allow the mirroring driver to refresh the screen after current bitmap
5021 changed. Note that moHidd_Gfx_ShowViewPorts is very different and moHidd_BitMap_UpdateRect
5022 will not be called if it succeeded!
5025 obj - an object whose image to refresh
5026 x, y - A top-left edge of the rectangle to refresh
5027 width - Width of the rectangle to refresh
5028 height - Height of the rectangle to refresh
5034 This method is called also on offscreen bitmaps. You should track visible state of your bitmap
5035 and ignore these calls if it's not currently visible on the screen.
5045 *****************************************************************************************/
5047 VOID
BM__Hidd_BitMap__UpdateRect(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_BitMap_UpdateRect
*msg
)
5049 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
5051 DUPDATE(bug("[BitMap] UpdateRect(0x%p, %d, %d, %d, %d)\n", o
, msg
->x
, msg
->y
, msg
->width
, msg
->height
));
5054 * We check data->visible twice in order to avoid unnecessary locking
5055 * when our bitmap is not on display (it may be not displayable at all).
5056 * However the second check is still needed in order to make sure that
5057 * this bitmap is still on display, because we could be preempted between
5058 * the test and ObtainSemaphoreShared() by concurrently running Show() call.
5059 * We use shared lock because it's safe to have two concurrently running
5060 * updates even on the same region.
5064 ObtainSemaphoreShared(&data
->lock
);
5069 * Complete update rectangle.
5070 * Display rectangle is already in bitmap's coordinates.
5072 UWORD srcX
= msg
->x
;
5073 UWORD srcY
= msg
->y
;
5074 UWORD xLimit
= srcX
+ msg
->width
;
5075 UWORD yLimit
= srcY
+ msg
->height
;
5077 /* Intersect rectangles */
5078 if (data
->display
.MinX
> srcX
)
5079 srcX
= data
->display
.MinX
;
5080 if (data
->display
.MinY
> srcY
)
5081 srcY
= data
->display
.MinY
;
5082 if (data
->display
.MaxX
< xLimit
)
5083 xLimit
= data
->display
.MaxX
;
5084 if (data
->display
.MaxY
< yLimit
)
5085 yLimit
= data
->display
.MaxY
;
5087 /* Update the intersection region, if any */
5088 if ((xLimit
> srcX
) && (yLimit
> srcY
))
5090 GFXHIDD__Hidd_Gfx__UpdateFB(CSD(cl
)->gfxhiddclass
, data
->gfxhidd
,
5092 srcX
- data
->display
.MinX
, srcY
- data
->display
.MinY
,
5093 xLimit
- srcX
, yLimit
- srcY
);
5097 ReleaseSemaphore(&data
->lock
);
5101 /****************************************************************************************/
5104 * Private methods follow.
5105 * They are implemented as non-virtual, for speed up.
5108 /* This is a private form of Set method. Doesn't need a standard message. */
5109 void BM__Hidd_BitMap__SetBitMapTags(OOP_Class
*cl
, OOP_Object
*o
, struct TagItem
*bitMapTags
)
5111 struct Library
*UtilityBase
= CSD(cl
)->cs_UtilityBase
;
5112 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
5113 struct TagItem
*tag
;
5115 while ((tag
= NextTagItem(&bitMapTags
)))
5119 if (IS_BITMAP_ATTR(tag
->ti_Tag
, idx
))
5123 case aoHidd_BitMap_Width
:
5124 data
->width
= tag
->ti_Data
;
5127 case aoHidd_BitMap_Height
:
5128 data
->height
= tag
->ti_Data
;
5131 case aoHidd_BitMap_BytesPerRow
:
5132 data
->bytesPerRow
= tag
->ti_Data
;
5135 case aoHidd_BitMap_Compositable
:
5136 data
->compositable
= tag
->ti_Data
;
5137 if (data
->compositable
)
5139 HIDDT_ModeID compositmodeid
;
5140 struct Library
*OOPBase
= csd
->cs_OOPBase
;
5144 OOP_GetAttr(data
->friend, aHidd_BitMap_ModeID
, &compositmodeid
);
5147 compositmodeid
= data
->modeid
;
5149 if (compositmodeid
== vHidd_ModeID_Invalid
)
5151 data
->compositable
= FALSE
;
5155 OOP_Object
*sync
, *pf
;
5157 if (!HIDD_Gfx_GetMode(data
->gfxhidd
, compositmodeid
, &sync
, &pf
))
5159 data
->compositable
= FALSE
;
5163 /* Get display size from the modeid */
5164 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &data
->displayWidth
);
5165 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &data
->displayHeight
);
5166 data
->display
.MaxX
= data
->displayWidth
;
5167 data
->display
.MaxY
= data
->displayHeight
;
5169 D(bug("[BitMap] Bitmap %dx%d, display %dx%d\n",
5170 data
->width
, data
->height
,
5171 data
->displayWidth
, data
->displayHeight
));
5181 * Updates bitmap's pixelformat.
5182 * Used from within planarbm subclass, and would be extremely dangerous to expose
5183 * as setable aHidd_BitMap_PixFmt, so implemented as a separate method.
5185 void BM__Hidd_BitMap__SetPixFmt(OOP_Class
*cl
, OOP_Object
*o
, OOP_Object
*pf
)
5187 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
5189 /* Already a pixfmt registered? */
5190 if (data
->pf_registered
)
5191 GFXHIDD__Hidd_Gfx__ReleasePixFmt(CSD(cl
)->gfxhiddclass
, data
->prot
.pixfmt
);
5193 /* Remember the new pixelformat */
5194 data
->prot
.pixfmt
= pf
;
5197 * This pixelformat was obtained using GFXHIDD__Hidd_Gfx__RegisterPixFmt().
5198 * It increases number of pixfmt users, so we'll need to release it when
5199 * not used any more.
5201 data
->pf_registered
= TRUE
;
5205 * Change visible state of the bitmap.
5206 * Used in mirrored framebuffer mode. Actually needed because
5207 * of semaphore barrier, which makes sure that bitmap state does
5208 * not change during scrolling or updating operation. Prevents possibilities
5209 * of screen corruption during concurrently running scrolling with Show.
5211 void BM__Hidd_BitMap__SetVisible(OOP_Class
*cl
, OOP_Object
*o
, BOOL val
)
5213 struct HIDDBitMapData
*data
= OOP_INST_DATA(cl
, o
);
5215 ObtainSemaphore(&data
->lock
);
5216 data
->visible
= val
;
5217 ReleaseSemaphore(&data
->lock
);