forcing device into host mode requires a full config - which we will do in opendevice...
[AROS.git] / rom / hidds / graphics / BM_Class.c
blobcc589bce5235b7c7b3ad438338883f51691408e7
1 /*
2 Copyright © 1995-2013, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics bitmap class implementation.
6 Lang: english
7 */
9 /****************************************************************************************/
11 #define SDEBUG 0
12 #define DEBUG 0
13 #define DPUTPATTERN(x)
15 #include <aros/debug.h>
16 #include <proto/exec.h>
17 #include <proto/utility.h>
18 #include <proto/oop.h>
19 #include <exec/memory.h>
20 #include <utility/tagitem.h>
21 #include <oop/oop.h>
22 #include <oop/static_mid.h>
23 #include <graphics/text.h>
24 #include <graphics/scale.h>
25 #include <hidd/graphics.h>
27 #include <string.h>
28 #include <stdlib.h>
31 #include "graphics_intern.h"
33 /****************************************************************************************/
35 #define POINT_OUTSIDE_CLIP(gc, x, y) \
36 ( (x) < GC_CLIPX1(gc) \
37 || (x) > GC_CLIPX2(gc) \
38 || (y) < GC_CLIPY1(gc) \
39 || (y) > GC_CLIPY2(gc) )
41 /*****************************************************************************************
43 NAME
44 --background_bitmap--
46 LOCATION
47 hidd.graphics.bitmap
49 NOTES
50 Every display driver should implement at least one bitmap class for displayable
51 bitmaps.
53 Normally this class doesn't need to have public ID. In order to use it the driver
54 should pass class pointer as aoHidd_BitMap_ClassPtr value to the graphics base class
55 in its moHidd_Gfx_NewBitMap implementation.
57 BitMap base class is in C++ terminology a pure virtual
58 baseclass. It will not allocate any bitmap data at all;
59 that is up to the subclass to do.
61 The main task of the BitMap baseclass is to store some information about the bitmap
62 like its size and pixelformat. A pixelformat is an object of private class which
63 stores the actual information about the format.
65 There are two ways that we can find out the pixfmt in our moHidd_Gfx_NewBitMap
66 implementation:
68 Displayable bitmap -
69 The tags will contain a modeid.
70 One can use this modeid to get a pointer to an
71 already registered pixfmt.
73 Non-displayable bitmap -
74 The aoHidd_BitMap_StdPixFmt or aoHidd_BitMap_Friend attribute will always be
75 passed.
77 *****************************************************************************************/
79 #define PIXBUFBYTES 16384
81 static BOOL DoBufferedOperation(OOP_Class *cl, OOP_Object *o, UWORD startx, UWORD starty, UWORD width, UWORD height,
82 BOOL getimage, HIDDT_StdPixFmt stdpf, VOID_FUNC operation, void *userdata)
84 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
85 ULONG bytesperline = width * sizeof(ULONG);
86 UWORD buflines = PIXBUFBYTES / 4; /* Remove slow division */
87 ULONG bufsize;
88 UWORD endy = starty + height;
89 UWORD y;
90 UBYTE *buf;
92 if (buflines == 0)
93 buflines = 1;
94 else if (buflines > height)
95 buflines = height;
97 bufsize = buflines * bytesperline;
98 buf = AllocMem(bufsize, MEMF_PUBLIC);
99 if (!buf && (buflines > 1))
101 /* Try to allocate single-line buffer */
102 buflines = 1;
103 bufsize = bytesperline;
104 buf = AllocMem(bufsize, MEMF_PUBLIC);
106 if (!buf)
107 return FALSE;
109 for (y = starty; y < endy; y += buflines)
111 if (y + buflines > endy)
113 /* This prevents overflow on last pass, buffer may be used only partially */
114 buflines = endy - y;
117 if (getimage)
119 /* For some operations this can be optimized away */
120 HIDD_BM_GetImage(o, buf, bytesperline, startx, y, width, buflines, stdpf);
123 operation(buf, y, width, buflines, userdata);
125 HIDD_BM_PutImage(o, data->gc, buf, bytesperline, startx, y, width, buflines, stdpf);
128 FreeMem(buf, bufsize);
129 return TRUE;
132 /*****************************************************************************************
134 NAME
135 aoHidd_BitMap_Width
137 SYNOPSIS
138 [ISG], UWORD
140 LOCATION
141 hidd.graphics.bitmap
143 FUNCTION
144 Specifies bitmap width in pixels.
146 Setting this attribute does not cause actual bitmap resize, just updates the information
147 about it. Use this only from within subclasses only if you know what you do. For example
148 SDL hosted driver sets it when framebufer changes the resolution.
150 NOTES
152 EXAMPLE
154 BUGS
156 SEE ALSO
157 aoHidd_BitMap_Height
159 INTERNALS
161 *****************************************************************************************/
163 /*****************************************************************************************
165 NAME
166 aoHidd_BitMap_Height
168 SYNOPSIS
169 [ISG], UWORD
171 LOCATION
172 hidd.graphics.bitmap
174 FUNCTION
175 Specifies bitmap height in pixels.
177 Setting this attribute does not cause actual bitmap resize, just updates the information
178 about it. Use this only from within subclasses only if you know what you do. For example
179 SDL hosted driver sets it when framebufer changes the resolution.
181 NOTES
183 EXAMPLE
185 BUGS
187 SEE ALSO
188 aoHidd_BitMap_Width
190 INTERNALS
192 *****************************************************************************************/
194 /*****************************************************************************************
196 NAME
197 aoHidd_BitMap_Displayable
199 SYNOPSIS
200 [I.G], BOOL
202 LOCATION
203 hidd.graphics.bitmap
205 FUNCTION
206 The bitmap is displayable. A displayable bitmap is always managed by a display
207 driver and must have valid display mode ID specification.
209 If this attribute is not supplied during bitmap creation, its value defaults
210 to FALSE.
212 NOTES
214 EXAMPLE
216 BUGS
218 SEE ALSO
219 aoHidd_BitMap_ModeID
221 INTERNALS
223 *****************************************************************************************/
225 /*****************************************************************************************
227 NAME
228 aoHidd_BitMap_Visible
230 SYNOPSIS
231 [..G], BOOL
233 LOCATION
234 hidd.graphics.bitmap
236 FUNCTION
237 Check if the bitmap is currently visible on screen
239 NOTES
241 EXAMPLE
243 BUGS
244 Not all display drivers implement this attribute. No AROS components currently rely
245 on its value.
247 SEE ALSO
249 INTERNALS
250 Some drivers may choose to have this attribute internally setable. Do not rely on it
251 in any way and do not attempt to set it manually from within applications, this will
252 not do any nice things.
254 *****************************************************************************************/
256 /*****************************************************************************************
258 NAME
259 aoHidd_BitMap_IsLinearMem
261 SYNOPSIS
262 [..G], BOOL
264 LOCATION
265 hidd.graphics.bitmap
267 FUNCTION
268 Check if the bitmap provides linear memory access. This means that bitmap's
269 pixelbuffer is directly addressable by the CPU.
271 Bitmaps with no linear memory may implement moHidd_BitMap_ObtainDirectAccess,
272 but this means that this method will rely on mirrored buffer. In such a case
273 the user must call moHidd_BitMap_UpdateRect after modifying bitmap's contents.
275 NOTES
276 Used by cybergraphics.library/GetCyberMapAttr() for providing CYBRMATTR_ISLINEARMEM
277 value.
279 EXAMPLE
281 BUGS
282 Currently no display drivers implement this attribute despite many native mode
283 drivers actually provide linear memory.
285 SEE ALSO
286 moHidd_BitMap_ObtainDirectAccess, moHidd_BitMap_ReleaseDirectAccess,
287 moHidd_BitMap_UpdateRect
289 INTERNALS
291 *****************************************************************************************/
293 /*****************************************************************************************
295 NAME
296 aoHidd_BitMap_BytesPerRow
298 SYNOPSIS
299 [ISG], ULONG
301 LOCATION
302 hidd.graphics.bitmap
304 FUNCTION
305 Specify or query number of bytes per row in the bitmap storage buffer.
307 Setting this attribute doesn't actually cause changing buffer layout, just updates
308 the information about it. Use this only from within subclasses and only if you
309 exactly know why you do this.
311 Specifying this attribute during object creation overrides the value calculated
312 based on aoHidd_BitMap_Width and aoHidd_BitMap_Align values. Useful for wrapping
313 own buffers into bitmap objects, for example, in conjunction with
314 aoHidd_ChunkyBM_Buffer.
316 NOTES
317 The returned value includes possible padding needed for alignment.
319 EXAMPLE
321 BUGS
323 SEE ALSO
324 aoHidd_BitMap_Align
326 INTERNALS
328 *****************************************************************************************/
330 /*****************************************************************************************
332 NAME
333 aoHidd_BitMap_ColorMap
335 SYNOPSIS
336 [..G], OOP_Object *
338 LOCATION
339 hidd.graphics.bitmap
341 FUNCTION
342 Return associated colormap (palette) object.
344 By default only displayable bitmaps have colormaps. However a colormap can be attached
345 to any bitmap using moHidd_BitMap_SetColors or moHidd_BitMap_SetColorMap.
347 Note that manual attaching of a colormap to a nondisplayable bitmap may cause undesired
348 side-effects on graphics.library behavior. It's better not to do this at all. The system
349 knows what it does better than you.
351 NOTES
353 EXAMPLE
355 BUGS
357 SEE ALSO
358 moHidd_BitMap_SetColorMap, moHidd_BitMap_SetColors.
360 INTERNALS
362 *****************************************************************************************/
364 /*****************************************************************************************
366 NAME
367 aoHidd_BitMap_Friend
369 SYNOPSIS
370 [I.G], OOP_Object *
372 LOCATION
373 hidd.graphics.bitmap
375 FUNCTION
376 Specify a friend bitmap. The bitmap will be allocated so that it
377 is optimized for blitting to this bitmap.
379 Display drivers may query this attribute and then query friend bitmap
380 for anything they want (like pixelformat, mode ID, etc).
382 Note that explicit specification of mode ID and/or standard pixelformat
383 should override defaults provided by friend bitmap (i.e. actually breaking
384 the friendship).
386 NOTES
388 EXAMPLE
390 BUGS
392 SEE ALSO
394 INTERNALS
396 *****************************************************************************************/
398 /*****************************************************************************************
400 NAME
401 aoHidd_BitMap_GfxHidd
403 SYNOPSIS
404 [I.G], OOP_Object *
406 LOCATION
407 hidd.graphics.bitmap
409 FUNCTION
410 Specify display driver object this bitmap was created with.
412 Normally the user doesn't have to supply this attribute. Instead you should use
413 driver's moHidd_Gfx_NewBitMap method in order to create bitmaps. In this case
414 aoHidd_BitMap_GfxHidd attribute will be provided by graphics driver base class
415 with the correct value.
417 It is illegal to manually create bitmap objects with no driver associated.
418 graphics.library maintains at least a memory driver for nondisplayable
419 bitmaps in system RAM without any acceleration.
421 NOTES
423 EXAMPLE
425 BUGS
427 SEE ALSO
428 CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
430 INTERNALS
432 *****************************************************************************************/
434 /*****************************************************************************************
436 NAME
437 aoHidd_BitMap_StdPixFmt
439 SYNOPSIS
440 [I..], HIDDT_StdPixFmt
442 LOCATION
443 hidd.graphics.bitmap
445 FUNCTION
446 Specify standard pixelformat code (one of vHidd_StdPixFmt_... values) for the
447 bitmap.
449 Values less than num_Hidd_PseudoStdPixFmt are illegal for this attribute.
451 Actually the bitmap class itself ignores this attribute. It is processed by
452 CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap method in order to look up a corresponding
453 pixelformat object in the system's database.
455 NOTES
456 Bitmaps with this attribute set should be created as RAM bitmaps with direct CPU
457 access. It is not recommended to replace them with, for example, virtual surfaces on
458 hosted AROS. Such bitmaps are expected to be directly addressable and breaking
459 this may cause undesired side effects.
461 EXAMPLE
463 BUGS
465 SEE ALSO
466 aoHidd_BitMap_PixFmt, CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
468 INTERNALS
469 Currently all display drivers omit specifying own bitmap class for bitmaps with this
470 attribute set, letting base class (actually memory driver) to select an appropriate
471 class for it. This way it ends up in a bitmap of CLID_Hidd_ChunkyBM or CLID_Hidd_PlanarBM
472 class. It is recommended to follow this rule. It's not prohibited, however, to do some
473 adjustments to the bitmap (like alignment) in order to optimize blitting to/from it.
474 In fact if the display driver was asked to create such a bitmap, this means that
475 the standard bitmap is being created as a friend of some bitmap which was allocated
476 using this driver. This way the bitmap is expected to be friendly to this driver.
478 *****************************************************************************************/
480 /*****************************************************************************************
482 NAME
483 aoHidd_BitMap_PixFmt
485 SYNOPSIS
486 [I.G], OOP_Object *
488 LOCATION
489 hidd.graphics.bitmap
491 FUNCTION
492 Specify or query pixelformat descriptor object associated with the bitmap.
494 Every bitmap has some associated pixelformat object. Pixelformat objects are
495 shared data storages, so many bitmaps may refer to the same pixelformat objects.
497 NOTES
498 This attribute is internally specified during bitmap creation, but it's illegal
499 to do this for the user. NewBitMap method of graphics driver performs an explicit
500 check against this. It's up to graphics base classes to figure out its value.
502 EXAMPLE
504 BUGS
506 SEE ALSO
508 INTERNALS
510 *****************************************************************************************/
512 /*****************************************************************************************
514 NAME
515 aoHidd_BitMap_ModeID
517 SYNOPSIS
518 [ISG], HIDDT_ModeID
520 LOCATION
521 hidd.graphics.bitmap
523 FUNCTION
524 Specify display mode ID for displayable bitmap.
526 A displayable bitmap must have this attribute supplied with valid value. A nondisplayable
527 one may miss it, however it may remember it if it was created as a friend of displayable
528 one. This way you may create another displayable bitmap as a friend of nondisplayable
529 one which in turn is a friend of displayable one.
531 This attribute can be set on a framebuffer bitmap. Doing so means an explicit request
532 for the driver to change current display mode on the hardware. Dependent parameters
533 (width, height and pixelformat) will be automatically adjusted, if not explicitly
534 specified in the attributes list.
536 NOTES
537 If the given ModeID is not supported, the operation causes an error. You can check
538 for this by checking return value of OOP_SetAttrs() function. It will be TRUE in
539 case of success and FALSE upon failure. In case of failure none of bitmap attributes
540 will be changed.
542 EXAMPLE
544 BUGS
546 SEE ALSO
548 INTERNALS
550 *****************************************************************************************/
552 /*****************************************************************************************
554 NAME
555 aoHidd_BitMap_ClassPtr
557 SYNOPSIS
558 [I..], OOP_Class *
560 LOCATION
561 hidd.graphics.bitmap
563 FUNCTION
564 Explicitly specify bitmap's class pointer.
566 This attribute is not actually a bitmap's attribute. Your display driver class can
567 supply it to base class' moHidd_Gfx_NewBitMap method in order to select a class on
568 which to call OOP_NewObject().
570 If neither this attribute nor aoHidd_BitMap_ClassID attribute is provided for
571 moHidd_Gfx_NewBitMap, graphics base class will do its best in order to find out the
572 correct class based on aoHidd_StdPixFmt attribute value or friend bitmap.
574 NOTES
575 If a friend bitmap is given, the new bitmap will have the same class, if your driver
576 doesn't override it by supplying explicit class specification (using either
577 aoHidd_BitMap_ClassPtr or aoHidd_BitMap_ClassID attribute).
579 EXAMPLE
581 BUGS
583 SEE ALSO
584 aoHidd_BitMap_ClassID, CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
586 INTERNALS
588 *****************************************************************************************/
590 /*****************************************************************************************
592 NAME
593 aoHidd_BitMap_ClassID
595 SYNOPSIS
596 [I..]
598 LOCATION
599 hidd.graphics.bitmap
601 FUNCTION
602 Explicitly specify bitmap's class ID.
604 The purpose of this attribute is to let graphics driver base class to select a class
605 on which to call OOP_NewObject() in its moHidd_Gfx_NewBitMap implementation.
607 If neither this attribute nor aoHidd_BitMap_ClassPtr attribute is provided for
608 moHidd_Gfx_NewBitMap, graphics base class will do its best in order to find out the
609 correct class based on aoHidd_StdPixFmt attribute value or aoHidd_BitMap_ClassPtr value
610 of friend bitmap.
612 NOTES
614 EXAMPLE
616 BUGS
617 The pointer to a given class will not be remembered as aoHidd_BitMap_ClassPtr value.
619 SEE ALSO
620 aoHidd_BitMap_ClassPtr, CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
622 INTERNALS
624 *****************************************************************************************/
626 /*****************************************************************************************
628 NAME
629 aoHidd_BitMap_PixFmtTags
631 SYNOPSIS
632 [...]
634 LOCATION
635 hidd.graphics.bitmap
637 FUNCTION
638 Private, very obsolete and currently has no function. Considered reserved.
640 NOTES
642 EXAMPLE
644 BUGS
646 SEE ALSO
648 INTERNALS
650 *****************************************************************************************/
652 /*****************************************************************************************
654 NAME
655 aoHidd_BitMap_FrameBuffer
657 SYNOPSIS
658 [I.G], BOOL
660 LOCATION
661 hidd.graphics.bitmap
663 FUNCTION
664 Specifies that the bitmap is a framebuffer bitmap.
666 A detailed description of a framebuffer is given in CLID_Hidd_Gfx/moHidd_Gfx_NewBitMap
667 and in CLID_Hidd_Gfx/moHidd_Gfx_Show documentation.
669 Specifying this attribute causes also implicit setting of aoHidd_BitMap_Displayable
670 to TRUE.
672 NOTES
674 EXAMPLE
676 BUGS
678 SEE ALSO
680 INTERNALS
682 *****************************************************************************************/
684 /*****************************************************************************************
686 NAME
687 aoHidd_BitMap_LeftEdge
689 SYNOPSIS
690 [.SG]
692 LOCATION
693 hidd.graphics.bitmap
695 FUNCTION
696 Controls horizontal position of a scrollable screen bitmap.
698 Size of displayable bitmaps may differ from actual screen size. In this case the
699 bitmap can be scrolled around the whole display area. If the bitmap is larger than
700 the display, only its part can be visible.
702 Setting this attribute causes changing left origin point of the bitmap. The value
703 of this attribute represents an offset from the physical edge of the display to the
704 logical edge of the bitmap. This means that if a large bitmap scrolls to the left in
705 order to reveal its right part, the offset will be negative. If the bitmap scrolls
706 to the left (possibly revealing another bitmap behind it), the offset will be positive.
708 It's up to the display driver to set scroll limits. If the value of the attribute
709 becomes unacceptable for any reason, the driver should adjust it and provide the real
710 resulting value back.
712 NOTES
713 Implementing screen scrolling does not enforce to implement screen composition, despite
714 the composition is really based on scrolling (in case of composition scrolling a bitmap
715 off-display is expected to reveal another bitmap behing it instead of empty space).
717 EXAMPLE
719 BUGS
721 SEE ALSO
722 aoHidd_BitMap_TopEdge
724 INTERNALS
725 Base class will always provide zero value for this attribute and ignore all attempts
726 to set it. This means that by default bitmaps don't scroll and this needs explicit
727 implementation in the display driver.
729 *****************************************************************************************/
731 /*****************************************************************************************
733 NAME
734 aoHidd_BitMap_TopEdge
736 SYNOPSIS
737 [.SG]
739 LOCATION
740 hidd.graphics.bitmap
742 FUNCTION
743 Controls vertical position of a scrollable screen bitmap.
745 Size of displayable bitmaps may differ from actual screen size. In this case the
746 bitmap can be scrolled around the whole display area. If the bitmap is larger than
747 the display, only its part can be visible.
749 Setting this attribute causes changing top origin point of the bitmap. The value
750 of this attribute represents an offset from the physical edge of the display to the
751 logical edge of the bitmap. This means that if a large bitmap scrolls upwards in
752 order to reveal its bottom part, the offset will be negative. If the bitmap scrolls
753 downdards (possibly revealing another bitmap behind it), the offset will be positive.
755 It's up to the display driver to set scroll limits. If the value of the attribute
756 becomes unacceptable for any reason, the driver should adjust it and provide the real
757 resulting value back.
759 NOTES
760 Implementing screen scrolling does not enforce to implement screen composition, despite
761 the composition is really based on scrolling (in case of composition scrolling a bitmap
762 off-display is expected to reveal another bitmap behing it instead of empty space).
764 EXAMPLE
766 BUGS
768 SEE ALSO
770 INTERNALS
772 *****************************************************************************************/
774 /*****************************************************************************************
776 NAME
777 aoHidd_BitMap_Align
779 SYNOPSIS
780 [I.G]
782 LOCATION
783 hidd.graphics.bitmap
785 FUNCTION
786 Specify number of pixels to align bitmap data width to.
788 This attribute can be added in order to enforce alignment needed for example by
789 blitting hardware. It will have an impact on default aoHidd_BitMap_BytesPerRow
790 value.
792 Direct specification of aoHidd_BitMap_BytesPerRow attribute overrides any value
793 of this attribute.
795 NOTES
796 Default value of this attribute is 16. This alignment is required by graphics.library
797 for AmigaOS(tm) compatibility reasons.
799 EXAMPLE
801 BUGS
803 SEE ALSO
804 aoHidd_BitMap_BytesPerRow
806 INTERNALS
808 *****************************************************************************************/
810 /*****************************************************************************************
812 NAME
813 aoHidd_BitMap_Depth
815 SYNOPSIS
816 [G.I]
818 LOCATION
819 hidd.graphics.bitmap
821 FUNCTION
822 Specify or query the actual bitmap depth.
824 This a convenience attribute to simplify handling planar bitmaps, whose actual depth
825 may vary. Default implementation in base class simply returns depth of bitmap's
826 pixelformat, and is ignored during initialization. Planar bitmap class returns the
827 actual depth here. If your specific bitmap class also operates on bitmaps with variable
828 depths, you need to implement this attribute in it.
830 NOTES
832 EXAMPLE
834 BUGS
836 SEE ALSO
838 INTERNALS
840 *****************************************************************************************/
842 /****************************************************************************************/
844 #undef csd
847 * Calculate suggested bytes per row value based on bitmap's default alignment
848 * and pixelformat's bytes per pixel value.
850 static ULONG GetBytesPerRow(struct HIDDBitMapData *data, struct class_static_data *csd)
852 struct Library *OOPBase = csd->cs_OOPBase;
853 UWORD align = data->align - 1;
854 UWORD width = (data->width + align) & ~align;
855 IPTR bytesperpixel, stdpf;
857 OOP_GetAttr(data->prot.pixfmt, aHidd_PixFmt_BytesPerPixel, &bytesperpixel);
858 OOP_GetAttr(data->prot.pixfmt, aHidd_PixFmt_StdPixFmt, &stdpf);
860 if (stdpf == vHidd_StdPixFmt_Plane)
863 * Planar format actually have 8 pixels per one byte.
864 * However bytesperpixel == 1 for them. Perhaps this should
865 * be changed to 0 ?
867 return width >> 3;
869 else
871 return width * bytesperpixel;
875 #define csd CSD(cl)
877 OOP_Object *BM__Root__New(OOP_Class *cl, OOP_Object *obj, struct pRoot_New *msg)
879 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
880 struct Library *UtilityBase = CSD(cl)->cs_UtilityBase;
882 EnterFunc(bug("BitMap::New()\n"));
884 obj = (OOP_Object *)OOP_DoSuperMethod(cl, obj, (OOP_Msg) msg);
886 if (NULL != obj)
888 struct TagItem colmap_tags[] =
890 { aHidd_ColorMap_NumEntries , 16 },
891 { TAG_DONE }
893 struct TagItem *tag, *tstate;
894 BOOL ok = TRUE;
895 struct HIDDBitMapData *data = OOP_INST_DATA(cl, obj);
897 /* Set some default values */
898 data->modeid = vHidd_ModeID_Invalid;
899 data->align = 16;
901 tstate = msg->attrList;
902 while ((tag = NextTagItem(&tstate)))
904 ULONG idx;
906 if (IS_BITMAP_ATTR(tag->ti_Tag, idx))
908 switch (idx)
910 case aoHidd_BitMap_Width:
911 data->width = tag->ti_Data;
912 break;
914 case aoHidd_BitMap_Height:
915 data->height = tag->ti_Data;
916 break;
918 case aoHidd_BitMap_Align:
919 data->align = tag->ti_Data;
920 break;
922 case aoHidd_BitMap_BytesPerRow:
923 data->bytesPerRow = tag->ti_Data;
924 break;
926 case aoHidd_BitMap_GfxHidd:
927 data->gfxhidd = (OOP_Object *)tag->ti_Data;
928 break;
930 case aoHidd_BitMap_Friend:
931 data->friend = (OOP_Object *)tag->ti_Data;
932 break;
934 case aoHidd_BitMap_Displayable:
935 data->displayable = tag->ti_Data;
936 break;
938 case aoHidd_BitMap_FrameBuffer:
939 data->framebuffer = tag->ti_Data;
940 break;
942 case aoHidd_BitMap_ModeID:
943 data->modeid = tag->ti_Data;
944 break;
946 case aoHidd_BitMap_PixFmt:
947 data->prot.pixfmt = (OOP_Object *)tag->ti_Data;
948 break;
953 /* aoHidd_BitMap_GfxHidd is mandatory */
954 if (!data->gfxhidd)
956 D(bug("!!!! BM CLASS DID NOT GET GFX HIDD !!!\n"));
957 D(bug("!!!! The reason for this is that the gfxhidd subclass NewBitmap() method\n"));
958 D(bug("!!!! has not left it to the baseclass to actually create the object,\n"));
959 D(bug("!!!! but rather done it itself. This MUST be corrected in the gfxhidd subclass\n"));
961 ok = FALSE;
964 /* FrameBuffer implies Displayable */
965 if (data->framebuffer)
966 data->displayable = TRUE;
968 if (ok && data->displayable)
970 /* We should allways get modeid, but we check anyway */
971 if (data->modeid == vHidd_ModeID_Invalid)
973 D(bug("!!! BitMap:New() DID NOT GET MODEID FOR DISPLAYABLE BITMAP !!!\n"));
974 ok = FALSE;
976 else
978 OOP_Object *sync, *pf;
980 if (!HIDD_Gfx_GetMode(data->gfxhidd, data->modeid, &sync, &pf))
982 D(bug("!!! BitMap::New() RECEIVED INVALID MODEID 0x%08X\n", data->modeid));
983 ok = FALSE;
985 else
987 /* Update the missing bitmap data from the modeid */
988 if (!data->width)
990 IPTR width;
992 OOP_GetAttr(sync, aHidd_Sync_HDisp, &width);
993 data->width = width;
996 if (!data->height)
998 IPTR height;
1000 OOP_GetAttr(sync, aHidd_Sync_VDisp, &height);
1001 data->height = height;
1004 if (!data->prot.pixfmt)
1006 /* The PixFmt is allready registered and locked in the PixFmt database */
1007 data->prot.pixfmt = pf;
1011 } /* if (ok) */
1013 if (ok)
1015 /* * PixFmt will be NULL in case of e. g. planarbm late initialization. */
1016 if (data->prot.pixfmt)
1018 ULONG bytesPerRow = GetBytesPerRow(data, CSD(cl));
1020 if (data->bytesPerRow)
1022 /* If we have user-supplied BytesPerRow value, make sure it's suitable */
1023 if (data->bytesPerRow < bytesPerRow)
1024 ok = FALSE;
1026 else
1028 /* Otherwise we have what we calculated */
1029 data->bytesPerRow = bytesPerRow;
1034 if (ok)
1036 /* Cache default GC */
1037 OOP_GetAttr(data->gfxhidd, aHidd_Gfx_DefaultGC, (IPTR *)&data->gc);
1040 * Initialize the direct method calling.
1041 * We don't check against errors because our base class contains all
1042 * these functions.
1044 #if USE_FAST_PUTPIXEL
1045 data->putpixel = OOP_GetMethod(obj, HiddBitMapBase + moHidd_BitMap_PutPixel, &data->putpixel_Class);
1046 #endif
1047 #if USE_FAST_GETPIXEL
1048 data->getpixel = OOP_GetMethod(obj, HiddBitMapBase + moHidd_BitMap_GetPixel, &data->getpixel_Class);
1049 #endif
1050 #if USE_FAST_DRAWPIXEL
1051 data->drawpixel = OOP_GetMethod(obj, HiddBitMapBase + moHidd_BitMap_DrawPixel, &data->drawpixel_Class);
1052 #endif
1055 * Try to create the colormap.
1057 * stegerg: Only add a ColorMap for a visible bitmap (screen). This
1058 * is important because one can create for example a bitmap
1059 * in PIXFMT_LUT8 without friend bitmap and then copy this
1060 * bitmap to a 16 bit screen. During copy the screen bitmap
1061 * CLUT must be used, which would not happen if our PIXFMT_LUT8
1062 * also had a colormap itself because then bltbitmap would use the
1063 * colormap of the PIXFMT_LUT8 bitmap as lookup, which in this
1064 * case would just cause everything to become black in the
1065 * destination (screen) bitmap, because noone ever sets up the
1066 * colormap of the PIXFMT_LUT8 bitmap
1068 * sonic: CHECKME: Why does the colormap always have 16 colors? May be calculate this
1069 * based on depth ? The colormap auto-enlarges itself if SetColors method requests
1070 * missing entries, but is it so good?
1073 if (data->displayable)
1075 data->colmap = OOP_NewObject(NULL, CLID_Hidd_ColorMap, colmap_tags);
1076 if (NULL == data->colmap)
1077 ok = FALSE;
1082 if (!ok)
1084 ULONG dispose_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
1086 OOP_CoerceMethod(cl, obj, &dispose_mid);
1087 obj = NULL;
1089 } /* if(obj) */
1091 } /* if (NULL != obj) */
1093 ReturnPtr("BitMap::New", OOP_Object *, obj);
1096 /****************************************************************************************/
1098 void BM__Root__Dispose(OOP_Class *cl, OOP_Object *obj, OOP_Msg *msg)
1100 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
1101 struct HIDDBitMapData *data = OOP_INST_DATA(cl, obj);
1103 EnterFunc(bug("BitMap::Dispose()\n"));
1105 if (NULL != data->colmap)
1106 OOP_DisposeObject(data->colmap);
1108 D(bug("Calling super\n"));
1110 /* Release the previously registered pixel format */
1111 if (data->pf_registered)
1112 GFX__Hidd_Gfx__ReleasePixFmt(CSD(cl)->gfxhiddclass, data->prot.pixfmt);
1114 OOP_DoSuperMethod(cl, obj, (OOP_Msg) msg);
1116 ReturnVoid("BitMap::Dispose");
1119 /****************************************************************************************/
1121 VOID BM__Root__Get(OOP_Class *cl, OOP_Object *obj, struct pRoot_Get *msg)
1123 struct HIDDBitMapData *data = OOP_INST_DATA(cl, obj);
1124 ULONG idx;
1126 EnterFunc(bug("BitMap::Get() attrID: %i storage: %p\n", msg->attrID, msg->storage));
1128 if (IS_BITMAP_ATTR(msg->attrID, idx))
1130 switch(idx)
1132 case aoHidd_BitMap_Width:
1133 *msg->storage = data->width;
1134 D(bug(" width: %i\n", data->width));
1135 return;
1137 case aoHidd_BitMap_Height:
1138 *msg->storage = data->height;
1139 return;
1141 case aoHidd_BitMap_Depth:
1143 * Generally our bitmaps have a fixed depth, which depends on pixelformat.
1144 * If this is not true for your bitmap, overload aoHidd_BitMap_Depth in your class.
1146 *msg->storage = ((HIDDT_PixelFormat *)data->prot.pixfmt)->depth;
1147 return;
1149 case aoHidd_BitMap_Displayable:
1150 *msg->storage = data->displayable;
1151 return;
1153 case aoHidd_BitMap_FrameBuffer:
1154 *msg->storage = data->framebuffer;
1155 return;
1157 case aoHidd_BitMap_PixFmt:
1158 *msg->storage = (IPTR)data->prot.pixfmt;
1159 return;
1161 case aoHidd_BitMap_Friend:
1162 *msg->storage = (IPTR)data->friend;
1163 return;
1165 case aoHidd_BitMap_ColorMap:
1166 *msg->storage = (IPTR)data->colmap;
1167 return;
1169 case aoHidd_BitMap_GfxHidd:
1170 *msg->storage = (IPTR)data->gfxhidd;
1171 return;
1173 case aoHidd_BitMap_ModeID:
1174 *msg->storage = data->modeid;
1175 return;
1177 case aoHidd_BitMap_Align:
1178 *msg->storage = data->align;
1179 return;
1181 case aoHidd_BitMap_BytesPerRow:
1182 *msg->storage = data->bytesPerRow;
1183 return;
1185 /* Generic bitmaps don't scroll. This has to be implemented in the subclass. */
1186 case aoHidd_BitMap_LeftEdge:
1187 case aoHidd_BitMap_TopEdge:
1188 *msg->storage = 0;
1189 return;
1191 D(default: bug("UNKNOWN ATTR IN BITMAP BASECLASS: %d\n", idx);)
1195 OOP_DoSuperMethod(cl, obj, &msg->mID);
1196 ReturnVoid("BitMap::Get");
1199 /****************************************************************************************/
1201 #define UB(x) ((UBYTE *)x)
1203 /*****************************************************************************************
1205 NAME
1206 moHidd_BitMap_SetColors
1208 SYNOPSIS
1209 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetColors *msg);
1211 BOOL HIDD_BM_SetColors (OOP_Object *obj, HIDDT_Color *colors,
1212 UWORD firstColor, UWORD numColors);
1214 LOCATION
1215 hidd.graphics.bitmap
1217 FUNCTION
1218 Sets values for one or more colors in the colormap object associated with the
1219 bitmap.
1221 The colormap will be created if it does not exist.
1223 Only ARGB values from the source array are taken into account. pixval member is
1224 updated with the real pixel value for every color.
1226 INPUTS
1227 obj - A bitmap object whose colormap needs to be set
1228 colors - A pointer to source data array
1229 firstColor - Number of the first color to set
1230 numColors - Number of subsequent colors to set
1232 RESULT
1233 TRUE on success, FALSE in case of some error (like out of memory)
1235 NOTES
1237 EXAMPLE
1239 BUGS
1241 SEE ALSO
1242 CLID_Hidd_ColorMap/moHidd_ColorMap_SetColors
1244 INTERNALS
1246 *****************************************************************************************/
1248 BOOL BM__Hidd_BitMap__SetColors(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_SetColors *msg)
1250 /* Copy the colors into the internal buffer */
1251 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
1252 struct HIDDBitMapData *data;
1254 data = OOP_INST_DATA(cl, o);
1256 /* Subclass has initialized HIDDT_Color->pixelVal field and such.
1257 Just copy it into the colortab.
1260 if (NULL == data->colmap)
1262 struct TagItem colmap_tags[] =
1264 { aHidd_ColorMap_NumEntries, 0 },
1265 { TAG_DONE }
1268 colmap_tags[0].ti_Data = msg->firstColor + msg->numColors;
1269 data->colmap = OOP_NewObject(NULL, CLID_Hidd_ColorMap, colmap_tags);
1272 if (NULL == data->colmap)
1274 return FALSE;
1277 /* Use the colormap class to set the colors */
1278 return HIDD_CM_SetColors(data->colmap, msg->colors,
1279 msg->firstColor, msg->numColors,
1280 data->prot.pixfmt);
1284 /*****************************************************************************************
1286 NAME
1287 moHidd_BitMap_DrawPixel
1289 SYNOPSIS
1290 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPixel *msg);
1292 ULONG HIDD_BM_DrawPixel(OOP_Object *obj, OOP_Object *gc, WORD x, WORD y);
1294 LOCATION
1295 hidd.graphics.bitmap
1297 FUNCTION
1298 Changes the pixel at (x,y). The color of the pixel depends on the
1299 attributes of gc, eg. colors, drawmode, colormask etc.
1300 This function does not check the coordinates.
1302 INPUTS
1303 obj - A bitmap to draw on
1304 gc - A GC (graphics context) object to use for drawing
1305 x, y - Coordinates of the pixel to draw
1307 RESULT
1308 Undefined. Many drivers declare this method as void.
1310 NOTES
1312 EXAMPLE
1314 BUGS
1316 SEE ALSO
1318 INTERNALS
1320 TODO
1321 - Support for shapeplane.
1322 - Optimize
1324 *****************************************************************************************/
1326 ULONG BM__Hidd_BitMap__DrawPixel(OOP_Class *cl, OOP_Object *obj,
1327 struct pHidd_BitMap_DrawPixel *msg)
1329 HIDDT_Pixel src, dest, val;
1330 HIDDT_DrawMode mode;
1331 HIDDT_Pixel writeMask;
1332 OOP_Object *gc;
1334 /* EnterFunc(bug("BitMap::DrawPixel() x: %i, y: %i\n", msg->x, msg->y));
1337 Example: Pixels which bits are set to 0 in the colMask must be
1338 unchanged
1340 data->colMask = 001111
1341 dest = 101100
1344 writeMask = ~data->colMask & dest
1345 = 110000 & 101100
1346 = 100000
1348 dest = data->fg && dest = 010100
1351 dest = dest & (writeMask | data->ColMask)
1352 = 010100 & (100000 | 001111)
1353 = 010100 & (101111)
1354 = 000100
1357 dest = dest | writeMask;
1358 = 000100 100000
1359 = 100100
1363 gc = msg->gc;
1365 src = GC_FG(gc);
1366 mode = GC_DRMD(gc);
1368 #if OPTIMIZE_DRAWPIXEL_FOR_COPY
1369 if (vHidd_GC_DrawMode_Copy == mode && GC_COLMASK(gc) == ~0)
1371 val = src;
1373 else
1374 #endif
1376 dest = GETPIXEL(cl, obj, msg->x, msg->y);
1377 writeMask = ~GC_COLMASK(gc) & dest;
1379 val = 0;
1381 if(mode & 1) val = ( src & dest);
1382 if(mode & 2) val = ( src & ~dest) | val;
1383 if(mode & 4) val = (~src & dest) | val;
1384 if(mode & 8) val = (~src & ~dest) | val;
1386 val = (val & (writeMask | GC_COLMASK(gc) )) | writeMask;
1390 PUTPIXEL(cl, obj, msg->x, msg->y, val);
1392 /* ReturnInt("BitMap::DrawPixel ", ULONG, 1); */ /* in quickmode return always 1 */
1394 return 1;
1397 /*****************************************************************************************
1399 NAME
1400 moHidd_BitMap_DrawLine
1402 SYNOPSIS
1403 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPixel *msg);
1405 VOID HIDD_BM_DrawLine(OOP_Object *obj, OOP_Object *gc, WORD x1, WORD y1,
1406 WORD x2, WORD y2);
1408 LOCATION
1409 hidd.graphics.bitmap
1411 FUNCTION
1412 Draws a line from (x1,y1) to (x2,y2) in the specified gc.
1413 The function does not clip the line against the drawing area.
1415 INPUTS
1416 obj - A bitmap to draw on
1417 gc - A graphics context object to use
1418 x1,y1 - start point of the line in pixels
1419 x2,y2 - end point of the line in pixels
1421 RESULT
1422 None.
1424 NOTES
1426 EXAMPLE
1428 BUGS
1430 SEE ALSO
1432 INTERNALS
1433 Uses midpoint line ("Bresenham") algorithm([FOL90] 3.2.2)
1435 TODO Support for line pattern
1436 Optimize remove if t == 1 ...
1437 Implement better clipping: Should be no reason to calculate
1438 more than the part of the line that is inside the cliprect
1440 *****************************************************************************************/
1442 VOID BM__Hidd_BitMap__DrawLine
1444 OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_DrawLine *msg
1447 WORD dx, dy, incrE, incrNE, d, x, y, s1, s2, t, i;
1448 WORD x1, y1, x2, y2;
1449 UWORD maskLine; /* for line pattern */
1450 ULONG fg; /* foreground pen */
1451 APTR doclip;
1452 BOOL opaque;
1453 OOP_Object *gc;
1456 /* bug("BitMap::DrawLine()\n");
1457 */ EnterFunc(bug("BitMap::DrawLine() x1: %i, y1: %i x2: %i, y2: %i\n", msg->x1, msg->y1, msg->x2, msg->y2));
1459 gc = msg->gc;
1460 doclip = GC_DOCLIP(gc);
1461 opaque = (GC_COLEXP(gc) & vHidd_GC_ColExp_Opaque) ? TRUE : FALSE;
1462 fg = GC_FG(gc);
1464 maskLine = 1 << GC_LINEPATCNT(gc);
1466 if (doclip)
1468 /* If line is not inside cliprect, then just return */
1469 /* Normalize coords */
1470 if (msg->x1 > msg->x2)
1472 x1 = msg->x2; x2 = msg->x1;
1474 else
1476 x1 = msg->x1; x2 = msg->x2;
1479 if (msg->y1 > msg->y2)
1481 y1 = msg->y2; y2 = msg->y1;
1483 else
1485 y1 = msg->y1; y2 = msg->y2;
1488 if ( x1 > GC_CLIPX2(gc)
1489 || x2 < GC_CLIPX1(gc)
1490 || y1 > GC_CLIPY2(gc)
1491 || y2 < GC_CLIPY1(gc) )
1494 /* Line is not inside cliprect, so just return */
1495 return;
1500 x1 = msg->x1;
1501 y1 = msg->y1;
1502 x2 = msg->x2;
1503 y2 = msg->y2;
1505 if (y1 == y2)
1508 Horizontal line drawing code.
1510 y = y1;
1512 /* Don't swap coordinates if x2 < x1! Because of linepattern! */
1514 if (x1 < x2)
1516 x2++;
1517 dx = 1;
1519 else
1521 x2--;
1522 dx = -1;
1525 for(i = x1; i != x2; i += dx)
1527 /* Pixel inside ? */
1529 if (!doclip || !POINT_OUTSIDE_CLIP(gc, i, y ))
1531 if(GC_LINEPAT(gc) & maskLine)
1533 HIDD_BM_DrawPixel(obj, gc, i, y);
1535 else if (opaque)
1537 GC_FG(gc) = GC_BG(gc);
1538 HIDD_BM_DrawPixel(obj, gc, i, y);
1539 GC_FG(gc) = fg;
1543 maskLine = maskLine >> 1;
1544 if (!maskLine) maskLine = 1L << 15;
1547 else if (x1 == x2)
1550 Vertical line drawing code.
1552 x = x1;
1554 /* Don't swap coordinates if y2 < y1! Because of linepattern! */
1556 if (y1 < y2)
1558 y2++;
1559 dy = 1;
1561 else
1563 y2--;
1564 dy = -1;
1567 for(i = y1; i != y2; i += dy)
1569 /* Pixel inside ? */
1570 if (!doclip || !POINT_OUTSIDE_CLIP(gc, x, i ))
1572 if(GC_LINEPAT(gc) & maskLine)
1574 HIDD_BM_DrawPixel(obj, gc, x, i);
1576 else if (opaque)
1578 GC_FG(gc) = GC_BG(gc);
1579 HIDD_BM_DrawPixel(obj, gc, x, i);
1580 GC_FG(gc) = fg;
1584 maskLine = maskLine >> 1;
1585 if (!maskLine) maskLine = 1L << 15;
1589 else
1592 Generic line drawing code.
1594 /* Calculate slope */
1595 dx = abs(x2 - x1);
1596 dy = abs(y2 - y1);
1598 /* which direction? */
1599 if((x2 - x1) > 0) s1 = 1; else s1 = - 1;
1600 if((y2 - y1) > 0) s2 = 1; else s2 = - 1;
1602 /* change axes if dx < dy */
1603 if(dx < dy)
1605 d = dx;
1606 dx = dy;
1607 dy = d;
1608 t = 0;
1610 else
1612 t = 1;
1615 d = 2 * dy - dx; /* initial value of d */
1617 incrE = 2 * dy; /* Increment use for move to E */
1618 incrNE = 2 * (dy - dx); /* Increment use for move to NE */
1620 x = x1; y = y1;
1622 for(i = 0; i <= dx; i++)
1624 /* Pixel inside ? */
1625 if (!doclip || !POINT_OUTSIDE_CLIP(gc, x, y ))
1627 if(GC_LINEPAT(gc) & maskLine)
1629 HIDD_BM_DrawPixel(obj, gc, x, y);
1631 else if (opaque)
1633 GC_FG(gc) = GC_BG(gc);
1634 HIDD_BM_DrawPixel(obj, gc, x, y);
1635 GC_FG(gc) = fg;
1639 if(d <= 0)
1641 if(t == 1)
1643 x = x + s1;
1645 else
1647 y = y + s2;
1650 d = d + incrE;
1652 else
1654 x = x + s1;
1655 y = y + s2;
1656 d = d + incrNE;
1659 maskLine = maskLine >> 1;
1660 if (!maskLine) maskLine = 1L << 15;
1665 ReturnVoid("BitMap::DrawLine ");
1668 /*****************************************************************************************
1670 NAME
1671 moHidd_BitMap_DrawRect
1673 SYNOPSIS
1674 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawRect *msg);
1676 VOID HIDD_BM_DrawRect (OOP_Object *obj, OOP_Object *gc, WORD minX, WORD minY,
1677 WORD maxX, WORD maxY);
1679 LOCATION
1680 hidd.graphics.bitmap
1682 FUNCTION
1683 Draws a hollow rectangle. minX and minY specifies the upper
1684 left corner of the rectangle. minY and maxY specifies the lower
1685 right corner of the rectangle.
1686 The function does not clip the rectangle against the drawing area.
1688 INPUTS
1689 obj - A bitmap to draw on
1690 gc - A GC object to use for drawing
1691 minX, minY - upper left corner of the rectangle in pixels
1692 maxX, maxY - lower right corner of the rectangle in pixels
1694 RESULT
1695 None.
1697 NOTES
1698 This method is not used by the system and considered reserved.
1700 EXAMPLE
1702 BUGS
1704 SEE ALSO
1706 INTERNALS
1708 TODO
1710 *****************************************************************************************/
1712 VOID BM__Hidd_BitMap__DrawRect(OOP_Class *cl, OOP_Object *obj,
1713 struct pHidd_BitMap_DrawRect *msg)
1715 #ifdef __RESERVED__
1716 OOP_Object *gc = msg->gc;
1717 WORD addX, addY;
1719 EnterFunc(bug("BitMap::DrawRect()"));
1721 if(msg->minX == msg->maxX) addX = 0; else addX = 1;
1722 if(msg->minY == msg->maxY) addY = 0; else addY = 1;
1724 HIDD_BM_DrawLine(obj, gc, msg->minX, msg->minY , msg->maxX, msg->minY);
1725 HIDD_BM_DrawLine(obj, gc, msg->maxX, msg->minY + addY, msg->maxX, msg->maxY);
1726 HIDD_BM_DrawLine(obj, gc, msg->maxX - addX, msg->maxY, msg->minX, msg->maxY);
1727 HIDD_BM_DrawLine(obj, gc, msg->minX, msg->maxY - addY, msg->minX, msg->minY + addY);
1728 #endif
1730 ReturnVoid("BitMap::DrawRect");
1733 /*****************************************************************************************
1735 NAME
1736 moHidd_BitMap_FillRect
1738 SYNOPSIS
1739 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawRect *msg);
1741 VOID HIDD_BM_FillRect (OOP_Object *obj, OOP_Object *gc, WORD minX, WORD minY,
1742 WORD maxX, WORD maxY);
1744 LOCATION
1745 hidd.graphics.bitmap
1747 FUNCTION
1749 Draws a solid rectangle. minX and minY specifies the upper
1750 left corner of the rectangle. minY and maxY specifies the lower
1751 right corner of the rectangle.
1752 The function does not clip the rectangle against the drawing area.
1754 INPUTS
1755 obj - A bitmap to draw on
1756 gc - A GC object to use for drawing
1757 minX, minY - upper left corner of the rectangle in pixels
1758 maxX, maxY - lower right corner of the rectangle in pixels
1760 RESULT
1761 None.
1763 NOTES
1765 EXAMPLE
1767 BUGS
1769 SEE ALSO
1771 INTERNALS
1773 TODO
1774 Fill with pattern
1776 *****************************************************************************************/
1778 VOID BM__Hidd_BitMap__FillRect(OOP_Class *cl, OOP_Object *obj,
1779 struct pHidd_BitMap_DrawRect *msg)
1781 OOP_Object *gc = msg->gc;
1782 WORD y = msg->minY;
1783 UWORD linepat;
1785 EnterFunc(bug("BitMap::FillRect()"));
1787 linepat = GC_LINEPAT(gc);
1788 GC_LINEPAT(gc) = ~0;
1790 for(; y <= msg->maxY; y++)
1792 HIDD_BM_DrawLine(obj, gc, msg->minX, y, msg->maxX, y);
1795 GC_LINEPAT(gc) = linepat;
1797 ReturnVoid("BitMap::FillRect");
1800 /*****************************************************************************************
1802 NAME
1803 moHidd_BitMap_DrawEllipse
1805 SYNOPSIS
1806 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawEllipse *msg);
1808 VOID HIDD_BM_DrawEllipse (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
1809 WORD rx, WORD ry);
1811 LOCATION
1812 hidd.graphics.bitmap
1814 FUNCTION
1815 Draws a hollow ellipse from the center point (x,y) with the radii
1816 rx and ry in the specified bitmap.
1817 The function does not clip the ellipse against the drawing area.
1819 INPUTS
1820 obj - A bitmap to draw on
1821 gc - A GC object to use for drawing
1822 x,y - Coordinates of center point in pixels
1823 rx,ry - ry and ry radius in pixels
1825 RESULT
1826 None.
1828 NOTES
1830 EXAMPLE
1832 BUGS
1833 Because of overflow the current code do not work with big
1834 values of rx and ry.
1836 SEE ALSO
1838 INTERNALS
1840 TODO
1841 Bugfix
1843 *****************************************************************************************/
1845 /* TODO: Try to opimize clipping here */
1847 VOID BM__Hidd_BitMap__DrawEllipse(OOP_Class *cl, OOP_Object *obj,
1848 struct pHidd_BitMap_DrawEllipse *msg)
1850 OOP_Object *gc = msg->gc;
1851 WORD x = msg->rx, y = 0; /* ellipse points */
1853 /* intermediate terms to speed up loop */
1854 WORD t1 = msg->rx * msg->rx, t2 = t1 << 1, t3 = t2 << 1;
1855 WORD t4 = msg->ry * msg->ry, t5 = t4 << 1, t6 = t5 << 1;
1856 WORD t7 = msg->rx * t5, t8 = t7 << 1, t9 = 0L;
1857 WORD d1 = t2 - t7 + (t4 >> 1); /* error terms */
1858 WORD d2 = (t1 >> 1) - t8 + t5;
1860 APTR doclip = GC_DOCLIP(gc);
1863 EnterFunc(bug("BitMap::DrawEllipse()"));
1865 while (d2 < 0) /* til slope = -1 */
1867 /* draw 4 points using symmetry */
1869 if (doclip)
1872 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y + y))
1873 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
1875 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y - y))
1876 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
1878 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y + y))
1879 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
1881 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y - y))
1882 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
1885 else
1887 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
1888 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
1889 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
1890 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
1893 y++; /* always move up here */
1894 t9 = t9 + t3;
1895 if (d1 < 0) /* move straight up */
1897 d1 = d1 + t9 + t2;
1898 d2 = d2 + t9;
1900 else /* move up and left */
1902 x--;
1903 t8 = t8 - t6;
1904 d1 = d1 + t9 + t2 - t8;
1905 d2 = d2 + t9 + t5 - t8;
1909 do /* rest of top right quadrant */
1911 /* draw 4 points using symmetry */
1912 #if 1
1913 if (doclip)
1916 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y + y))
1917 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
1919 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y - y))
1920 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
1922 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y + y))
1923 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
1925 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y - y))
1926 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
1929 else
1932 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
1933 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
1934 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
1935 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
1937 #else
1939 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
1940 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
1941 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
1942 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
1943 #endif
1944 x--; /* always move left here */
1945 t8 = t8 - t6;
1946 if (d2 < 0) /* move up and left */
1948 y++;
1949 t9 = t9 + t3;
1950 d2 = d2 + t9 + t5 - t8;
1952 else /* move straight left */
1954 d2 = d2 + t5 - t8;
1957 } while (x >= 0);
1960 ReturnVoid("BitMap::DrawEllipse");
1963 /*****************************************************************************************
1965 NAME
1966 moHidd_BitMap_FillEllipse
1968 SYNOPSIS
1969 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawEllipse *msg);
1971 VOID HIDD_BM_FillEllipse (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
1972 WORD ry, WORD rx);
1974 LOCATION
1975 hidd.graphics.bitmap
1977 FUNCTION
1978 Draws a solid ellipse from the center point (x,y) with the radii
1979 rx and ry in the specified bitmap.
1980 The function does not clip the ellipse against the drawing area.
1982 INPUTS
1983 obj - A bitmap to draw on
1984 gc - A GC object to use for drawing
1985 x,y - Coordinates of center point in pixels
1986 rx,ry - ry and ry radius in pixels
1988 RESULT
1989 None.
1991 NOTES
1992 This method is not used by the system and considered reserved.
1994 EXAMPLE
1996 Because of overflow the current code do not work with big
1997 values of rx and ry.
1999 SEE ALSO
2001 INTERNALS
2003 TODO
2004 Bugfix
2006 *****************************************************************************************/
2008 VOID BM__Hidd_BitMap__FillEllipse(OOP_Class *cl, OOP_Object *obj,
2009 struct pHidd_BitMap_DrawEllipse *msg)
2011 #ifdef __RESERVED__
2012 OOP_Object *gc = msg->gc;
2013 WORD x = msg->rx, y = 0; /* ellipse points */
2015 /* intermediate terms to speed up loop */
2016 WORD t1 = msg->rx * msg->rx, t2 = t1 << 1, t3 = t2 << 1;
2017 WORD t4 = msg->ry * msg->ry, t5 = t4 << 1, t6 = t5 << 1;
2018 WORD t7 = msg->rx * t5, t8 = t7 << 1, t9 = 0L;
2019 WORD d1 = t2 - t7 + (t4 >> 1); /* error terms */
2020 WORD d2 = (t1 >> 1) - t8 + t5;
2022 EnterFunc(bug("BitMap::FillEllipse()"));
2024 while (d2 < 0) /* til slope = -1 */
2026 /* draw 4 points using symmetry */
2027 HIDD_BM_DrawLine(obj, gc, msg->x - x, msg->y + y, msg->x + x, msg->y + y);
2028 HIDD_BM_DrawLine(obj, gc, msg->x - x, msg->y - y, msg->x + x, msg->y - y);
2030 y++; /* always move up here */
2031 t9 = t9 + t3;
2032 if (d1 < 0) /* move straight up */
2034 d1 = d1 + t9 + t2;
2035 d2 = d2 + t9;
2037 else /* move up and left */
2039 x--;
2040 t8 = t8 - t6;
2041 d1 = d1 + t9 + t2 - t8;
2042 d2 = d2 + t9 + t5 - t8;
2046 do /* rest of top right quadrant */
2048 /* draw 4 points using symmetry */
2049 HIDD_BM_DrawLine(obj, gc, msg->x - x, msg->y + y, msg->x + x, msg->y + y);
2050 HIDD_BM_DrawLine(obj, gc, msg->x - x, msg->y - y, msg->x + x, msg->y - y);
2052 x--; /* always move left here */
2053 t8 = t8 - t6;
2054 if (d2 < 0) /* move up and left */
2056 y++;
2057 t9 = t9 + t3;
2058 d2 = d2 + t9 + t5 - t8;
2060 else /* move straight left */
2062 d2 = d2 + t5 - t8;
2065 } while (x >= 0);
2066 #endif
2068 ReturnVoid("BitMap::FillEllipse");
2071 /*****************************************************************************************
2073 NAME
2074 moHidd_BitMap_DrawPolygon
2076 SYNOPSIS
2077 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg);
2079 VOID HIDD_BM_DrawPolygon (OOP_Object *obj, OOP_Object *gc, UWORD n, WORD *coords);
2081 LOCATION
2082 hidd.graphics.bitmap
2084 FUNCTION
2085 Draws a hollow polygon from the list of coordinates in coords[].
2086 The function does not clip the polygon against the drawing area.
2088 INPUTS
2089 obj - A bitmap to draw on
2090 gc - A GC object to use for drawing
2091 n - number of coordinate pairs
2092 coords - array of n (x, y) coordinates in pixels
2094 RESULT
2095 None.
2097 NOTES
2098 This method is not used by the system and considered reserved.
2100 EXAMPLE
2102 BUGS
2104 SEE ALSO
2106 INTERNALS
2108 TODO
2110 *****************************************************************************************/
2112 VOID BM__Hidd_BitMap__DrawPolygon(OOP_Class *cl, OOP_Object *obj,
2113 struct pHidd_BitMap_DrawPolygon *msg)
2115 #ifdef __RESERVED__
2116 OOP_Object *gc = msg->gc;
2117 WORD i;
2119 EnterFunc(bug("BitMap::DrawPolygon()"));
2121 for(i = 2; i < (2 * msg->n); i = i + 2)
2123 HIDD_BM_DrawLine(obj, gc, msg->coords[i - 2], msg->coords[i - 1],
2124 msg->coords[i], msg->coords[i + 1]);
2126 #endif
2128 ReturnVoid("BitMap::DrawPolygon");
2131 /*****************************************************************************************
2133 NAME
2134 moHidd_BitMap_FillPolygon
2136 SYNOPSIS
2137 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg);
2139 VOID HIDD_BM_FillPolygon (OOP_Object *obj, OOP_Object *gc, UWORD n, WORD *coords);
2141 LOCATION
2142 hidd.graphics.bitmap
2144 FUNCTION
2145 This method was initially designed for drawing solid polygons, however it was never
2146 used and implemented. At the moment it is considered reserved, its synopsis and
2147 semantics may change in future.
2149 INPUTS
2150 obj - A bitmap to draw on
2151 gc - A GC object to use for drawing
2152 n - number of coordinate pairs
2153 coords - array of n (x, y) coordinates in pixels
2155 RESULT
2156 None
2158 NOTES
2160 EXAMPLE
2162 BUGS
2163 Never used and implemented
2165 SEE ALSO
2167 INTERNALS
2169 TODO
2171 *****************************************************************************************/
2173 VOID BM__Hidd_BitMap__FillPolygon(OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg)
2175 D(bug("Sorry, FillPolygon() not implemented yet in bitmap baseclass\n"));
2178 /*****************************************************************************************
2180 NAME
2181 moHidd_BitMap_DrawText
2183 SYNOPSIS
2184 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2186 VOID HIDD_BM_DrawText (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2187 STRPTR text, UWORD length);
2189 LOCATION
2190 hidd.graphics.bitmap
2192 FUNCTION
2193 Draws the first length characters of text at (x, y).
2194 The function does not clip the text against the drawing area.
2196 INPUTS
2197 obj - A bitmap to draw on
2198 gc - A GC object to use for drawing and font specification
2199 x, y - Position to start drawing in pixels. The x
2200 coordinate is relativ to the left side of the
2201 first character.
2202 The y coordinate is relative to the baseline of the font.
2203 text - Pointer to a Latin 1 string
2204 length - Number of characters to draw
2206 RESULT
2207 None.
2209 NOTES
2210 At the moment text drawing is processed entirely by graphics.library
2211 using BltTemplate(), which in turn uses moHodd_BitMap_PutTemplate.
2212 This method is considered obsolete.
2214 EXAMPLE
2216 BUGS
2217 The default implementation in the base class does not process styles,
2218 color and alpha-blended fonts.
2220 SEE ALSO
2222 INTERNALS
2224 TODO
2226 *****************************************************************************************/
2228 VOID BM__Hidd_BitMap__DrawText(OOP_Class *cl, OOP_Object *obj,
2229 struct pHidd_BitMap_DrawText *msg)
2231 #ifdef __RESERVED__
2232 OOP_Object *gc = msg->gc;
2233 struct TextFont *font = GC_FONT(gc);
2234 UBYTE *charPatternPtr = font->tf_CharData;
2235 UWORD modulo = font->tf_Modulo;
2236 ULONG charLog;
2237 UBYTE ch; /* current character to print */
2238 WORD fx, fx2, fy, fw; /* position and length of character in the */
2239 /* character bitmap */
2240 WORD xMem = msg->x; /* position in bitmap */
2241 WORD yMem = msg->y - font->tf_Baseline;
2242 WORD x, y, i;
2245 EnterFunc(bug("BitMap::DrawText()"));
2247 for(i = 0; i < msg->length; i++)
2249 ch = msg->text[i];
2251 if((ch < font->tf_LoChar) || (ch > font->tf_HiChar))
2253 ch = font->tf_HiChar - font->tf_LoChar + 1;
2255 else
2257 ch = ch - font->tf_LoChar;
2260 if(font->tf_Flags & FPF_PROPORTIONAL)
2262 xMem = xMem + ((UWORD *) font->tf_CharKern)[ch];
2265 charLog = ((ULONG *) font->tf_CharLoc)[ch];
2266 fx2 = charLog >> 16; /* x position of character pattern in character bitmap */
2267 fw = (UWORD) charLog; /* width of character pattern in character bitmap */
2269 y = yMem;
2271 for(fy = 0; fy < font->tf_YSize; fy ++)
2273 x = xMem;
2275 for(fx = fx2; fx < fw + fx2; fx++)
2277 if(*(charPatternPtr + fx / 8 + fy * modulo) & (128 >> (fx % 8)))
2279 HIDD_BM_DrawPixel(obj, msg->gc, x, y);
2281 x++;
2284 y++;
2287 if(font->tf_Flags & FPF_PROPORTIONAL)
2289 xMem = xMem + ((UWORD *) font->tf_CharSpace)[ch];
2291 else
2293 xMem = xMem + font->tf_XSize;
2296 #endif
2297 ReturnVoid("BitMap::DrawText");
2300 /*****************************************************************************************
2302 NAME
2303 moHidd_BitMap_FillText
2305 SYNOPSIS
2306 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2308 VOID HIDD_BM_FillText (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2309 STRPTR text, UWORD length);
2311 LOCATION
2312 hidd.graphics.bitmap
2314 FUNCTION
2315 Historically this method was designed to draw a text with background.
2316 It was never implemented.
2318 Currently this method is considered reserved. Its synopsis and semantics
2319 may change in future.
2321 INPUTS
2322 obj - A bitmap to draw on
2323 gc - A GC object to use for drawing
2324 x, y - Position to start drawing in pixels. The x
2325 coordinate is relative to the left side of the
2326 first character.
2327 The y coordinate is relative to the baseline of the font.
2328 text - Pointer to a Latin 1 string
2329 length - Number of characters to draw
2331 RESULT
2333 NOTES
2335 EXAMPLE
2337 BUGS
2339 SEE ALSO
2341 INTERNALS
2343 TODO
2345 *****************************************************************************************/
2347 VOID BM__Hidd_BitMap__FillText(OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_DrawText *msg)
2349 D(bug("Sorry, FillText() not implemented yet in bitmap baseclass\n"));
2352 /*****************************************************************************************
2354 NAME
2355 moHidd_BitMap_FillSpan
2357 SYNOPSIS
2358 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2360 LOCATION
2361 hidd.graphics.bitmap
2363 FUNCTION
2364 Reserved, never implemented method. The definition will change in future.
2366 INPUTS
2368 RESULT
2369 None.
2371 NOTES
2373 EXAMPLE
2375 BUGS
2377 SEE ALSO
2379 INTERNALS
2381 TODO
2383 *****************************************************************************************/
2385 VOID BM__Hidd_BitMap__FillSpan(OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_DrawText *msg)
2387 D(bug("Sorry, FillSpan() not implemented yet\n"));
2390 /*****************************************************************************************
2392 NAME
2393 moHidd_BitMap_Clear
2395 SYNOPSIS
2396 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_Clear *msg);
2398 VOID HIDD_BM_Clear (OOP_Object *obj, OOP_Object *gc);
2400 LOCATION
2401 hidd.graphics.bitmap
2403 FUNCTION
2404 Sets all pixels of the drawing area to the background color.
2406 INPUTS
2407 obj - A bitmap to clear.
2408 gc - A GC object, specifies background color value
2410 RESULT
2412 NOTES
2413 This method is not used by the system and considered reserved. However it can
2414 be useful for display driver's own needs.
2416 EXAMPLE
2418 BUGS
2419 Default implementation in the base class sets all pixels to zero color instead of
2420 the background color from GC
2422 SEE ALSO
2424 INTERNALS
2426 TODO
2428 *****************************************************************************************/
2430 VOID BM__Hidd_BitMap__Clear(OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_Clear *msg)
2432 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
2433 WORD x, y;
2434 IPTR width, height;
2436 EnterFunc(bug("BitMap::Clear()\n"));
2438 OOP_GetAttr(obj, aHidd_BitMap_Width, &width);
2439 OOP_GetAttr(obj, aHidd_BitMap_Height, &height);
2441 for(y = 0; y < height; y++)
2443 for(x = 0; x < width; x++)
2445 HIDD_BM_PutPixel(obj, x, y, 0);
2449 ReturnVoid("BitMap::Clear");
2452 /****************************************************************************************/
2454 static LONG inline getpixfmtbpp(OOP_Class *cl, OOP_Object *o, HIDDT_StdPixFmt stdpf)
2456 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
2457 OOP_Object *pf;
2458 struct HIDDBitMapData *data;
2459 SIPTR bpp = -1;
2461 data = OOP_INST_DATA(cl, o);
2463 switch (stdpf)
2465 case vHidd_StdPixFmt_Native:
2466 OOP_GetAttr(data->prot.pixfmt, aHidd_PixFmt_BytesPerPixel, &bpp);
2467 break;
2469 case vHidd_StdPixFmt_Native32:
2470 bpp = sizeof (HIDDT_Pixel);
2471 break;
2473 default:
2474 pf = HIDD_Gfx_GetPixFmt(data->gfxhidd, stdpf);
2476 if (NULL == pf)
2478 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", stdpf));
2480 else
2482 OOP_GetAttr(pf, aHidd_PixFmt_BytesPerPixel, &bpp);
2484 break;
2487 return bpp;
2490 /*****************************************************************************************
2492 NAME
2493 moHidd_BitMap_GetImage
2495 SYNOPSIS
2496 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_GetImage *msg);
2498 VOID HIDD_BM_GetImage (OOP_Object *obj, UBYTE *pixels, ULONG modulo, WORD x, WORD y,
2499 WORD width, WORD height, HIDDT_StdPixFmt pixFmt);
2501 LOCATION
2502 hidd.graphics.bitmap
2504 FUNCTION
2506 INPUTS
2507 obj -
2508 pixels -
2509 modulo -
2510 x, y -
2511 width -
2512 height -
2513 pixFmt -
2515 RESULT
2517 NOTES
2519 EXAMPLE
2521 BUGS
2523 SEE ALSO
2525 INTERNALS
2527 *****************************************************************************************/
2529 VOID BM__Hidd_BitMap__GetImage(OOP_Class *cl, OOP_Object *o,
2530 struct pHidd_BitMap_GetImage *msg)
2532 WORD x, y;
2533 UBYTE *pixarray = (UBYTE *)msg->pixels;
2534 APTR ppixarray = &pixarray;
2535 WORD bpp;
2536 struct HIDDBitMapData *data;
2538 data = OOP_INST_DATA(cl, o);
2540 EnterFunc(bug("BitMap::GetImage(x=%d, y=%d, width=%d, height=%d)\n"
2541 , msg->x, msg->y, msg->width, msg->height));
2544 bpp = getpixfmtbpp(cl, o, msg->pixFmt);
2545 if (-1 == bpp)
2547 D(bug("!!! INVALID PIXFMT IN BitMap::GetImage(): %d !!!\n", msg->pixFmt));
2548 return;
2552 switch(msg->pixFmt)
2554 case vHidd_StdPixFmt_Native:
2555 case vHidd_StdPixFmt_Native32:
2556 for (y = 0; y < msg->height; y ++)
2558 for (x = 0; x < msg->width; x ++)
2560 register HIDDT_Pixel pix;
2562 pix = HIDD_BM_GetPixel(o, x + msg->x , y + msg->y);
2564 switch (bpp)
2566 case 1:
2567 *pixarray++ = pix;
2568 break;
2570 case 2:
2571 *((UWORD *)pixarray) = pix;
2572 pixarray += 2;
2573 break;
2575 case 3:
2576 #if AROS_BIG_ENDIAN
2577 pixarray[0] = (pix >> 16) & 0xFF;
2578 pixarray[1] = (pix >> 8) & 0xFF;
2579 pixarray[2] = pix & 0xFF;
2580 #else
2581 pixarray[0] = pix & 0xFF;
2582 pixarray[1] = (pix >> 8) & 0xFF;
2583 pixarray[2] = (pix >> 16) & 0xFF;
2584 #endif
2585 pixarray += 3;
2586 break;
2588 case 4:
2589 *(ULONG *)pixarray = pix;
2590 pixarray += 4;
2591 break;
2596 pixarray += (msg->modulo - msg->width * bpp);
2599 break;
2601 default:
2603 OOP_Object *dstpf;
2604 APTR buf, srcPixels;
2606 dstpf = HIDD_Gfx_GetPixFmt(data->gfxhidd, msg->pixFmt);
2608 buf = srcPixels = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
2609 if (buf)
2611 for(y = 0; y < msg->height; y++)
2613 HIDD_BM_GetImage(o,
2614 buf,
2616 msg->x,
2617 msg->y + y,
2618 msg->width,
2620 vHidd_StdPixFmt_Native);
2622 HIDD_BM_ConvertPixels(o,
2623 &srcPixels,
2624 (HIDDT_PixelFormat *)data->prot.pixfmt,
2626 (APTR *)ppixarray,
2627 (HIDDT_PixelFormat *)dstpf,
2628 msg->modulo,
2629 msg->width,
2631 NULL);
2634 FreeVec(buf);
2637 break;
2639 } /* switch(msg->pixFmt) */
2641 ReturnVoid("BitMap::GetImage");
2644 /*****************************************************************************************
2646 NAME
2647 moHidd_BitMap_PutImage
2649 SYNOPSIS
2650 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutImage *msg);
2652 VOID HIDD_BM_PutImage (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
2653 WORD x, WORD y, WORD width, WORD height, HIDDT_StdPixFmt pixFmt);
2655 LOCATION
2656 hidd.graphics.bitmap
2658 FUNCTION
2660 INPUTS
2661 obj -
2662 gc -
2663 pixels -
2664 modulo -
2665 x, y -
2666 width -
2667 height -
2668 pixFmt -
2670 RESULT
2672 NOTES
2674 EXAMPLE
2676 BUGS
2678 SEE ALSO
2680 INTERNALS
2682 *****************************************************************************************/
2684 VOID BM__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o,
2685 struct pHidd_BitMap_PutImage *msg)
2687 WORD x, y;
2688 UBYTE *pixarray = (UBYTE *)msg->pixels;
2689 APTR ppixarray = &pixarray;
2690 ULONG old_fg;
2691 WORD bpp;
2692 struct HIDDBitMapData *data;
2693 OOP_Object *gc = msg->gc;
2695 data = OOP_INST_DATA(cl, o);
2697 EnterFunc(bug("BitMap::PutImage(x=%d, y=%d, width=%d, height=%d)\n"
2698 , msg->x, msg->y, msg->width, msg->height));
2700 if (msg->width <= 0 || msg->height <= 0)
2701 return;
2703 bpp = getpixfmtbpp(cl, o, msg->pixFmt);
2704 if (-1 == bpp)
2706 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", msg->pixFmt));
2707 return;
2710 switch(msg->pixFmt)
2712 case vHidd_StdPixFmt_Native:
2713 case vHidd_StdPixFmt_Native32:
2715 /* Preserve old fg pen */
2716 old_fg = GC_FG(gc);
2718 for (y = 0; y < msg->height; y ++)
2720 for (x = 0; x < msg->width; x ++)
2722 register HIDDT_Pixel pix = 0;
2724 switch (bpp)
2726 case 1:
2727 pix = *((UBYTE *)pixarray);
2728 pixarray ++;
2729 break;
2731 case 2:
2732 pix = *((UWORD *)pixarray);
2733 pixarray += 2;
2734 break;
2736 case 3:
2737 #if AROS_BIG_ENDIAN
2738 pix = ((UBYTE *)pixarray)[0] << 16;
2739 pix |= ((UBYTE *)pixarray)[1] << 8;
2740 pix |= ((UBYTE *)pixarray)[2];
2741 #else
2742 pix = ((UBYTE *)pixarray)[2] << 16;
2743 pix |= ((UBYTE *)pixarray)[1] << 8;
2744 pix |= ((UBYTE *)pixarray)[0];
2745 #endif
2746 pixarray += 3;
2747 break;
2749 case 4:
2750 pix = *((ULONG *)pixarray); pixarray += 4;
2751 break;
2755 GC_FG(gc) = pix;
2757 HIDD_BM_DrawPixel(o, gc, x + msg->x , y + msg->y);
2759 pixarray += (msg->modulo - msg->width * bpp);
2762 GC_FG(gc) = old_fg;
2763 break;
2765 default:
2767 OOP_Object *srcpf;
2768 APTR buf, destPixels;
2770 srcpf = HIDD_Gfx_GetPixFmt(data->gfxhidd, msg->pixFmt);
2772 buf = destPixels = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
2773 if (buf)
2775 for(y = 0; y < msg->height; y++)
2777 HIDD_BM_ConvertPixels(o,
2778 (APTR *)ppixarray,
2779 (HIDDT_PixelFormat *)srcpf,
2780 msg->modulo,
2781 &destPixels,
2782 (HIDDT_PixelFormat *)data->prot.pixfmt,
2784 msg->width,
2786 NULL);
2788 HIDD_BM_PutImage(o,
2789 msg->gc,
2790 buf,
2792 msg->x,
2793 msg->y + y,
2794 msg->width,
2796 vHidd_StdPixFmt_Native);
2798 FreeVec(buf);
2801 break;
2803 } /* switch(msg->pixFmt) */
2805 ReturnVoid("BitMap::PutImage");
2808 /****************************************************************************************/
2810 int static inline
2811 __attribute__((always_inline, const)) do_alpha(int a, int v)
2813 int tmp = (a*v);
2814 return ((tmp<<8) + tmp + 32768)>>16;
2817 #if AROS_BIG_ENDIAN
2819 #define RGB32_DECOMPOSE(red, green, blue, pix) \
2820 red = ((pix) & 0x00FF0000) >> 16; \
2821 green = ((pix) & 0x0000FF00) >> 8; \
2822 blue = ((pix) & 0x000000FF);
2824 #define ARGB32_ALPHA(pix) ((pix) & 0xFF000000)
2826 #define ARGB32_DECOMPOSE(alpha, red, green, blue, pix) \
2827 alpha = ((pix) & 0xFF000000) >> 24; \
2828 red = ((pix) & 0x00FF0000) >> 16; \
2829 green = ((pix) & 0x0000FF00) >> 8; \
2830 blue = ((pix) & 0x000000FF);
2832 #define ARGB32_COMPOSE(red, green, blue, old) (((old) & 0xFF000000) + ((red) << 16) + ((green) << 8) + (blue))
2834 #else
2836 #define RGB32_DECOMPOSE(red, green, blue, pix) \
2837 red = (pix & 0x0000FF00) >> 8; \
2838 green = (pix & 0x00FF0000) >> 16; \
2839 blue = (pix & 0xFF000000) >> 24
2841 #define ARGB32_ALPHA(pix) ((pix) & 0x000000FF)
2843 #define ARGB32_DECOMPOSE(alpha, red, green, blue, pix) \
2844 alpha = (pix & 0x000000FF); \
2845 red = (pix & 0x0000FF00) >> 8; \
2846 green = (pix & 0x00FF0000) >> 16; \
2847 blue = (pix & 0xFF000000) >> 24
2849 #define ARGB32_COMPOSE(red, green, blue, old) (((blue) << 24) + ((green) << 16) + ((red) << 8) + ((old) & 0x000000FF))
2851 #endif
2853 /*****************************************************************************************
2855 NAME
2856 moHidd_BitMap_PutAlphaImage
2858 SYNOPSIS
2859 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutAlphaImage *msg);
2861 VOID HIDD_BM_PutAlphaImage (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
2862 WORD x, WORD y, WORD width, WORD height);
2864 LOCATION
2865 hidd.graphics.bitmap
2867 FUNCTION
2868 Perform an alpha-blending operation between a bitmap and ARGB pixel array.
2870 INPUTS
2871 obj - A bitmap to operate on
2872 gc - A GC object, internally needed to perform the operation. All its attributes
2873 are ignored.
2874 pixels - A pointer to an array of pixels
2875 modulo - Number of bytes per row in pixel array
2876 x, y - Top-left corner of affected bitmap's region
2877 width - Width of the modified rectangle.
2878 height - Height of the modified rectangle.
2880 RESULT
2881 None.
2883 NOTES
2884 Do not rely on 'gc' parameter being valid when implementing this method in own
2885 display driver. This parameter is actually obsolete, and will be set to NULL in
2886 future AROS versions. Current base class implementation ignores it.
2888 EXAMPLE
2890 BUGS
2892 SEE ALSO
2894 INTERNALS
2896 *****************************************************************************************/
2898 struct paib_data
2900 void *pixels;
2901 ULONG modulo;
2905 * TODOs:
2906 * 1. Merge buffered and slow versions of PutAlphaImage(), use the same processing algorithm
2907 * (convert array's pixels to bitmap's format, not vice versa)
2908 * 2. Make DoBufferedOperation() public, to be used for cybergraphics.library/ProcessPixelArray()
2909 * implementation, and for some other functions in graphics.library and cybergraphics.library,
2910 * currently using own implementation of pixel buffer.
2911 * 3. Reuse the new code for other buffered operations (currently using old macros).
2914 static void PutAlphaImageBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct paib_data *data)
2916 UWORD x, y;
2918 for (y = 0; y < height; y++)
2920 ULONG *pixarray = data->pixels;
2922 for (x = 0; x < width; x++)
2924 ULONG destpix;
2925 ULONG srcpix;
2926 ULONG src_red, src_green, src_blue, src_alpha;
2927 ULONG dst_red, dst_green, dst_blue;
2929 srcpix = *pixarray++;
2931 if (ARGB32_ALPHA(srcpix) == ARGB32_ALPHA(0xFFFFFFFF))
2933 xbuf[x] = srcpix;
2935 else if (ARGB32_ALPHA(srcpix) != 0)
2937 ARGB32_DECOMPOSE(src_alpha, src_red, src_green, src_blue, srcpix);
2939 destpix = xbuf[x];
2940 RGB32_DECOMPOSE(dst_red, dst_green, dst_blue, destpix);
2942 dst_red += do_alpha(src_alpha, src_red - dst_red);
2943 dst_green += do_alpha(src_alpha, src_green - dst_green);
2944 dst_blue += do_alpha(src_alpha, src_blue - dst_blue);
2946 xbuf[x] = ARGB32_COMPOSE(dst_red, dst_green, dst_blue, destpix);
2950 xbuf += width;
2951 data->pixels += data->modulo;
2955 VOID BM__Hidd_BitMap__PutAlphaImage(OOP_Class *cl, OOP_Object *o,
2956 struct pHidd_BitMap_PutAlphaImage *msg)
2958 WORD x, y;
2959 struct paib_data data = {msg->pixels, msg->modulo};
2961 EnterFunc(bug("BitMap::PutAlphaImage(x=%d, y=%d, width=%d, height=%d)\n"
2962 , msg->x, msg->y, msg->width, msg->height));
2964 if (msg->width <= 0 || msg->height <= 0)
2965 return;
2967 if (!DoBufferedOperation(cl, o, msg->x, msg->y, msg->width, msg->height, TRUE, vHidd_StdPixFmt_ARGB32,
2968 (VOID_FUNC)PutAlphaImageBuffered, &data))
2970 /* Buffered method failed, use slow pixel-by-pixel method */
2971 for (y = msg->y; y < msg->y + msg->height; y++)
2973 ULONG *pixarray = data.pixels;
2975 for (x = msg->x; x < msg->x + msg->width; x++)
2977 HIDDT_Pixel destpix;
2978 HIDDT_Color col;
2979 ULONG srcpix;
2980 LONG src_red, src_green, src_blue, src_alpha;
2981 LONG dst_red, dst_green, dst_blue;
2983 destpix = HIDD_BM_GetPixel(o, x, y);
2984 HIDD_BM_UnmapPixel(o, destpix, &col);
2986 srcpix = *pixarray++;
2987 ARGB32_DECOMPOSE(src_alpha, src_red, src_green, src_blue, srcpix);
2989 dst_red = col.red >> 8;
2990 dst_green = col.green >> 8;
2991 dst_blue = col.blue >> 8;
2993 dst_red += do_alpha(src_alpha, src_red - dst_red);
2994 dst_green += do_alpha(src_alpha, src_green - dst_green);
2995 dst_blue += do_alpha(src_alpha, src_blue - dst_blue);
2997 col.red = dst_red << 8;
2998 col.green = dst_green << 8;
2999 col.blue = dst_blue << 8;
3001 HIDD_BM_PutPixel(o, x, y, HIDD_BM_MapColor(o, &col));
3003 } /* for(x = msg->x; x < msg->x + msg->width; x++) */
3005 data.pixels += msg->modulo;
3007 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
3009 ReturnVoid("BitMap::PutAlphaImage");
3012 /*****************************************************************************************
3014 NAME
3015 moHidd_BitMap_PutTemplate
3017 SYNOPSIS
3018 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutTemplate *msg);
3020 VOID HIDD_BM_PutTemplate (OOP_Object *obj, OOP_Object *gc, UBYTE *masktemplate, ULONG modulo,
3021 WORD srcx, WORD x, WORD y, WORD width, WORD height, BOOL inverttemplate);
3023 LOCATION
3024 hidd.graphics.bitmap
3026 FUNCTION
3027 Apply a single-bit mask to the given portion of the bitmap. Pixels set to 1 in the mask will be filled
3028 by foreground color. Pixels set to 0 in the mask will be filled by background color or left unchanged,
3029 according to the following GC attributes:
3030 Foreground - a foreground color
3031 Background - a background color
3032 DrawMode - if set to Invert, foreground and background colors will be ignored. Instead,
3033 pixels which are set to 1 in the mask, will be inverted. Other pixels will be
3034 left unchanged.
3035 ColorExpansion - if set to Transparent, only pixels which are set to 1 in the mask, will be modified.
3036 Other pixels will not be changed (background color will be ignored).
3038 INPUTS
3039 obj - A bitmap to draw on
3040 gc - A GC object, holding operation parameters
3041 masktemplate - A pointer to a bit mask
3042 modulo - Number of bytes per line in the mask
3043 srcx - Horizontal offset of the mask
3044 x, y - Top-left corner of the bitmap's region to affect
3045 width - Width of the affected region
3046 height - Height of the affected region
3047 inverttemplate - If set to TRUE, bit mask will be interpreted in inverted form
3049 RESULT
3050 None
3052 NOTES
3054 EXAMPLE
3056 BUGS
3058 SEE ALSO
3060 INTERNALS
3062 *****************************************************************************************/
3064 struct ptb_data
3066 void *bitarray;
3067 ULONG bitmask;
3068 ULONG modulo;
3069 ULONG fg;
3070 ULONG bg;
3071 UWORD invert;
3074 static void JAM1TemplateBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ptb_data *data)
3076 UWORD x, y;
3078 for (y = 0; y < height; y++)
3080 ULONG mask = data->bitmask;
3081 UWORD *array = data->bitarray;
3082 UWORD bitword = AROS_BE2WORD(*array);
3084 for (x = 0; x < width; x++)
3086 if ((bitword & mask) == (data->invert & mask))
3087 xbuf[x] = data->fg;
3089 mask >>= 1;
3090 if (!mask)
3092 mask = 0x8000;
3093 array++;
3094 bitword = AROS_BE2WORD(*array);
3098 xbuf += width;
3099 data->bitarray += data->modulo;
3103 static void ComplementTemplateBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ptb_data *data)
3105 UWORD x, y;
3107 for (y = 0; y < height; y++)
3109 ULONG mask = data->bitmask;
3110 UWORD *array = data->bitarray;
3111 UWORD bitword = AROS_BE2WORD(*array);
3113 for (x = 0; x < width; x++)
3115 if ((bitword & mask) == (data->invert & mask))
3116 xbuf[x] = ~xbuf[x];
3118 mask >>= 1;
3119 if (!mask)
3121 mask = 0x8000;
3122 array++;
3123 bitword = AROS_BE2WORD(*array);
3127 xbuf += width;
3128 data->bitarray += data->modulo;
3132 static void JAM2TemplateBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ptb_data *data)
3134 UWORD x, y;
3136 for (y = 0; y < height; y++)
3138 ULONG mask = data->bitmask;
3139 UWORD *array = data->bitarray;
3140 UWORD bitword = AROS_BE2WORD(*array);
3142 for (x = 0; x < width; x++)
3144 if ((bitword & mask) == (data->invert & mask))
3145 xbuf[x] = data->fg;
3146 else
3147 xbuf[x] = data->bg;
3149 mask >>= 1;
3150 if (!mask)
3152 mask = 0x8000;
3153 array++;
3154 bitword = AROS_BE2WORD(*array);
3158 xbuf += width;
3159 data->bitarray += data->modulo;
3163 VOID BM__Hidd_BitMap__PutTemplate(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutTemplate *msg)
3165 OOP_Object *gc = msg->gc;
3166 BOOL get = TRUE;
3167 void (*op)(ULONG *, UWORD, UWORD, UWORD, struct ptb_data *);
3168 struct ptb_data data;
3170 EnterFunc(bug("BitMap::PutTemplate(x=%d, y=%d, width=%d, height=%d)\n"
3171 , msg->x, msg->y, msg->width, msg->height));
3173 if (msg->width <= 0 || msg->height <= 0)
3174 return;
3176 if (GC_COLEXP(gc) == vHidd_GC_ColExp_Transparent)
3178 op = JAM1TemplateBuffered;
3180 else if (GC_DRMD(gc) == vHidd_GC_DrawMode_Invert)
3182 op = ComplementTemplateBuffered;
3184 else
3186 op = JAM2TemplateBuffered;
3187 get = FALSE;
3190 data.bitarray = msg->masktemplate + ((msg->srcx / 16) * 2);
3191 data.bitmask = 0x8000 >> (msg->srcx & 0xF);
3192 data.modulo = msg->modulo;
3193 data.fg = GC_FG(msg->gc);
3194 data.bg = GC_BG(msg->gc);
3195 data.invert = msg->inverttemplate ? 0 : 0xFFFF;
3197 DoBufferedOperation(cl, o, msg->x, msg->y, msg->width, msg->height, get, vHidd_StdPixFmt_Native32, (VOID_FUNC)op, &data);
3199 /* TODO: write fallback */
3201 ReturnVoid("BitMap::PutTemplate");
3204 /*****************************************************************************************
3206 NAME
3207 moHidd_BitMap_PutAlphaTemplate
3209 SYNOPSIS
3210 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutAlphaTemplate *msg);
3212 VOID HIDD_BM_PutAlphaTemplate (OOP_Object *obj, OOP_Object *gc, UBYTE *alpha, ULONG modulo,
3213 WORD x, WORD y, WORD width, WORD height, BOOL invertalpha);
3215 LOCATION
3216 hidd.graphics.bitmap
3218 FUNCTION
3219 Perform a drawing with current foreground color, using 8-bit alpha channel mask. The following
3220 GC attributes are considered:
3221 Foreground - a foreground color
3222 Background - a background color
3223 DrawMode - if set to Invert, foreground and background colors will be ignored. Instead,
3224 pixels, for which alpha channel value is greater than 127, will be inverted.
3225 Other pixels will be left unchanged.
3226 ColorExpansion - if set to Opaque, alpha blending will happen between foreground and background
3227 colors, instead of between foreground color and old bitmap contents.
3229 INPUTS
3230 obj - A bitmap to draw on
3231 gc - A GC object specifying drawing parameters
3232 alpha - A pointer to a 8-bit per pixel alpha channel mask
3233 modulo - Number of bytes per line in the mask
3234 x, y - Top-left corner of the affected bitmap's region
3235 width - Width of the affected bitmap's region
3236 height - Height of the affected bitmap's region
3237 invertalpha - If set to TRUE, alpha mask values will be treated in inverted form
3239 RESULT
3240 None
3242 NOTES
3244 EXAMPLE
3246 BUGS
3248 SEE ALSO
3250 INTERNALS
3252 *****************************************************************************************/
3254 struct patb_data
3256 UBYTE *pixarray;
3257 ULONG modulo;
3258 LONG a_red, a_green, a_blue;
3259 LONG b_red, b_green, b_blue;
3260 UBYTE invert;
3263 static void JAM1AlphaTemplateBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct patb_data *data)
3265 UWORD x, y;
3267 for (y = 0; y < height; y++)
3269 UBYTE *pixarray = data->pixarray;
3271 for (x = 0; x < width; x++)
3273 LONG dst_red, dst_green, dst_blue, alpha;
3275 alpha = (*pixarray++) ^ data->invert;
3276 RGB32_DECOMPOSE(dst_red, dst_green, dst_blue, xbuf[x]);
3278 dst_red += do_alpha(alpha, data->a_red - dst_red);
3279 dst_green += do_alpha(alpha, data->a_green - dst_green);
3280 dst_blue += do_alpha(alpha, data->a_blue - dst_blue);
3282 xbuf[x] = ARGB32_COMPOSE(dst_red, dst_green, dst_blue, 0);
3285 xbuf += width;
3286 data->pixarray += data->modulo;
3290 static void ComplementAlphaTemplateBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct patb_data *data)
3292 UWORD x, y;
3294 for (y = 0; y < height; y++)
3296 UBYTE *pixarray = data->pixarray;
3298 for (x = 0; x < width; x++)
3300 UBYTE alpha = (*pixarray++) ^ data->invert;
3302 if (alpha >= 0x80)
3303 xbuf[x] = ~xbuf[x];
3306 xbuf += width;
3307 data->pixarray += data->modulo;
3311 static void JAM2AlphaTemplateBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct patb_data *data)
3313 UWORD x, y;
3315 for (y = 0; y < height; y++)
3317 UBYTE *pixarray = data->pixarray;
3319 for (x = 0; x < width; x++)
3321 LONG dst_red, dst_green, dst_blue, alpha;
3323 alpha = (*pixarray++) ^ data->invert;
3325 dst_red = data->b_red + ((data->a_red - data->b_red) * alpha) / 256;
3326 dst_green = data->b_green + ((data->a_green - data->b_green) * alpha) / 256;
3327 dst_blue = data->b_blue + ((data->a_blue - data->b_blue) * alpha) / 256;
3329 xbuf[x] = ARGB32_COMPOSE(dst_red, dst_green, dst_blue, 0);
3332 xbuf += width;
3333 data->pixarray += data->modulo;
3337 VOID BM__Hidd_BitMap__PutAlphaTemplate(OOP_Class *cl, OOP_Object *o,
3338 struct pHidd_BitMap_PutAlphaTemplate *msg)
3340 OOP_Object *gc = msg->gc;
3341 BOOL get = TRUE;
3342 void (*op)(ULONG *, UWORD, UWORD, UWORD, struct patb_data *);
3343 struct patb_data data;
3344 HIDDT_Color color;
3346 EnterFunc(bug("BitMap::PutAlphaTemplate(x=%d, y=%d, width=%d, height=%d)\n"
3347 , msg->x, msg->y, msg->width, msg->height));
3349 if (msg->width <= 0 || msg->height <= 0)
3350 return;
3352 HIDD_BM_UnmapPixel(o, GC_FG(gc), &color);
3353 data.a_red = color.red >> 8;
3354 data.a_green = color.green >> 8;
3355 data.a_blue = color.blue >> 8;
3357 if (GC_COLEXP(gc) == vHidd_GC_ColExp_Transparent)
3359 op = JAM1AlphaTemplateBuffered;
3361 else if (GC_DRMD(gc) == vHidd_GC_DrawMode_Invert)
3363 op = ComplementAlphaTemplateBuffered;
3365 else
3367 op = JAM2AlphaTemplateBuffered;
3368 get = FALSE;
3370 HIDD_BM_UnmapPixel(o, GC_BG(gc), &color);
3371 data.b_red = color.red >> 8;
3372 data.b_green = color.green >> 8;
3373 data.b_blue = color.blue >> 8;
3376 data.pixarray = msg->alpha;
3377 data.modulo = msg->modulo;
3378 data.invert = msg->invertalpha ? 255 : 0;
3380 DoBufferedOperation(cl, o, msg->x, msg->y, msg->width, msg->height, get, vHidd_StdPixFmt_ARGB32, (VOID_FUNC)op, &data);
3382 /* TODO: write fallback */
3384 ReturnVoid("BitMap::PutAlphaTemplate");
3387 /*****************************************************************************************
3389 NAME
3390 moHidd_BitMap_PutPattern
3392 SYNOPSIS
3393 VOID OOP_DoMethod(OOP_Object *o, struct pHidd_BitMap_PutPattern *msg);
3395 VOID HIDD_BM_PutPattern(OOP_Object *obj, OOP_Object *gc, UBYTE *pattern,
3396 WORD patternsrcx, WORD patternsrcy, WORD patternheight, WORD patterndepth,
3397 HIDDT_PixelLUT *patternlut, BOOL invertpattern, UBYTE *mask,
3398 ULONG maskmodulo, WORD masksrcx, WORD x, WORD y,
3399 WORD width, WORD height);
3401 LOCATION
3402 hidd.graphics.bitmap
3404 FUNCTION
3406 INPUTS
3407 obj - A bitmap to draw on
3408 gc - A GC object to use for drawing
3409 pattern -
3410 patternsrcx -
3411 patternsrcy -
3412 patternheight -
3413 patterndepth -
3414 patternlut -
3415 invertpattern -
3416 mask -
3417 maskmodulo -
3418 masksrcx -
3419 x, y -
3420 width -
3421 height -
3423 RESULT
3424 None
3426 NOTES
3428 EXAMPLE
3430 BUGS
3432 SEE ALSO
3434 INTERNALS
3436 *****************************************************************************************/
3438 struct ppb_data
3440 UWORD *patarray;
3441 void *maskarray;
3442 ULONG *patternlut;
3443 UWORD patternsrcy;
3444 UWORD desty;
3445 UWORD patternheight;
3446 ULONG maskmodulo;
3447 ULONG fg;
3448 ULONG bg;
3449 UWORD patmask;
3450 UWORD maskmask;
3451 UWORD patterndepth;
3452 UWORD invert;
3455 static void JAM1PatternBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ppb_data *data)
3457 UWORD x, y;
3459 for (y = 0; y < height; y++)
3461 UWORD pmask = data->patmask;
3462 UWORD mmask = data->maskmask;
3463 UWORD *parray = data->patarray + ((y + starty + data->patternsrcy - data->desty) % data->patternheight);
3464 UWORD patword = AROS_BE2WORD(*parray);
3465 UWORD *marray = data->maskarray;
3466 UWORD maskword = marray ? AROS_BE2WORD(*marray) : 0xFFFF;
3468 for (x = 0; x < width; x++)
3470 if (maskword & mmask)
3472 if ((patword & pmask) == (data->invert & pmask))
3473 xbuf[x] = data->fg;
3476 if (marray)
3478 mmask >>= 1;
3479 if (!mmask)
3481 mmask = 0x8000;
3482 marray++;
3483 maskword = AROS_BE2WORD(*marray);
3487 pmask >>= 1;
3488 if (!pmask)
3489 pmask = 0x8000;
3491 } /* for (x) */
3493 xbuf += width;
3494 if (data->maskarray)
3495 data->maskarray += data->maskmodulo;
3497 } /* for (y) */
3500 static void ComplementPatternBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ppb_data *data)
3502 UWORD x, y;
3504 for (y = 0; y < height; y++)
3506 UWORD pmask = data->patmask;
3507 UWORD mmask = data->maskmask;
3508 UWORD *parray = data->patarray + ((y + starty + data->patternsrcy - data->desty) % data->patternheight);
3509 UWORD patword = AROS_BE2WORD(*parray);
3510 UWORD *marray = data->maskarray;
3511 UWORD maskword = marray ? AROS_BE2WORD(*marray) : 0xFFFF;
3513 for (x = 0; x < width; x++)
3515 if (maskword & mmask)
3517 if ((patword & pmask) == (data->invert & pmask))
3518 xbuf[x] = ~xbuf[x];
3521 if (marray)
3523 mmask >>= 1;
3524 if (!mmask)
3526 mmask = 0x8000;
3527 marray++;
3528 maskword = AROS_BE2WORD(*marray);
3532 pmask >>= 1;
3533 if (!pmask)
3534 pmask = 0x8000;
3536 } /* for (x) */
3538 xbuf += width;
3539 if (data->maskarray)
3540 data->maskarray += data->maskmodulo;
3542 } /* for (y) */
3545 static void JAM2PatternBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ppb_data *data)
3547 UWORD x, y;
3549 for (y = 0; y < height; y++)
3551 UWORD pmask = data->patmask;
3552 UWORD mmask = data->maskmask;
3553 UWORD *parray = data->patarray + ((y + starty + data->patternsrcy - data->desty) % data->patternheight);
3554 UWORD patword = AROS_BE2WORD(*parray);
3555 UWORD *marray = data->maskarray;
3556 UWORD maskword = marray ? AROS_BE2WORD(*marray) : 0xFFFF;
3558 for (x = 0; x < width; x++)
3560 if (maskword & mmask)
3562 if ((patword & pmask) == (data->invert & pmask))
3563 xbuf[x] = data->fg;
3564 else
3565 xbuf[x] = data->bg;
3568 if (marray)
3570 mmask >>= 1;
3571 if (!mmask)
3573 mmask = 0x8000;
3574 marray++;
3575 maskword = AROS_BE2WORD(*marray);
3579 pmask >>= 1;
3580 if (!pmask)
3581 pmask = 0x8000;
3583 } /* for (x) */
3585 xbuf += width;
3586 if (data->maskarray)
3587 data->maskarray += data->maskmodulo;
3589 } /* for (y) */
3592 static void ColorPatternBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ppb_data *data)
3594 UWORD x, y;
3596 for (y = 0; y < height; y++)
3598 UWORD pmask = data->patmask;
3599 UWORD mmask = data->maskmask;
3600 UWORD *parray = data->patarray + ((y + starty + data->patternsrcy - data->desty) % data->patternheight);
3601 UWORD patword = AROS_BE2WORD(*parray);
3602 UWORD *marray = data->maskarray;
3603 UWORD maskword = marray ? AROS_BE2WORD(*marray) : 0xFFFF;
3605 for (x = 0; x < width; x++)
3607 if (maskword & mmask)
3609 UWORD plane;
3610 ULONG pixel = (patword & pmask) ? 1 : 0; /* CHECKME: Shouldn't we handle INVERSVID here too ? */
3612 for (plane = 1; plane < data->patterndepth; plane++)
3614 UWORD *_parray = parray + plane * data->patternheight;
3615 UWORD _patword = AROS_BE2WORD(*_parray);
3617 if (_patword & pmask)
3618 pixel |= 1L << plane;
3621 if (data->patternlut)
3622 pixel = data->patternlut[pixel];
3624 xbuf[x] = pixel;
3627 if (marray)
3629 mmask >>= 1;
3630 if (!mmask)
3632 mmask = 0x8000;
3633 marray++;
3634 maskword = AROS_BE2WORD(*marray);
3638 pmask >>= 1;
3639 if (!pmask)
3640 pmask = 0x8000;
3642 } /* for (x) */
3644 xbuf += width;
3645 if (data->maskarray)
3646 data->maskarray += data->maskmodulo;
3648 } /* for (y) */
3651 VOID BM__Hidd_BitMap__PutPattern(OOP_Class *cl, OOP_Object *o,
3652 struct pHidd_BitMap_PutPattern *msg)
3654 void (*op)(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ppb_data *data);
3655 BOOL get = TRUE;
3656 struct ppb_data data;
3658 DPUTPATTERN(bug("BitMap::PutPattern(x=%d, y=%d, width=%d, height=%d)\n",
3659 msg->x, msg->y, msg->width, msg->height));
3661 if (msg->width <= 0 || msg->height <= 0)
3662 return;
3664 if (msg->patterndepth > 1)
3666 DPUTPATTERN(bug("[PutPattern] Color\n"));
3667 op = ColorPatternBuffered;
3668 get = FALSE;
3670 else if (GC_COLEXP(msg->gc) == vHidd_GC_ColExp_Transparent)
3672 DPUTPATTERN(bug("[PutPattern] JAM1\n"));
3673 op = JAM1PatternBuffered;
3675 else if (GC_DRMD(msg->gc) == vHidd_GC_DrawMode_Invert)
3677 DPUTPATTERN(bug("[PutPattern] Complement\n"));
3678 op = ComplementPatternBuffered;
3680 else
3682 DPUTPATTERN(bug("[PutPattern] JAM2\n"));
3683 op = JAM2PatternBuffered;
3684 get = FALSE;
3687 data.patarray = (UWORD *)msg->pattern;
3688 data.patmask = 0x8000 >> (msg->patternsrcx & 0xF);
3689 data.maskarray = msg->mask;
3690 data.patternlut = msg->patternlut ? msg->patternlut->pixels : NULL;
3691 data.patternsrcy = msg->patternsrcy;
3692 data.desty = msg->y;
3693 data.patternheight = msg->patternheight;
3694 data.patterndepth = msg->patterndepth;
3695 data.maskmodulo = msg->maskmodulo;
3696 data.fg = GC_FG(msg->gc);
3697 data.bg = GC_BG(msg->gc);
3698 data.invert = msg->invertpattern ? 0 : 0xFFFF;
3700 if (data.maskarray)
3702 data.maskarray += (msg->masksrcx / 16) * 2;
3703 data.maskmask = 0x8000 >> (msg->masksrcx & 0xF);
3704 get = TRUE;
3706 else
3707 data.maskmask = 0xFFFF;
3709 DPUTPATTERN(bug("[PutPattern] MaskArray 0x%p, MaskMask 0x%04X\n", data.maskarray, data.maskmask));
3711 DoBufferedOperation(cl, o, msg->x, msg->y, msg->width, msg->height, get, vHidd_StdPixFmt_Native32, (VOID_FUNC)op, &data);
3713 /* TODO: Write fallback */
3715 ReturnVoid("BitMap::PutPattern");
3718 /*****************************************************************************************
3720 NAME
3721 moHidd_BitMap_PutImageLUT
3723 SYNOPSIS
3724 VOID OOP_DoMethod(OOP_Object *o, struct pHidd_BitMap_PutImageLUT *msg);
3726 VOID HIDD_BM_PutImageLUT (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
3727 WORD x, WORD y, WORD width, WORD height, HIDDT_PixelLUT *pixlut);
3729 LOCATION
3730 hidd.graphics.bitmap
3732 FUNCTION
3734 INPUTS
3735 obj -
3736 gc -
3737 pixels -
3738 modulo -
3739 x, y -
3740 width -
3741 height -
3742 pixlut -
3744 RESULT
3746 NOTES
3748 EXAMPLE
3750 BUGS
3752 SEE ALSO
3754 INTERNALS
3756 *****************************************************************************************/
3758 VOID BM__Hidd_BitMap__PutImageLUT(OOP_Class *cl, OOP_Object *o,
3759 struct pHidd_BitMap_PutImageLUT *msg)
3761 WORD x, y;
3762 UBYTE *pixarray = (UBYTE *)msg->pixels;
3763 HIDDT_PixelLUT *pixlut = msg->pixlut;
3764 HIDDT_Pixel *lut = pixlut ? pixlut->pixels : NULL;
3765 HIDDT_Pixel *linebuf;
3766 OOP_Object *gc = msg->gc;
3768 EnterFunc(bug("BitMap::PutImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
3769 , msg->x, msg->y, msg->width, msg->height));
3771 if (msg->width <= 0 || msg->height <= 0)
3772 return;
3774 linebuf = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
3776 for(y = 0; y < msg->height; y++)
3778 if (linebuf)
3780 if (lut)
3782 for(x = 0; x < msg->width; x++)
3784 linebuf[x] = lut[pixarray[x]];
3787 else
3789 for(x = 0; x < msg->width; x++)
3791 linebuf[x] = pixarray[x];
3794 pixarray += msg->modulo;
3796 HIDD_BM_PutImage(o,
3797 msg->gc,
3798 (UBYTE *)linebuf,
3800 msg->x,
3801 msg->y + y,
3802 msg->width,
3804 vHidd_StdPixFmt_Native32);
3806 } /* if (linebuf) */
3807 else
3809 ULONG old_fg;
3811 /* Preserve old fg pen */
3812 old_fg = GC_FG(gc);
3814 if (lut)
3816 for(x = 0; x < msg->width; x++)
3818 GC_FG(gc) = lut[pixarray[x]];
3819 HIDD_BM_DrawPixel(o, gc, msg->x + x, msg->y + y);
3822 else
3824 for(x = 0; x < msg->width; x++)
3826 GC_FG(gc) = pixarray[x];
3827 HIDD_BM_DrawPixel(o, gc, msg->x + x, msg->y + y);
3830 GC_FG(gc) = old_fg;
3832 pixarray += msg->modulo;
3834 } /* if (linebuf) else ... */
3836 } /* for(y = 0; y < msg->height; y++) */
3838 FreeVec(linebuf);
3840 ReturnVoid("BitMap::PutImageLUT");
3842 /*****************************************************************************************
3844 NAME
3845 moHidd_BitMap_PutTranspImageLUT
3847 SYNOPSIS
3848 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutTranspImageLUT *msg);
3850 VOID HIDD_BM_PutTranspImageLUT (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels,
3851 ULONG modulo, WORD x, WORD y, WORD width, WORD height,
3852 HIDDT_PixelLUT *pixlut, UBYTE transparent);
3854 LOCATION
3855 hidd.graphics.bitmap
3857 FUNCTION
3858 Copy an array of 8-bit LUT pixels to the bitmap at the specified position making
3859 one of colors transparent.
3861 Pixels are converted to bitmap's native format using either user-supplied LUT (if
3862 given) or bitmap's own colormap.
3864 Draw mode of the supplied GC is ignored, the operation is always bulk copy.
3866 INPUTS
3867 obj - A bitmap to draw image on
3868 gc - A GC used for drawing
3869 pixels - A pointer to source pixel array
3870 modulo - Total number of bytes per line in the source array
3871 x, y - Top-left corner of the destination rectangle
3872 width - Width of the image to draw
3873 height - Height of the image to draw
3874 pixlut - An optional pointer to a LUT to use. NULL means using bitmap's
3875 own colormap (if available)
3876 transparent - Value of pixels in the source array which will be made
3877 transparent
3879 RESULT
3880 None
3882 NOTES
3884 EXAMPLE
3886 BUGS
3888 SEE ALSO
3890 INTERNALS
3892 *****************************************************************************************/
3894 #undef csd /* Bad hack, but there's no other way */
3896 struct ptilb_data
3898 UBYTE *pixarray;
3899 ULONG *lut;
3900 OOP_Object *colmap;
3901 struct class_static_data *csd;
3902 ULONG modulo;
3903 UBYTE transparent;
3906 static void PutTranspImageLUTBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ptilb_data *data)
3908 struct class_static_data *csd = data->csd;
3909 UWORD x, y;
3911 for (y = 0; y < height; y++)
3913 UBYTE *pixarray = data->pixarray;
3915 if (data->lut)
3917 for (x = 0; x < width; x++)
3919 UBYTE pix = *pixarray++;
3921 if (pix != data->transparent)
3922 xbuf[x] = data->lut[pix];
3924 } /* for (x) */
3926 else
3928 for (x = 0; x < width; x++)
3930 UBYTE pix = *pixarray++;
3932 if (pix != data->transparent)
3934 if (data->colmap)
3935 pix = HIDD_CM_GetPixel(data->colmap, pix);
3937 xbuf[x] = pix;
3940 } /* for (x) */
3943 xbuf += width;
3944 data->pixarray += data->modulo;
3945 } /* for (y) */
3948 VOID BM__Hidd_BitMap__PutTranspImageLUT(OOP_Class *cl, OOP_Object *o,
3949 struct pHidd_BitMap_PutTranspImageLUT *msg)
3951 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
3952 struct ptilb_data userdata =
3954 msg->pixels,
3955 NULL,
3956 data->colmap,
3957 CSD(cl),
3958 msg->modulo,
3959 msg->transparent
3962 EnterFunc(bug("BitMap::PutTranspImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
3963 , msg->x, msg->y, msg->width, msg->height));
3965 if (msg->width <= 0 || msg->height <= 0)
3966 return;
3968 if (msg->pixlut)
3969 userdata.lut = msg->pixlut->pixels;
3971 DoBufferedOperation(cl, o, msg->x, msg->y, msg->width, msg->height, TRUE, vHidd_StdPixFmt_Native32,
3972 (VOID_FUNC)PutTranspImageLUTBuffered, &userdata);
3974 /* TODO: Write fallback */
3976 ReturnVoid("BitMap::PutTranspImageLUT");
3979 #define csd CSD(cl)
3981 /*****************************************************************************************
3983 NAME
3984 moHidd_BitMap_GetImageLUT
3986 SYNOPSIS
3987 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_GetImageLUT *msg);
3989 VOID HIDD_BM_GetImageLUT (OOP_Object *obj, UBYTE *pixels, ULONG modulo, WORD x, WORD y,
3990 WORD width, WORD height, HIDDT_PixelLUT *pixlut);
3992 LOCATION
3993 hidd.graphics.bitmap
3995 FUNCTION
3997 INPUTS
3998 obj -
3999 pixels -
4000 modulo -
4001 x, y -
4002 width -
4003 height -
4004 pixlut -
4006 RESULT
4008 NOTES
4010 EXAMPLE
4012 BUGS
4014 SEE ALSO
4016 INTERNALS
4018 *****************************************************************************************/
4020 VOID BM__Hidd_BitMap__GetImageLUT(OOP_Class *cl, OOP_Object *o,
4021 struct pHidd_BitMap_GetImageLUT *msg)
4023 WORD x, y;
4024 UBYTE *pixarray = (UBYTE *)msg->pixels;
4025 HIDDT_PixelLUT *pixlut = msg->pixlut;
4026 HIDDT_Pixel *lut = pixlut ? pixlut->pixels : NULL;
4027 HIDDT_Pixel *linebuf;
4029 EnterFunc(bug("BitMap::GetImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
4030 , msg->x, msg->y, msg->width, msg->height));
4032 linebuf = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
4034 for(y = 0; y < msg->height; y++)
4036 if (linebuf)
4038 HIDD_BM_GetImage(o,
4039 (UBYTE *)linebuf,
4041 msg->x,
4042 msg->y + y,
4043 msg->width,
4045 vHidd_StdPixFmt_Native32);
4046 if (lut)
4048 /* FIXME: This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway */
4049 for(x = 0; x < msg->width; x++)
4051 pixarray[x] = (UBYTE)linebuf[x];
4054 else
4056 for(x = 0; x < msg->width; x++)
4058 pixarray[x] = (UBYTE)linebuf[x];
4061 pixarray += msg->modulo;
4063 } /* if (linebuf) */
4064 else
4066 if (lut)
4068 /* FIXME: This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway */
4069 for(x = 0; x < msg->width; x++)
4071 pixarray[x] = (UBYTE)HIDD_BM_GetPixel(o, msg->x + x, msg->y + y);
4074 else
4076 for(x = 0; x < msg->width; x++)
4078 pixarray[x] = (UBYTE)HIDD_BM_GetPixel(o, msg->x + x, msg->y + y);
4082 pixarray += msg->modulo;
4084 } /* if (linebuf) else ... */
4086 } /* for(y = 0; y < msg->height; y++) */
4088 if (linebuf) FreeVec(linebuf);
4090 ReturnVoid("BitMap::GetImageLUT");
4093 /*****************************************************************************************
4095 NAME
4096 moHidd_BitMap_BlitColorExpansion
4098 SYNOPSIS
4099 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BlitColorExpansion *msg);
4101 VOID HIDD_BM_BlitColorExpansion (OOP_Object *obj, OOP_Object *gc, OOP_Object *srcBitMap,
4102 WORD srcX, WORD srcY, WORD destX, WORD destY,
4103 UWORD width, UWORD height);
4105 LOCATION
4106 hidd.graphics.bitmap
4108 FUNCTION
4109 Perform a color expansion of the mask in srcBitMap according to foreground and background
4110 colors and expansion mode specified by the supplied GC. Pixels which are set to zero in
4111 the mask bitmap will be either painted by background (in opaque mode) or left without
4112 change (in transparent mode). Pixels which are set to nonzero in the mask will be painted
4113 by foreground color.
4115 The result of expansion is blitted onto the destination bitmap accorging to GC's draw mode.
4117 INPUTS
4118 obj - A bitmap to draw on
4119 gc - A GC object to use for drawing
4120 srcBitMap - A bitmap object containing mask image.
4121 srcX, srcY - A top-left coordinate of the used rectangle in the source bitmap
4122 destX, destY - A top-left coordinate of the destination rectangle to draw in
4123 width, height - A size of the rectangle to blit
4125 RESULT
4126 None.
4128 NOTES
4129 This method was previously used by graphics.library/Text() to draw fonts with no
4130 styles specified. Currently graphics.library always uses BltTemplate() and this
4131 method is considered obsolete.
4133 EXAMPLE
4135 BUGS
4137 SEE ALSO
4139 INTERNALS
4141 *****************************************************************************************/
4143 VOID BM__Hidd_BitMap__BlitColorExpansion(OOP_Class *cl, OOP_Object *o,
4144 struct pHidd_BitMap_BlitColorExpansion *msg)
4146 #ifdef __RESERVED__
4147 ULONG cemd;
4148 ULONG fg, bg;
4149 WORD x, y;
4151 OOP_Object *gc = msg->gc;
4153 EnterFunc(bug("BitMap::BlitColorExpansion(srcBM=%p, srcX=%d, srcY=%d, destX=%d, destY=%d, width=%d, height=%d)\n",
4154 msg->srcBitMap, msg->srcX, msg->srcY, msg->destX, msg->destY, msg->width, msg->height));
4156 cemd = GC_COLEXP(gc);
4157 fg = GC_FG(gc);
4158 bg = GC_BG(gc);
4160 /* bug("------------- Blit_ColExp: (%d, %d, %d, %d, %d, %d) cemd=%d, fg=%p, bg=%p -------------\n"
4161 , msg->srcX, msg->srcY, msg->destX, msg->destY, msg->width, msg->height
4162 , cemd, fg, bg);
4164 for (y = 0; y < msg->height; y ++)
4166 for (x = 0; x < msg->width; x ++)
4168 ULONG is_set;
4170 /* Pixel value is either 0 or 1 for BM of depth 1 */
4171 is_set = HIDD_BM_GetPixel(msg->srcBitMap, x + msg->srcX, y + msg->srcY);
4174 if (is_set)
4175 bug("#");
4176 else
4177 bug(" ");
4179 if (is_set)
4181 HIDD_BM_DrawPixel(o, gc, x + msg->destX, y + msg->destY);
4183 else
4185 if (cemd & vHidd_GC_ColExp_Opaque)
4187 /* Write bixel with BG pen */
4188 GC_FG(gc) = bg;
4189 HIDD_BM_DrawPixel(o, gc, x + msg->destX, y + msg->destY);
4190 /* Reset to FG pen */
4191 GC_FG(gc) = fg;
4194 } /* if () */
4196 } /* for (each x) */
4198 bug("\n");
4200 } /* for ( each y ) */
4201 #endif
4203 ReturnVoid("BitMap::BlitColorExpansion");
4206 /*****************************************************************************************
4208 NAME
4209 moHidd_BitMap_BytesPerLine
4211 SYNOPSIS
4212 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BytesPerLine *msg);
4214 ULONG HIDD_BM_BytesPerLine(OOP_Object *obj, HIDDT_StdPixFmt pixFmt, UWORD width);
4216 LOCATION
4217 hidd.graphics.bitmap
4219 FUNCTION
4220 This method is currently not used and reserved.
4222 INPUTS
4223 obj -
4224 pixFmt -
4225 width -
4227 RESULT
4229 NOTES
4231 EXAMPLE
4233 BUGS
4235 SEE ALSO
4237 INTERNALS
4239 *****************************************************************************************/
4241 ULONG BM__Hidd_BitMap__BytesPerLine(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_BytesPerLine *msg)
4243 #ifdef __RESERVED__
4244 ULONG bpl;
4246 switch (msg->pixFmt)
4248 case vHidd_StdPixFmt_Native32:
4249 bpl = sizeof (HIDDT_Pixel) * msg->width;
4250 break;
4252 case vHidd_StdPixFmt_Native:
4254 struct HIDDBitMapData *data;
4256 data = OOP_INST_DATA(cl, o);
4258 bpl = ((HIDDT_PixelFormat *)data->prot.pixfmt)->bytes_per_pixel * msg->width;
4259 break;
4262 default:
4264 OOP_Object *pf;
4265 struct HIDDBitMapData *data;
4267 data = OOP_INST_DATA(cl, o);
4269 pf = HIDD_Gfx_GetPixFmt(data->gfxhidd, msg->pixFmt);
4271 if (NULL == pf)
4273 D(bug("!!! COULD NOT GET STD PIXFMT IN BitMap::BytesPerLine() !!!\n"));
4274 return 0;
4277 bpl = ((HIDDT_PixelFormat *)pf)->bytes_per_pixel * msg->width;
4278 break;
4282 return bpl;
4283 #else
4284 return 0;
4285 #endif
4289 /****************************************************************************************/
4292 This makes it easier to create a subclass of the graphics hidd.
4293 It is only allowed to use this method in the p_RootNew method of a
4294 bitmap subclass.
4297 /****************************************************************************************/
4299 IPTR BM__Root__Set(OOP_Class *cl, OOP_Object *obj, struct pRoot_Set *msg)
4301 struct Library *UtilityBase = CSD(cl)->cs_UtilityBase;
4302 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
4303 struct HIDDBitMapData *data = OOP_INST_DATA(cl, obj);
4305 if (data->framebuffer)
4308 * If this is a framebuffer, we can process ModeID change.
4309 * We do it before parsing the rest of tags, because here we retrieve
4310 * defaults for new bitmap parameters (size and pixelformat).
4311 * They can be overriden by other tags. For example we can imagine
4312 * a hardware scrollable framebuffer whose width and height are larger
4313 * than visible part.
4315 HIDDT_ModeID modeid = GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
4316 OOP_Object *sync, *pixfmt;
4318 if (HIDD_Gfx_GetMode(data->gfxhidd, modeid, &sync, &pixfmt))
4320 data->modeid = modeid;
4322 * Set defaults based on the ModeID.
4323 * They can be overriden lated, in SetBitMapTags.
4325 data->width = OOP_GET(sync, aHidd_Sync_HDisp);
4326 data->height = OOP_GET(sync, aHidd_Sync_VDisp);
4327 data->bytesPerRow = GetBytesPerRow(data, CSD(cl));
4328 data->prot.pixfmt = pixfmt;
4330 else
4332 /* Bad ModeID given, request rejected */
4333 return FALSE;
4336 /* Process the rest of tags. */
4337 BM__Hidd_BitMap__SetBitMapTags(cl, obj, msg->attrList);
4339 /* There's no superclass above us */
4340 return TRUE;
4343 /*****************************************************************************************
4345 NAME
4346 moHidd_BitMap_SetColorMap
4348 SYNOPSIS
4349 OOP_Object * OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetColorMap *msg);
4351 OOP_Object * HIDD_BM_SetColorMap(OOP_Object *obj, OOP_Object *colorMap);
4353 LOCATION
4354 hidd.graphics.bitmap
4356 FUNCTION
4358 INPUTS
4359 obj -
4360 colorMap -
4362 RESULT
4364 NOTES
4366 EXAMPLE
4368 BUGS
4370 SEE ALSO
4372 INTERNALS
4374 *****************************************************************************************/
4376 OOP_Object *BM__Hidd_BitMap__SetColorMap(OOP_Class *cl, OOP_Object *o,
4377 struct pHidd_BitMap_SetColorMap *msg)
4379 struct HIDDBitMapData *data;
4380 OOP_Object *old;
4382 data = OOP_INST_DATA(cl, o);
4384 old = data->colmap;
4385 data->colmap = msg->colorMap;
4387 return old;
4390 /*****************************************************************************************
4392 NAME
4393 moHidd_BitMap_MapColor
4395 SYNOPSIS
4396 HIDDT_Pixel OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_MapColor *msg);
4398 HIDDT_Pixel HIDD_BM_MapColor(OOP_Object *obj, HIDDT_Color *color);
4400 LOCATION
4401 hidd.graphics.bitmap
4403 FUNCTION
4405 INPUTS
4406 obj -
4407 color -
4409 RESULT
4411 NOTES
4413 EXAMPLE
4415 BUGS
4417 SEE ALSO
4419 INTERNALS
4421 *****************************************************************************************/
4423 /* We only care about magnitudes here, so we don't
4424 * have to perform the square root operation to get
4425 * the real distance.
4427 static ULONG colorDistance(HIDDT_Color *a, HIDDT_Color *b)
4429 #define SQR(x) ((x) * (x))
4430 return SQR((int)a->red - (int)b->red) +
4431 SQR((int)a->blue - (int)b->blue) +
4432 SQR((int)a->green - (int)b->green) +
4433 SQR((int)a->alpha - (int)b->alpha);
4434 #undef SQR
4437 HIDDT_Pixel BM__Hidd_BitMap__MapColor(OOP_Class *cl, OOP_Object *o,
4438 struct pHidd_BitMap_MapColor *msg)
4440 HIDDT_PixelFormat *pf = BM_PIXFMT(o);
4442 HIDDT_Pixel red = msg->color->red;
4443 HIDDT_Pixel green = msg->color->green;
4444 HIDDT_Pixel blue = msg->color->blue;
4445 HIDDT_Pixel alpha = msg->color->alpha;
4447 /* This code assumes that sizeof(HIDDT_Pixel) is a multiple of sizeof(col->#?),
4448 which should be true for most (all?) systems. I have never heard
4449 of any system with for example 3 byte types.
4452 if (IS_TRUECOLOR(pf))
4454 if (HIDD_PF_SWAPPIXELBYTES(pf))
4456 /* FIXME: BM__Hidd_BitMap__MapColor assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats */
4458 HIDDT_Pixel pixel = MAP_RGBA(red, green, blue, alpha, pf);
4460 msg->color->pixval = SWAPBYTES_WORD(pixel);
4462 else
4464 msg->color->pixval = MAP_RGBA(red, green, blue, alpha, pf);
4467 else
4469 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
4470 HIDDT_Color *ctab;
4471 HIDDT_ColorLUT *cmap;
4472 UWORD i;
4473 ULONG best_ndx = ~0, best_dist = ~0;
4475 cmap = (HIDDT_ColorLUT *)data->colmap;
4476 ctab = cmap->colors;
4477 /* Search for the best match in the color table */
4478 for (i = 0; i < cmap->entries; i++) {
4479 ULONG dist;
4481 dist = colorDistance(&ctab[i], msg->color);
4482 if (dist < best_dist) {
4483 best_dist = dist;
4484 best_ndx = i;
4488 if (best_dist != ~0)
4489 msg->color->pixval = ctab[best_ndx].pixval;
4492 return msg->color->pixval;
4495 /*****************************************************************************************
4497 NAME
4498 moHidd_BitMap_UnmapPixel
4500 SYNOPSIS
4501 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_UnmapPixel *msg);
4503 VOID HIDD_BM_UnmapPixel(OOP_Object *obj, HIDDT_Pixel pixel, HIDDT_Color *color);
4505 LOCATION
4506 hidd.graphics.bitmap
4508 FUNCTION
4510 INPUTS
4511 obj -
4512 pixel -
4513 color -
4515 RESULT
4517 NOTES
4519 EXAMPLE
4521 BUGS
4523 SEE ALSO
4525 INTERNALS
4527 *****************************************************************************************/
4529 VOID BM__Hidd_BitMap__UnmapPixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_UnmapPixel *msg)
4532 HIDDT_PixelFormat *pf = BM_PIXFMT(o);
4534 if (IS_TRUECOLOR(pf))
4536 HIDDT_Pixel pixel = msg->pixel;
4538 if (HIDD_PF_SWAPPIXELBYTES(pf))
4540 /* FIXME: bitmap_unmappixel assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats */
4541 pixel = SWAPBYTES_WORD(pixel);
4544 msg->color->red = RED_COMP (pixel, pf);
4545 msg->color->green = GREEN_COMP (pixel, pf);
4546 msg->color->blue = BLUE_COMP (pixel, pf);
4547 msg->color->alpha = ALPHA_COMP (pixel, pf);
4549 else
4551 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
4552 HIDDT_ColorLUT *clut;
4554 clut = (HIDDT_ColorLUT *)data->colmap;
4558 /* FIXME: Use CLUT shift and CLUT mask here */
4559 if (msg->pixel < 0 || msg->pixel >= clut->entries)
4560 return;
4562 *msg->color = clut->colors[msg->pixel];
4566 /* Unnecessary, but... */
4567 msg->color->pixval = msg->pixel;
4570 /*****************************************************************************************
4572 NAME
4573 moHidd_BitMap_ObtainDirectAccess
4575 SYNOPSIS
4576 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_ObtainDirectAccess *msg);
4578 BOOL HIDD_BM_ObtainDirectAccess(OOP_Object *obj, UBYTE **addressReturn,
4579 ULONG *widthReturn, ULONG *heightReturn,
4580 ULONG *bankSizeReturn, ULONG *memSizeReturn);
4582 LOCATION
4583 hidd.graphics.bitmap
4585 FUNCTION
4587 INPUTS
4588 obj -
4589 addressReturn -
4590 widthReturn -
4591 heightReturn -
4592 bankSizeReturn -
4593 memSizeReturn -
4595 RESULT
4596 BOOL
4598 NOTES
4600 EXAMPLE
4602 BUGS
4604 SEE ALSO
4606 INTERNALS
4608 *****************************************************************************************/
4610 BOOL BM__Hidd_BitMap__ObtainDirectAccess(OOP_Class *cl, OOP_Object *o,
4611 struct pHidd_BitMap_ObtainDirectAccess *msg)
4613 /* Default implementation of direct access funcs. Just return FALSE */
4614 return FALSE;
4617 /*****************************************************************************************
4619 NAME
4620 moHidd_BitMap_ReleaseDirectAccess
4622 SYNOPSIS
4623 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_ReleaseDirectAccess *msg);
4625 VOID HIDD_BM_ReleaseDirectAccess(OOP_Object *obj);
4627 LOCATION
4628 hidd.graphics.bitmap
4630 FUNCTION
4632 INPUTS
4633 obj -
4635 RESULT
4637 NOTES
4639 EXAMPLE
4641 BUGS
4643 SEE ALSO
4645 INTERNALS
4647 *****************************************************************************************/
4649 VOID BM__Hidd_BitMap__ReleaseDirectAccess(OOP_Class *cl, OOP_Object *o,
4650 struct pHidd_BitMap_ReleaseDirectAccess *msg)
4652 D(bug("!!! BitMap BaseClasse ReleaseDirectAccess() called !!!\n"));
4653 D(bug("!!! This should never happen and is probably due to a buggy implementation in the subclass !!!\n"));
4655 return;
4658 /*****************************************************************************************
4660 NAME
4661 moHidd_BitMap_BitMapScale
4663 SYNOPSIS
4664 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BitMapScale * msg);
4666 VOID HIDD_BM_BitMapScale(OOP_Object *obj, OOP_Object *src, OOP_Object *dest,
4667 struct BitScaleArgs * bsa, OOP_Object *gc);
4669 LOCATION
4670 hidd.graphics.bitmap
4672 FUNCTION
4674 INPUTS
4675 obj -
4676 src -
4677 dest -
4678 bsa -
4679 gc -
4681 RESULT
4683 NOTES
4685 EXAMPLE
4687 BUGS
4689 SEE ALSO
4691 INTERNALS
4693 *****************************************************************************************/
4695 VOID BM__Hidd_BitMap__BitMapScale(OOP_Class * cl, OOP_Object *o,
4696 struct pHidd_BitMap_BitMapScale * msg)
4698 struct BitScaleArgs *bsa = msg->bsa;
4699 ULONG *srcbuf, *dstbuf;
4700 WORD srcline = -1;
4701 UWORD *linepattern;
4702 UWORD count;
4703 UWORD ys = bsa->bsa_SrcY;
4704 UWORD xs = bsa->bsa_SrcX;
4705 UWORD dyd = bsa->bsa_DestHeight;
4706 UWORD dxd = bsa->bsa_DestWidth;
4707 LONG accuys = dyd;
4708 LONG accuxs = dxd;
4709 UWORD dxs = bsa->bsa_SrcWidth;
4710 UWORD dys = bsa->bsa_SrcHeight;
4711 LONG accuyd = - (dys >> 1);
4712 LONG accuxd = - (dxs >> 1);
4713 UWORD x;
4715 if ((srcbuf = AllocVec(bsa->bsa_SrcWidth * sizeof(ULONG), 0)) == NULL)
4716 return;
4718 if ((dstbuf = AllocVec(bsa->bsa_DestWidth * sizeof(ULONG), 0)) == NULL) {
4719 FreeVec(srcbuf);
4720 return;
4723 if ((linepattern = (UWORD *) AllocVec(bsa->bsa_DestWidth * sizeof(UWORD), 0)) == NULL) {
4724 FreeVec(dstbuf);
4725 FreeVec(srcbuf);
4726 return;
4729 count = 0;
4730 while (count < bsa->bsa_DestWidth) {
4731 accuxd += dxs;
4732 while (accuxd > accuxs) {
4733 xs++;
4734 accuxs += dxd;
4737 linepattern[count] = xs;
4739 count++;
4742 count = bsa->bsa_DestY;
4743 while (count < bsa->bsa_DestHeight + bsa->bsa_DestY) {
4744 accuyd += dys;
4745 while (accuyd > accuys) {
4746 ys++;
4747 accuys += dyd;
4750 if (srcline != ys) {
4751 HIDD_BM_GetImage(msg->src, (UBYTE *) srcbuf, bsa->bsa_SrcWidth * sizeof(ULONG), bsa->bsa_SrcX, bsa->bsa_SrcY + ys, bsa->bsa_SrcWidth, 1, vHidd_StdPixFmt_Native32);
4752 srcline = ys;
4754 for (x = 0; x < bsa->bsa_DestWidth; x++)
4755 dstbuf[x] = srcbuf[linepattern[x]];
4758 HIDD_BM_PutImage(msg->dst, msg->gc, (UBYTE *) dstbuf, bsa->bsa_DestWidth * sizeof(ULONG), bsa->bsa_DestX, count, bsa->bsa_DestWidth, 1, vHidd_StdPixFmt_Native32);
4760 count++;
4763 FreeVec(linepattern);
4765 FreeVec(dstbuf);
4766 FreeVec(srcbuf);
4769 /*****************************************************************************************
4771 NAME
4772 moHidd_BitMap_SetRGBConversionFunction
4774 SYNOPSIS
4775 HIDDT_RGBConversionFunction
4776 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetRGBConversionFunction *msg);
4778 HIDDT_RGBConversionFunction
4779 HIDD_BM_SetRGBConversionFunction(OOP_Object *obj, HIDDT_StdPixFmt srcPixFmt,
4780 HIDDT_StdPixFmt dstPixFmt,
4781 HIDDT_RGBConversionFunction function);
4783 LOCATION
4784 hidd.graphics.bitmap
4786 FUNCTION
4788 INPUTS
4790 RESULT
4792 NOTES
4794 EXAMPLE
4796 BUGS
4798 SEE ALSO
4800 INTERNALS
4802 *****************************************************************************************/
4804 HIDDT_RGBConversionFunction BM__Hidd_BitMap__SetRGBConversionFunction(OOP_Class * cl, OOP_Object *o,
4805 struct pHidd_BitMap_SetRGBConversionFunction * msg)
4807 HIDDT_RGBConversionFunction old;
4809 if ((msg->srcPixFmt < FIRST_RGB_STDPIXFMT) ||
4810 (msg->dstPixFmt < FIRST_RGB_STDPIXFMT) ||
4811 (msg->srcPixFmt > LAST_RGB_STDPIXFMT) ||
4812 (msg->dstPixFmt > LAST_RGB_STDPIXFMT))
4814 return (HIDDT_RGBConversionFunction)-1;
4816 else
4818 ObtainSemaphore(&CSD(cl)->rgbconvertfuncs_sem);
4819 old = CSD(cl)->rgbconvertfuncs[msg->srcPixFmt - FIRST_RGB_STDPIXFMT][msg->dstPixFmt - FIRST_RGB_STDPIXFMT];
4820 CSD(cl)->rgbconvertfuncs[msg->srcPixFmt - FIRST_RGB_STDPIXFMT][msg->dstPixFmt - FIRST_RGB_STDPIXFMT] = msg->function;
4821 ReleaseSemaphore(&CSD(cl)->rgbconvertfuncs_sem);
4823 return old;
4827 /*****************************************************************************************
4829 NAME
4830 moHidd_BitMap_UpdateRect
4832 SYNOPSIS
4833 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_UpdateRect *msg);
4835 VOID HIDD_BM_UpdateRect(OOP_Object *obj, WORD x, WORD y, WORD width, WORD height);
4837 LOCATION
4838 hidd.graphics.bitmap
4840 FUNCTION
4841 Update displayed image of the given rectangle.
4843 Some drivers (like VGA and VESA) may work not with VRAM directly, but with a mirrored
4844 copy of it. Usually it is done in case if VRAM reading is slow. This method is called
4845 by the system after it completes any drawing operation, in order to make sure that
4846 changes made are visible on the actual screen. If your driver uses mirroring, this method
4847 should copy the given rectangle (at least) from the mirror buffer to the actual VRAM.
4849 This method is also called after changing currently visible bitmap (after moHidd_Gfx_Show
4850 method call) in order to allow the mirroring driver to refresh the screen after current bitmap
4851 changed. Note that moHidd_Gfx_ShowViewPorts is very different and moHidd_BitMap_UpdateRect
4852 will not be called if it succeeded!
4854 INPUTS
4855 obj - an object whose image to refresh
4856 x, y - A top-left edge of the rectangle to refresh
4857 width - Width of the rectangle to refresh
4858 height - Height of the rectangle to refresh
4860 RESULT
4861 None.
4863 NOTES
4864 This method is called also on offscreen bitmaps. You should track visible state of your bitmap
4865 and ignore these calls if it's not currently visible on the screen.
4867 EXAMPLE
4869 BUGS
4871 SEE ALSO
4873 INTERNALS
4875 *****************************************************************************************/
4877 VOID BM__Hidd_BitMap__UpdateRect(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_UpdateRect *msg) {
4878 /* baseclass version does nothing */
4879 return;
4882 /****************************************************************************************/
4885 * Private methods follow.
4886 * They are implemented as non-virtual, for speed up.
4889 /* This is a private form of Set method. Doesn't need a standard message. */
4890 void BM__Hidd_BitMap__SetBitMapTags(OOP_Class *cl, OOP_Object *o, struct TagItem *bitMapTags)
4892 struct Library *UtilityBase = CSD(cl)->cs_UtilityBase;
4893 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
4894 struct TagItem *tag;
4896 while ((tag = NextTagItem(&bitMapTags)))
4898 ULONG idx;
4900 if (IS_BITMAP_ATTR(tag->ti_Tag, idx))
4902 switch (idx)
4904 case aoHidd_BitMap_Width:
4905 data->width = tag->ti_Data;
4906 break;
4908 case aoHidd_BitMap_Height:
4909 data->height = tag->ti_Data;
4910 break;
4912 case aoHidd_BitMap_BytesPerRow:
4913 data->bytesPerRow = tag->ti_Data;
4914 break;
4921 * Updates bitmap's pixelformat.
4922 * Used from within planarbm subclass, and would be extremely dangerous to expose
4923 * as setable aHidd_BitMap_PixFmt, so implemented as a separate method.
4925 void BM__Hidd_BitMap__SetPixFmt(OOP_Class *cl, OOP_Object *o, OOP_Object *pf)
4927 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
4929 /* Already a pixfmt registered? */
4930 if (data->pf_registered)
4931 GFX__Hidd_Gfx__ReleasePixFmt(CSD(cl)->gfxhiddclass, data->prot.pixfmt);
4933 /* Remember the new pixelformat */
4934 data->prot.pixfmt = pf;
4937 * This pixelformat was obtained using GFX__Hidd_Gfx__RegisterPixFmt().
4938 * It increases number of pixfmt users, so we'll need to release it when
4939 * not used any more.
4941 data->pf_registered = TRUE;