rename the directory
[AROS.git] / rom / hidds / graphics / BM_Class.c
blob27651b541c5db4ecd5d3ed620000189d2d27db2c
1 /*
2 Copyright © 1995-2015, 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)
14 #define DUPDATE(x)
16 #include <aros/debug.h>
17 #include <proto/exec.h>
18 #include <proto/utility.h>
19 #include <proto/oop.h>
20 #include <exec/memory.h>
21 #include <utility/tagitem.h>
22 #include <oop/oop.h>
23 #include <oop/static_mid.h>
24 #include <graphics/text.h>
25 #include <graphics/scale.h>
26 #include <hidd/graphics.h>
28 #include <string.h>
29 #include <stdlib.h>
32 #include "graphics_intern.h"
34 /****************************************************************************************/
36 #define POINT_OUTSIDE_CLIP(gc, x, y) \
37 ( (x) < GC_CLIPX1(gc) \
38 || (x) > GC_CLIPX2(gc) \
39 || (y) < GC_CLIPY1(gc) \
40 || (y) > GC_CLIPY2(gc) )
42 /*****************************************************************************************
44 NAME
45 --background_bitmap--
47 LOCATION
48 hidd.graphics.bitmap
50 NOTES
51 Every display driver should implement at least one bitmap class for displayable
52 bitmaps.
54 Normally this class doesn't need to have public ID. In order to use it the driver
55 should pass class pointer as aoHidd_BitMap_ClassPtr value to the graphics base class
56 in its moHidd_Gfx_CreateObject implementation.
58 BitMap base class is in C++ terminology a pure virtual
59 baseclass. It will not allocate any bitmap data at all;
60 that is up to the subclass to do.
62 The main task of the BitMap baseclass is to store some information about the bitmap
63 like its size and pixelformat. A pixelformat is an object of private class which
64 stores the actual information about the format.
66 There are two ways that we can find out the pixfmt in our moHidd_Gfx_CreateObject
67 implementation:
69 Displayable bitmap -
70 The tags will contain a modeid.
71 One can use this modeid to get a pointer to an
72 already registered pixfmt.
74 Non-displayable bitmap -
75 The aoHidd_BitMap_StdPixFmt or aoHidd_BitMap_Friend attribute will always be
76 passed.
78 *****************************************************************************************/
80 #define PIXBUFBYTES 16384
82 static BOOL DoBufferedOperation(OOP_Class *cl, OOP_Object *o, UWORD startx, UWORD starty, UWORD width, UWORD height,
83 BOOL getimage, HIDDT_StdPixFmt stdpf, VOID_FUNC operation, void *userdata)
85 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
86 ULONG bytesperline = width * sizeof(ULONG);
87 UWORD buflines = PIXBUFBYTES / 4; /* Remove slow division */
88 ULONG bufsize;
89 UWORD endy = starty + height;
90 UWORD y;
91 UBYTE *buf;
93 if (buflines == 0)
94 buflines = 1;
95 else if (buflines > height)
96 buflines = height;
98 bufsize = buflines * bytesperline;
99 buf = AllocMem(bufsize, MEMF_PUBLIC);
100 if (!buf && (buflines > 1))
102 /* Try to allocate single-line buffer */
103 buflines = 1;
104 bufsize = bytesperline;
105 buf = AllocMem(bufsize, MEMF_PUBLIC);
107 if (!buf)
108 return FALSE;
110 for (y = starty; y < endy; y += buflines)
112 if (y + buflines > endy)
114 /* This prevents overflow on last pass, buffer may be used only partially */
115 buflines = endy - y;
118 if (getimage)
120 /* For some operations this can be optimized away */
121 HIDD_BM_GetImage(o, buf, bytesperline, startx, y, width, buflines, stdpf);
124 operation(buf, y, width, buflines, userdata);
126 HIDD_BM_PutImage(o, data->gc, buf, bytesperline, startx, y, width, buflines, stdpf);
129 FreeMem(buf, bufsize);
130 return TRUE;
133 /*****************************************************************************************
135 NAME
136 aoHidd_BitMap_Width
138 SYNOPSIS
139 [ISG], UWORD
141 LOCATION
142 hidd.graphics.bitmap
144 FUNCTION
145 Specifies bitmap width in pixels.
147 Setting this attribute does not cause actual bitmap resize, just updates the information
148 about it. Use this only from within subclasses only if you know what you do. For example
149 SDL hosted driver sets it when framebufer changes the resolution.
151 NOTES
153 EXAMPLE
155 BUGS
157 SEE ALSO
158 aoHidd_BitMap_Height
160 INTERNALS
162 *****************************************************************************************/
164 /*****************************************************************************************
166 NAME
167 aoHidd_BitMap_Height
169 SYNOPSIS
170 [ISG], UWORD
172 LOCATION
173 hidd.graphics.bitmap
175 FUNCTION
176 Specifies bitmap height in pixels.
178 Setting this attribute does not cause actual bitmap resize, just updates the information
179 about it. Use this only from within subclasses only if you know what you do. For example
180 SDL hosted driver sets it when framebufer changes the resolution.
182 NOTES
184 EXAMPLE
186 BUGS
188 SEE ALSO
189 aoHidd_BitMap_Width
191 INTERNALS
193 *****************************************************************************************/
195 /*****************************************************************************************
197 NAME
198 aoHidd_BitMap_Displayable
200 SYNOPSIS
201 [I.G], BOOL
203 LOCATION
204 hidd.graphics.bitmap
206 FUNCTION
207 The bitmap is displayable. A displayable bitmap is always managed by a display
208 driver and must have valid display mode ID specification.
210 If this attribute is not supplied during bitmap creation, its value defaults
211 to FALSE.
213 NOTES
215 EXAMPLE
217 BUGS
219 SEE ALSO
220 aoHidd_BitMap_ModeID
222 INTERNALS
224 *****************************************************************************************/
226 /*****************************************************************************************
228 NAME
229 aoHidd_BitMap_Visible
231 SYNOPSIS
232 [..G], BOOL
234 LOCATION
235 hidd.graphics.bitmap
237 FUNCTION
238 Check if the bitmap is currently visible on screen
240 NOTES
242 EXAMPLE
244 BUGS
245 Not all display drivers implement this attribute. No AROS components currently rely
246 on its value.
248 SEE ALSO
250 INTERNALS
251 Some drivers may choose to have this attribute internally setable. Do not rely on it
252 in any way and do not attempt to set it manually from within applications, this will
253 not do any nice things.
255 *****************************************************************************************/
257 /*****************************************************************************************
259 NAME
260 aoHidd_BitMap_IsLinearMem
262 SYNOPSIS
263 [..G], BOOL
265 LOCATION
266 hidd.graphics.bitmap
268 FUNCTION
269 Check if the bitmap provides linear memory access. This means that bitmap's
270 pixelbuffer is directly addressable by the CPU.
272 Bitmaps with no linear memory may implement moHidd_BitMap_ObtainDirectAccess,
273 but this means that this method will rely on mirrored buffer. In such a case
274 the user must call moHidd_BitMap_UpdateRect after modifying bitmap's contents.
276 NOTES
277 Used by cybergraphics.library/GetCyberMapAttr() for providing CYBRMATTR_ISLINEARMEM
278 value.
280 EXAMPLE
282 BUGS
283 Currently no display drivers implement this attribute despite many native mode
284 drivers actually provide linear memory.
286 SEE ALSO
287 moHidd_BitMap_ObtainDirectAccess, moHidd_BitMap_ReleaseDirectAccess,
288 moHidd_BitMap_UpdateRect
290 INTERNALS
292 *****************************************************************************************/
294 /*****************************************************************************************
296 NAME
297 aoHidd_BitMap_BytesPerRow
299 SYNOPSIS
300 [ISG], ULONG
302 LOCATION
303 hidd.graphics.bitmap
305 FUNCTION
306 Specify or query number of bytes per row in the bitmap storage buffer.
308 Setting this attribute doesn't actually cause changing buffer layout, just updates
309 the information about it. Use this only from within subclasses and only if you
310 exactly know why you do this.
312 Specifying this attribute during object creation overrides the value calculated
313 based on aoHidd_BitMap_Width and aoHidd_BitMap_Align values. Useful for wrapping
314 own buffers into bitmap objects, for example, in conjunction with
315 aoHidd_ChunkyBM_Buffer.
317 NOTES
318 The returned value includes possible padding needed for alignment.
320 EXAMPLE
322 BUGS
324 SEE ALSO
325 aoHidd_BitMap_Align
327 INTERNALS
329 *****************************************************************************************/
331 /*****************************************************************************************
333 NAME
334 aoHidd_BitMap_ColorMap
336 SYNOPSIS
337 [..G], OOP_Object *
339 LOCATION
340 hidd.graphics.bitmap
342 FUNCTION
343 Return associated colormap (palette) object.
345 By default only displayable bitmaps have colormaps. However a colormap can be attached
346 to any bitmap using moHidd_BitMap_SetColors or moHidd_BitMap_SetColorMap.
348 Note that manual attaching of a colormap to a nondisplayable bitmap may cause undesired
349 side-effects on graphics.library behavior. It's better not to do this at all. The system
350 knows what it does better than you.
352 NOTES
354 EXAMPLE
356 BUGS
358 SEE ALSO
359 moHidd_BitMap_SetColorMap, moHidd_BitMap_SetColors.
361 INTERNALS
363 *****************************************************************************************/
365 /*****************************************************************************************
367 NAME
368 aoHidd_BitMap_Friend
370 SYNOPSIS
371 [I.G], OOP_Object *
373 LOCATION
374 hidd.graphics.bitmap
376 FUNCTION
377 Specify a friend bitmap. The bitmap will be allocated so that it
378 is optimized for blitting to this bitmap.
380 Display drivers may query this attribute and then query friend bitmap
381 for anything they want (like pixelformat, mode ID, etc).
383 Note that explicit specification of mode ID and/or standard pixelformat
384 should override defaults provided by friend bitmap (i.e. actually breaking
385 the friendship).
387 NOTES
389 EXAMPLE
391 BUGS
393 SEE ALSO
395 INTERNALS
397 *****************************************************************************************/
399 /*****************************************************************************************
401 NAME
402 aoHidd_BitMap_GfxHidd
404 SYNOPSIS
405 [I.G], OOP_Object *
407 LOCATION
408 hidd.graphics.bitmap
410 FUNCTION
411 Specify display driver object this bitmap was created with.
413 Normally the user doesn't have to supply this attribute. Instead you should use
414 driver's moHidd_Gfx_CreateObject method in order to create bitmaps. In this case
415 aoHidd_BitMap_GfxHidd attribute will be provided by graphics driver base class
416 with the correct value.
418 It is illegal to manually create bitmap objects with no driver associated.
419 graphics.library maintains at least a memory driver for nondisplayable
420 bitmaps in system RAM without any acceleration.
422 NOTES
424 EXAMPLE
426 BUGS
428 SEE ALSO
429 CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
431 INTERNALS
433 *****************************************************************************************/
435 /*****************************************************************************************
437 NAME
438 aoHidd_BitMap_StdPixFmt
440 SYNOPSIS
441 [I..], HIDDT_StdPixFmt
443 LOCATION
444 hidd.graphics.bitmap
446 FUNCTION
447 Specify standard pixelformat code (one of vHidd_StdPixFmt_... values) for the
448 bitmap.
450 Values less than num_Hidd_PseudoStdPixFmt are illegal for this attribute.
452 The bitmap class itself ignores this attribute. It is processed by
453 CLID_Hidd_Gfx/moHidd_Gfx_CreateObject method in order to look up a corresponding
454 pixelformat object in the system's database.
456 NOTES
457 Bitmaps with this attribute set should be created as RAM bitmaps with direct CPU
458 access. It is not recommended to replace them with, for example, virtual surfaces on
459 hosted AROS. Such bitmaps are expected to be directly addressable and breaking
460 this may cause undesired side effects.
462 EXAMPLE
464 BUGS
466 SEE ALSO
467 aoHidd_BitMap_PixFmt, CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
469 INTERNALS
470 Currently all display drivers omit specifying own bitmap class for bitmaps with this
471 attribute set, letting base class (actually memory driver) to select an appropriate
472 class for it. This way it ends up in a bitmap of CLID_Hidd_ChunkyBM or CLID_Hidd_PlanarBM
473 class. It is recommended to follow this rule. It's not prohibited, however, to do some
474 adjustments to the bitmap (like alignment) in order to optimize blitting to/from it.
475 In fact if the display driver was asked to create such a bitmap, this means that
476 the standard bitmap is being created as a friend of some bitmap which was allocated
477 using this driver. This way the bitmap is expected to be friendly to this driver.
479 *****************************************************************************************/
481 /*****************************************************************************************
483 NAME
484 aoHidd_BitMap_PixFmt
486 SYNOPSIS
487 [I.G], OOP_Object *
489 LOCATION
490 hidd.graphics.bitmap
492 FUNCTION
493 Specify or query pixelformat descriptor object associated with the bitmap.
495 Every bitmap has some associated pixelformat object. Pixelformat objects are
496 shared data storages, so many bitmaps may refer to the same pixelformat objects.
498 NOTES
499 This attribute is internally specified during bitmap creation, but it's illegal
500 to do this for the user. CreateObject method of graphics driver performs an explicit
501 check against this. It's up to graphics base classes to figure out its value.
503 EXAMPLE
505 BUGS
507 SEE ALSO
509 INTERNALS
511 *****************************************************************************************/
513 /*****************************************************************************************
515 NAME
516 aoHidd_BitMap_ModeID
518 SYNOPSIS
519 [ISG], HIDDT_ModeID
521 LOCATION
522 hidd.graphics.bitmap
524 FUNCTION
525 Specify display mode ID for displayable bitmap.
527 A displayable bitmap must have this attribute supplied with valid value. A nondisplayable
528 one may miss it, however it may remember it if it was created as a friend of displayable
529 one. This way you may create another displayable bitmap as a friend of nondisplayable
530 one which in turn is a friend of displayable one.
532 This attribute can be set on a framebuffer bitmap. Doing so means an explicit request
533 for the driver to change current display mode on the hardware. Dependent parameters
534 (width, height and pixelformat) will be automatically adjusted, if not explicitly
535 specified in the attributes list.
537 NOTES
538 If the given ModeID is not supported, the operation causes an error. You can check
539 for this by checking return value of OOP_SetAttrs() function. It will be TRUE in
540 case of success and FALSE upon failure. In case of failure none of bitmap attributes
541 will be changed.
543 EXAMPLE
545 BUGS
547 SEE ALSO
549 INTERNALS
551 *****************************************************************************************/
553 /*****************************************************************************************
555 NAME
556 aoHidd_BitMap_ClassPtr
558 SYNOPSIS
559 [I..], OOP_Class *
561 LOCATION
562 hidd.graphics.bitmap
564 FUNCTION
565 Explicitly specify bitmap's class pointer.
567 This attribute is not actually a bitmap's attribute. Your display driver class can
568 supply it to base class' moHidd_Gfx_CreateObject method in order to select a class on
569 which to call OOP_NewObject().
571 If neither this attribute nor aoHidd_BitMap_ClassID attribute is provided for
572 moHidd_Gfx_CreateObject, graphics base class will do its best in order to find out the
573 correct class based on aoHidd_StdPixFmt attribute value or friend bitmap.
575 NOTES
576 If a friend bitmap is given, the new bitmap will have the same class, if your driver
577 doesn't override it by supplying explicit class specification (using either
578 aoHidd_BitMap_ClassPtr or aoHidd_BitMap_ClassID attribute).
580 EXAMPLE
582 BUGS
584 SEE ALSO
585 aoHidd_BitMap_ClassID, CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
587 INTERNALS
589 *****************************************************************************************/
591 /*****************************************************************************************
593 NAME
594 aoHidd_BitMap_ClassID
596 SYNOPSIS
597 [I..]
599 LOCATION
600 hidd.graphics.bitmap
602 FUNCTION
603 Explicitly specify bitmap's class ID.
605 The purpose of this attribute is to let graphics driver base class to select a class
606 on which to call OOP_NewObject() in its moHidd_Gfx_CreateObject implementation.
608 If neither this attribute nor aoHidd_BitMap_ClassPtr attribute is provided for
609 moHidd_Gfx_CreateObject, graphics base class will do its best in order to find out the
610 correct class based on aoHidd_StdPixFmt attribute value or aoHidd_BitMap_ClassPtr value
611 of friend bitmap.
613 NOTES
615 EXAMPLE
617 BUGS
618 The pointer to a given class will not be remembered as aoHidd_BitMap_ClassPtr value.
620 SEE ALSO
621 aoHidd_BitMap_ClassPtr, CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
623 INTERNALS
625 *****************************************************************************************/
627 /*****************************************************************************************
629 NAME
630 aoHidd_BitMap_PixFmtTags
632 SYNOPSIS
633 [...]
635 LOCATION
636 hidd.graphics.bitmap
638 FUNCTION
639 Private, very obsolete and currently has no function. Considered reserved.
641 NOTES
643 EXAMPLE
645 BUGS
647 SEE ALSO
649 INTERNALS
651 *****************************************************************************************/
653 /*****************************************************************************************
655 NAME
656 aoHidd_BitMap_FrameBuffer
658 SYNOPSIS
659 [I.G], BOOL
661 LOCATION
662 hidd.graphics.bitmap
664 FUNCTION
665 Specifies that the bitmap is a framebuffer bitmap.
667 A detailed description of a framebuffer is given in CLID_Hidd_Gfx/moHidd_Gfx_CreateObject
668 and in CLID_Hidd_Gfx/moHidd_Gfx_Show documentation.
670 Specifying this attribute causes also implicit setting of aoHidd_BitMap_Displayable
671 to TRUE.
673 NOTES
675 EXAMPLE
677 BUGS
679 SEE ALSO
681 INTERNALS
683 *****************************************************************************************/
685 /*****************************************************************************************
687 NAME
688 aoHidd_BitMap_LeftEdge
690 SYNOPSIS
691 [.SG]
693 LOCATION
694 hidd.graphics.bitmap
696 FUNCTION
697 Controls horizontal position of a scrollable screen bitmap.
699 Size of displayable bitmaps may differ from actual screen size. In this case the
700 bitmap can be scrolled around the whole display area. If the bitmap is larger than
701 the display, only its part can be visible.
703 Setting this attribute causes changing left origin point of the bitmap. The value
704 of this attribute represents an offset from the physical edge of the display to the
705 logical edge of the bitmap. This means that if a large bitmap scrolls to the left in
706 order to reveal its right part, the offset will be negative. If the bitmap scrolls
707 to the left (possibly revealing another bitmap behind it), the offset will be positive.
709 It's up to the display driver to set scroll limits. If the value of the attribute
710 becomes unacceptable for any reason, the driver should adjust it and provide the real
711 resulting value back.
713 NOTES
714 Implementing screen scrolling does not enforce to implement screen composition, despite
715 the composition is really based on scrolling (in case of composition scrolling a bitmap
716 off-display is expected to reveal another bitmap behind it instead of empty space).
718 EXAMPLE
720 BUGS
722 SEE ALSO
723 aoHidd_BitMap_TopEdge
725 INTERNALS
726 Base class will always provide zero value for this attribute and ignore all attempts
727 to set it. This means that by default bitmaps don't scroll and this needs explicit
728 implementation in the display driver.
730 *****************************************************************************************/
732 /*****************************************************************************************
734 NAME
735 aoHidd_BitMap_TopEdge
737 SYNOPSIS
738 [.SG]
740 LOCATION
741 hidd.graphics.bitmap
743 FUNCTION
744 Controls vertical position of a scrollable screen bitmap.
746 Size of displayable bitmaps may differ from actual screen size. In this case the
747 bitmap can be scrolled around the whole display area. If the bitmap is larger than
748 the display, only its part can be visible.
750 Setting this attribute causes changing top origin point of the bitmap. The value
751 of this attribute represents an offset from the physical edge of the display to the
752 logical edge of the bitmap. This means that if a large bitmap scrolls upwards in
753 order to reveal its bottom part, the offset will be negative. If the bitmap scrolls
754 downwards (possibly revealing another bitmap behind it), the offset will be positive.
756 It's up to the display driver to set scroll limits. If the value of the attribute
757 becomes unacceptable for any reason, the driver should adjust it and provide the real
758 resulting value back.
760 NOTES
761 Implementing screen scrolling does not enforce to implement screen composition, despite
762 the composition is really based on scrolling (in case of composition scrolling a bitmap
763 off-display is expected to reveal another bitmap behind it instead of empty space).
765 EXAMPLE
767 BUGS
769 SEE ALSO
771 INTERNALS
773 *****************************************************************************************/
775 /*****************************************************************************************
777 NAME
778 aoHidd_BitMap_Align
780 SYNOPSIS
781 [I.G]
783 LOCATION
784 hidd.graphics.bitmap
786 FUNCTION
787 Specify number of pixels to align bitmap data width to.
789 This attribute can be added in order to enforce alignment needed for example by
790 blitting hardware. It will have an impact on default aoHidd_BitMap_BytesPerRow
791 value.
793 Direct specification of aoHidd_BitMap_BytesPerRow attribute overrides any value
794 of this attribute.
796 NOTES
797 Default value of this attribute is 16. This alignment is required by graphics.library
798 for AmigaOS(tm) compatibility reasons.
800 EXAMPLE
802 BUGS
804 SEE ALSO
805 aoHidd_BitMap_BytesPerRow
807 INTERNALS
809 *****************************************************************************************/
811 /*****************************************************************************************
813 NAME
814 aoHidd_BitMap_Depth
816 SYNOPSIS
817 [G.I]
819 LOCATION
820 hidd.graphics.bitmap
822 FUNCTION
823 Specify or query the actual bitmap depth.
825 This a convenience attribute to simplify handling planar bitmaps, whose actual depth
826 may vary. Default implementation in base class simply returns depth of bitmap's
827 pixelformat, and is ignored during initialization. Planar bitmap class returns the
828 actual depth here. If your specific bitmap class also operates on bitmaps with variable
829 depths, you need to implement this attribute in it.
831 NOTES
833 EXAMPLE
835 BUGS
837 SEE ALSO
839 INTERNALS
841 *****************************************************************************************/
843 /****************************************************************************************/
845 #undef csd
848 * Calculate suggested bytes per row value based on bitmap's default alignment
849 * and pixelformat's bytes per pixel value.
851 static ULONG GetBytesPerRow(struct HIDDBitMapData *data, struct class_static_data *csd)
853 struct Library *OOPBase = csd->cs_OOPBase;
854 UWORD align = data->align - 1;
855 UWORD width = (data->width + align) & ~align;
856 IPTR bytesperpixel, stdpf;
858 OOP_GetAttr(data->prot.pixfmt, aHidd_PixFmt_BytesPerPixel, &bytesperpixel);
859 OOP_GetAttr(data->prot.pixfmt, aHidd_PixFmt_StdPixFmt, &stdpf);
861 if (stdpf == vHidd_StdPixFmt_Plane)
864 * Planar format actually have 8 pixels per one byte.
865 * However bytesperpixel == 1 for them. Perhaps this should
866 * be changed to 0 ?
868 return width >> 3;
870 else
872 return width * bytesperpixel;
876 #define csd CSD(cl)
878 OOP_Object *BM__Root__New(OOP_Class *cl, OOP_Object *obj, struct pRoot_New *msg)
880 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
881 struct Library *UtilityBase = CSD(cl)->cs_UtilityBase;
883 EnterFunc(bug("BitMap::New()\n"));
885 obj = (OOP_Object *)OOP_DoSuperMethod(cl, obj, (OOP_Msg) msg);
887 if (NULL != obj)
889 struct TagItem colmap_tags[] =
891 { aHidd_ColorMap_NumEntries , 16 },
892 { TAG_DONE }
894 struct TagItem *tag, *tstate;
895 BOOL ok = TRUE;
896 struct HIDDBitMapData *data = OOP_INST_DATA(cl, obj);
898 /* Set some default values */
899 data->modeid = vHidd_ModeID_Invalid;
900 data->align = 16;
902 data->compositable = FALSE;
904 tstate = msg->attrList;
905 while ((tag = NextTagItem(&tstate)))
907 ULONG idx;
909 if (IS_BITMAP_ATTR(tag->ti_Tag, idx))
911 switch (idx)
913 case aoHidd_BitMap_BMStruct:
914 data->bmstruct = (struct BitMap *)tag->ti_Data;
915 break;
917 case aoHidd_BitMap_Width:
918 data->width = tag->ti_Data;
919 break;
921 case aoHidd_BitMap_Height:
922 data->height = tag->ti_Data;
923 break;
925 case aoHidd_BitMap_Align:
926 data->align = tag->ti_Data;
927 break;
929 case aoHidd_BitMap_BytesPerRow:
930 data->bytesPerRow = tag->ti_Data;
931 break;
933 case aoHidd_BitMap_GfxHidd:
934 data->gfxhidd = (OOP_Object *)tag->ti_Data;
935 break;
937 case aoHidd_BitMap_Friend:
938 data->friend = (OOP_Object *)tag->ti_Data;
939 break;
941 case aoHidd_BitMap_Displayable:
942 data->displayable = tag->ti_Data;
943 break;
945 case aoHidd_BitMap_Compositable:
946 data->compositable = tag->ti_Data;
947 break;
949 case aoHidd_BitMap_FrameBuffer:
950 data->framebuffer = tag->ti_Data;
951 break;
953 case aoHidd_BitMap_ModeID:
954 data->modeid = tag->ti_Data;
955 break;
957 case aoHidd_BitMap_PixFmt:
958 data->prot.pixfmt = (OOP_Object *)tag->ti_Data;
959 break;
964 /* aoHidd_BitMap_GfxHidd is mandatory */
965 if (!data->gfxhidd)
967 D(bug("!!!! BM CLASS DID NOT GET GFX HIDD !!!\n"));
968 D(bug("!!!! The reason for this is that the gfxhidd subclass CreateObject() method\n"));
969 D(bug("!!!! has not left it to the baseclass to actually create the object,\n"));
970 D(bug("!!!! but rather done it itself. This MUST be corrected in the gfxhidd subclass\n"));
972 ok = FALSE;
975 /* FrameBuffer implies Displayable */
976 if (data->framebuffer)
977 data->displayable = TRUE;
979 if (ok && (data->displayable || data->compositable))
981 HIDDT_ModeID bmmodeid = data->modeid;
983 /* We should always get modeid, but we check anyway */
984 if ((data->compositable) && (data->friend))
986 OOP_GetAttr(data->friend, aHidd_BitMap_ModeID, &bmmodeid);
987 D(bug("!!! BitMap:New() Using Friends ModeID - 0x%08X !!!\n", bmmodeid));
990 if (bmmodeid == vHidd_ModeID_Invalid)
992 D(bug("!!! BitMap:New() NO VALID MODEID SPECIFIED FOR DISPLAYABLE BITMAP !!!\n"));
993 data->compositable = ok = FALSE;
995 else
997 OOP_Object *sync, *pf;
999 if (!HIDD_Gfx_GetMode(data->gfxhidd, bmmodeid, &sync, &pf))
1001 D(bug("!!! BitMap::New() RECEIVED INVALID MODEID 0x%08X\n", bmmodeid));
1002 data->compositable = ok = FALSE;
1004 else
1006 /* Get display size from the modeid */
1007 OOP_GetAttr(sync, aHidd_Sync_HDisp, &data->displayWidth);
1008 OOP_GetAttr(sync, aHidd_Sync_VDisp, &data->displayHeight);
1009 data->display.MaxX = data->displayWidth;
1010 data->display.MaxY = data->displayHeight;
1012 /* Update the missing bitmap data */
1013 if (!data->width)
1014 data->width = data->displayWidth;
1015 if (!data->height)
1016 data->height = data->displayHeight;
1018 D(bug("[BitMap] Bitmap %dx%d, display %dx%d\n",
1019 data->width, data->height,
1020 data->displayWidth, data->displayHeight));
1022 if (!data->prot.pixfmt)
1024 /* The PixFmt is allready registered and locked in the PixFmt database */
1025 data->prot.pixfmt = pf;
1029 } /* if (ok) */
1031 if (ok)
1033 /* * PixFmt will be NULL in case of e.g. planarbm late initialization. */
1034 if (data->prot.pixfmt)
1036 ULONG bytesPerRow = GetBytesPerRow(data, CSD(cl));
1038 if (data->bytesPerRow)
1040 /* If we have user-supplied BytesPerRow value, make sure it's suitable */
1041 if (data->bytesPerRow < bytesPerRow)
1042 ok = FALSE;
1044 else
1046 /* Otherwise we have what we calculated */
1047 data->bytesPerRow = bytesPerRow;
1052 if (ok)
1054 InitSemaphore(&data->lock);
1056 /* Cache default GC */
1057 OOP_GetAttr(data->gfxhidd, aHidd_Gfx_DefaultGC, (IPTR *)&data->gc);
1060 * Initialize the direct method calling.
1061 * We don't check against errors because our base class contains all
1062 * these functions.
1064 #if USE_FAST_PUTPIXEL
1065 data->putpixel = OOP_GetMethod(obj, HiddBitMapBase + moHidd_BitMap_PutPixel, &data->putpixel_Class);
1066 #endif
1067 #if USE_FAST_GETPIXEL
1068 data->getpixel = OOP_GetMethod(obj, HiddBitMapBase + moHidd_BitMap_GetPixel, &data->getpixel_Class);
1069 #endif
1070 #if USE_FAST_DRAWPIXEL
1071 data->drawpixel = OOP_GetMethod(obj, HiddBitMapBase + moHidd_BitMap_DrawPixel, &data->drawpixel_Class);
1072 #endif
1075 * Try to create the colormap.
1077 * stegerg: Only add a ColorMap for a visible bitmap (screen). This
1078 * is important because one can create for example a bitmap
1079 * in PIXFMT_LUT8 without friend bitmap and then copy this
1080 * bitmap to a 16 bit screen. During copy the screen bitmap
1081 * CLUT must be used, which would not happen if our PIXFMT_LUT8
1082 * also had a colormap itself because then bltbitmap would use the
1083 * colormap of the PIXFMT_LUT8 bitmap as lookup, which in this
1084 * case would just cause everything to become black in the
1085 * destination (screen) bitmap, because noone ever sets up the
1086 * colormap of the PIXFMT_LUT8 bitmap
1088 * sonic: CHECKME: Why does the colormap always have 16 colors? May be calculate this
1089 * based on depth ? The colormap auto-enlarges itself if SetColors method requests
1090 * missing entries, but is it so good?
1093 if (data->displayable)
1095 data->colmap = OOP_NewObject(NULL, CLID_Hidd_ColorMap, colmap_tags);
1096 if (NULL == data->colmap)
1097 ok = FALSE;
1102 if (!ok)
1104 ULONG dispose_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
1106 OOP_CoerceMethod(cl, obj, &dispose_mid);
1107 obj = NULL;
1109 } /* if(obj) */
1111 } /* if (NULL != obj) */
1113 ReturnPtr("BitMap::New", OOP_Object *, obj);
1116 /****************************************************************************************/
1118 void BM__Root__Dispose(OOP_Class *cl, OOP_Object *obj, OOP_Msg *msg)
1120 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
1121 struct HIDDBitMapData *data = OOP_INST_DATA(cl, obj);
1123 EnterFunc(bug("BitMap::Dispose()\n"));
1125 if (NULL != data->colmap)
1126 OOP_DisposeObject(data->colmap);
1128 D(bug("Calling super\n"));
1130 /* Release the previously registered pixel format */
1131 if (data->pf_registered)
1132 GFX__Hidd_Gfx__ReleasePixFmt(CSD(cl)->gfxhiddclass, data->prot.pixfmt);
1134 OOP_DoSuperMethod(cl, obj, (OOP_Msg) msg);
1136 ReturnVoid("BitMap::Dispose");
1139 /****************************************************************************************/
1141 VOID BM__Root__Get(OOP_Class *cl, OOP_Object *obj, struct pRoot_Get *msg)
1143 struct HIDDBitMapData *data = OOP_INST_DATA(cl, obj);
1144 ULONG idx;
1146 EnterFunc(bug("BitMap::Get() attrID: %i storage: %p\n", msg->attrID, msg->storage));
1148 if (IS_BITMAP_ATTR(msg->attrID, idx))
1150 switch(idx)
1152 case aoHidd_BitMap_BMStruct:
1153 *msg->storage = (IPTR)data->bmstruct;
1154 return;
1156 case aoHidd_BitMap_Width:
1157 *msg->storage = data->width;
1158 D(bug(" width: %i\n", data->width));
1159 return;
1161 case aoHidd_BitMap_Height:
1162 *msg->storage = data->height;
1163 return;
1165 case aoHidd_BitMap_Depth:
1167 * Generally our bitmaps have a fixed depth, which depends on pixelformat.
1168 * If this is not true for your bitmap, overload aoHidd_BitMap_Depth in your class.
1170 *msg->storage = ((HIDDT_PixelFormat *)data->prot.pixfmt)->depth;
1171 return;
1173 case aoHidd_BitMap_Displayable:
1174 *msg->storage = data->displayable;
1175 return;
1177 case aoHidd_BitMap_FrameBuffer:
1178 *msg->storage = data->framebuffer;
1179 return;
1181 case aoHidd_BitMap_PixFmt:
1182 *msg->storage = (IPTR)data->prot.pixfmt;
1183 return;
1185 case aoHidd_BitMap_Friend:
1186 *msg->storage = (IPTR)data->friend;
1187 return;
1189 case aoHidd_BitMap_ColorMap:
1190 *msg->storage = (IPTR)data->colmap;
1191 return;
1193 case aoHidd_BitMap_GfxHidd:
1194 *msg->storage = (IPTR)data->gfxhidd;
1195 return;
1197 case aoHidd_BitMap_ModeID:
1198 *msg->storage = data->modeid;
1199 return;
1201 case aoHidd_BitMap_Align:
1202 *msg->storage = data->align;
1203 return;
1205 case aoHidd_BitMap_BytesPerRow:
1206 *msg->storage = data->bytesPerRow;
1207 return;
1209 case aoHidd_BitMap_Visible:
1210 /* Framebuffer is always visible */
1211 *msg->storage = data->framebuffer ? TRUE : data->visible;
1212 return;
1214 case aoHidd_BitMap_Compositable:
1215 *msg->storage = (IPTR)data->compositable;
1216 return;
1219 * The following two are stored with inverted sign!
1220 * Verbose explanation is in Set method.
1222 case aoHidd_BitMap_LeftEdge:
1223 *msg->storage = -data->display.MinX;
1224 return;
1226 case aoHidd_BitMap_TopEdge:
1227 *msg->storage = -data->display.MinY;
1228 return;
1230 D(default: bug("UNKNOWN ATTR IN BITMAP BASECLASS: %d\n", idx);)
1234 OOP_DoSuperMethod(cl, obj, &msg->mID);
1235 ReturnVoid("BitMap::Get");
1238 /****************************************************************************************/
1240 #define UB(x) ((UBYTE *)x)
1242 /*****************************************************************************************
1244 NAME
1245 moHidd_BitMap_SetColors
1247 SYNOPSIS
1248 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetColors *msg);
1250 BOOL HIDD_BM_SetColors (OOP_Object *obj, HIDDT_Color *colors,
1251 UWORD firstColor, UWORD numColors);
1253 LOCATION
1254 hidd.graphics.bitmap
1256 FUNCTION
1257 Sets values for one or more colors in the colormap object associated with the
1258 bitmap.
1260 The colormap will be created if it does not exist.
1262 Only ARGB values from the source array are taken into account. pixval member is
1263 updated with the real pixel value for every color.
1265 INPUTS
1266 obj - A bitmap object whose colormap needs to be set
1267 colors - A pointer to source data array
1268 firstColor - Number of the first color to set
1269 numColors - Number of subsequent colors to set
1271 RESULT
1272 TRUE on success, FALSE in case of some error (like out of memory)
1274 NOTES
1276 EXAMPLE
1278 BUGS
1280 SEE ALSO
1281 CLID_Hidd_ColorMap/moHidd_ColorMap_SetColors
1283 INTERNALS
1285 *****************************************************************************************/
1287 BOOL BM__Hidd_BitMap__SetColors(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_SetColors *msg)
1289 /* Copy the colors into the internal buffer */
1290 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
1291 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
1292 BOOL ret = TRUE;
1294 /* Subclass has initialized HIDDT_Color->pixelVal field and such.
1295 Just copy it into the colortab.
1298 if (NULL == data->colmap)
1300 struct TagItem colmap_tags[] =
1302 { aHidd_ColorMap_NumEntries, 0 },
1303 { TAG_DONE }
1306 colmap_tags[0].ti_Data = msg->firstColor + msg->numColors;
1307 data->colmap = OOP_NewObject(NULL, CLID_Hidd_ColorMap, colmap_tags);
1310 if (NULL == data->colmap)
1312 return FALSE;
1315 /* Use the colormap class to set the colors */
1316 if (!HIDD_CM_SetColors(data->colmap, msg->colors,
1317 msg->firstColor, msg->numColors,
1318 data->prot.pixfmt))
1320 return FALSE;
1323 /* We may need to duplicate changes on framebuffer if running in mirrored mode */
1324 if (data->visible)
1326 ObtainSemaphoreShared(&data->lock);
1328 if (data->visible)
1330 ret = GFX__Hidd_Gfx__SetFBColors(CSD(cl)->gfxhiddclass, data->gfxhidd, msg);
1333 ReleaseSemaphore(&data->lock);
1336 return ret;
1339 /*******************************************************************************
1341 NAME
1342 moHidd_BitMap_PutPixel
1344 SYNOPSIS
1345 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutPixel *msg);
1347 VOID HIDD_BM_PutPixel(OOP_Object *obj, WORD x, WORD y,
1348 HIDDT_Pixel pixel);
1350 LOCATION
1351 hidd.graphics.bitmap
1353 FUNCTION
1354 Sets a new color value for the pixel at (x,y). The actual color stored
1355 may be an approximation, due to the limited color depth or palette size
1356 of the bitmap. This function does not check the coordinates.
1358 INPUTS
1359 obj - bitmap to write to.
1360 x, y - coordinates of the pixel to write.
1361 pixel - the pixel's new color value.
1363 RESULT
1364 None.
1366 NOTES
1368 EXAMPLE
1370 BUGS
1372 SEE ALSO
1374 INTERNALS
1376 *******************************************************************************/
1378 /* PutPixel must be implemented in a subclass */
1380 /*****************************************************************************************
1382 NAME
1383 moHidd_BitMap_DrawPixel
1385 SYNOPSIS
1386 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPixel *msg);
1388 VOID HIDD_BM_DrawPixel(OOP_Object *obj, OOP_Object *gc, WORD x, WORD y);
1390 LOCATION
1391 hidd.graphics.bitmap
1393 FUNCTION
1394 Changes the pixel at (x,y). The color of the pixel depends on the
1395 attributes of gc, eg. colors, drawmode, colormask etc.
1396 This function does not check the coordinates.
1398 INPUTS
1399 obj - A bitmap to draw on
1400 gc - A GC (graphics context) object to use for drawing
1401 x, y - Coordinates of the pixel to draw
1403 RESULT
1404 None.
1406 NOTES
1408 EXAMPLE
1410 BUGS
1412 SEE ALSO
1414 INTERNALS
1416 TODO
1417 - Support for shapeplane.
1418 - Optimize
1420 *****************************************************************************************/
1422 VOID BM__Hidd_BitMap__DrawPixel(OOP_Class *cl, OOP_Object *obj,
1423 struct pHidd_BitMap_DrawPixel *msg)
1425 HIDDT_Pixel src, dest, val;
1426 HIDDT_DrawMode mode;
1427 HIDDT_Pixel writeMask;
1428 OOP_Object *gc;
1430 /* EnterFunc(bug("BitMap::DrawPixel() x: %i, y: %i\n", msg->x, msg->y));
1433 Example: Pixels whose bits are set to 0 in the colMask must be
1434 unchanged
1436 data->colMask = 001111
1437 dest = 101100
1440 writeMask = ~data->colMask & dest
1441 = 110000 & 101100
1442 = 100000
1444 dest = data->fg && dest = 010100
1447 dest = dest & (writeMask | data->ColMask)
1448 = 010100 & (100000 | 001111)
1449 = 010100 & (101111)
1450 = 000100
1453 dest = dest | writeMask;
1454 = 000100 100000
1455 = 100100
1459 gc = msg->gc;
1461 src = GC_FG(gc);
1462 mode = GC_DRMD(gc);
1464 #if OPTIMIZE_DRAWPIXEL_FOR_COPY
1465 if (vHidd_GC_DrawMode_Copy == mode && GC_COLMASK(gc) == ~0)
1467 val = src;
1469 else
1470 #endif
1472 dest = GETPIXEL(cl, obj, msg->x, msg->y);
1473 writeMask = ~GC_COLMASK(gc) & dest;
1475 val = 0;
1477 if(mode & 1) val = ( src & dest);
1478 if(mode & 2) val = ( src & ~dest) | val;
1479 if(mode & 4) val = (~src & dest) | val;
1480 if(mode & 8) val = (~src & ~dest) | val;
1482 val = (val & (writeMask | GC_COLMASK(gc) )) | writeMask;
1486 PUTPIXEL(cl, obj, msg->x, msg->y, val);
1489 /*****************************************************************************************
1491 NAME
1492 moHidd_BitMap_DrawLine
1494 SYNOPSIS
1495 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPixel *msg);
1497 VOID HIDD_BM_DrawLine(OOP_Object *obj, OOP_Object *gc, WORD x1, WORD y1,
1498 WORD x2, WORD y2);
1500 LOCATION
1501 hidd.graphics.bitmap
1503 FUNCTION
1504 Draws a line from (x1,y1) to (x2,y2) in the specified gc.
1505 The function does not clip the line against the drawing area.
1507 INPUTS
1508 obj - A bitmap to draw on
1509 gc - A graphics context object to use
1510 x1,y1 - start point of the line in pixels
1511 x2,y2 - end point of the line in pixels
1513 RESULT
1514 None.
1516 NOTES
1518 EXAMPLE
1520 BUGS
1522 SEE ALSO
1524 INTERNALS
1525 Uses midpoint line ("Bresenham") algorithm([FOL90] 3.2.2)
1527 TODO Support for line pattern
1528 Optimize remove if t == 1 ...
1529 Implement better clipping: Should be no reason to calculate
1530 more than the part of the line that is inside the cliprect
1532 *****************************************************************************************/
1534 VOID BM__Hidd_BitMap__DrawLine
1536 OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_DrawLine *msg
1539 WORD dx, dy, incrE, incrNE, d, x, y, s1, s2, t, i;
1540 WORD x1, y1, x2, y2;
1541 UWORD maskLine; /* for line pattern */
1542 ULONG fg; /* foreground pen */
1543 APTR doclip;
1544 BOOL opaque;
1545 OOP_Object *gc;
1548 /* bug("BitMap::DrawLine()\n");
1549 */ EnterFunc(bug("BitMap::DrawLine() x1: %i, y1: %i x2: %i, y2: %i\n", msg->x1, msg->y1, msg->x2, msg->y2));
1551 gc = msg->gc;
1552 doclip = GC_DOCLIP(gc);
1553 opaque = (GC_COLEXP(gc) & vHidd_GC_ColExp_Opaque) ? TRUE : FALSE;
1554 fg = GC_FG(gc);
1556 maskLine = 1 << GC_LINEPATCNT(gc);
1558 if (doclip)
1560 /* If line is not inside cliprect, then just return */
1561 /* Normalize coords */
1562 if (msg->x1 > msg->x2)
1564 x1 = msg->x2; x2 = msg->x1;
1566 else
1568 x1 = msg->x1; x2 = msg->x2;
1571 if (msg->y1 > msg->y2)
1573 y1 = msg->y2; y2 = msg->y1;
1575 else
1577 y1 = msg->y1; y2 = msg->y2;
1580 if ( x1 > GC_CLIPX2(gc)
1581 || x2 < GC_CLIPX1(gc)
1582 || y1 > GC_CLIPY2(gc)
1583 || y2 < GC_CLIPY1(gc) )
1586 /* Line is not inside cliprect, so just return */
1587 return;
1592 x1 = msg->x1;
1593 y1 = msg->y1;
1594 x2 = msg->x2;
1595 y2 = msg->y2;
1597 if (y1 == y2)
1600 Horizontal line drawing code.
1602 y = y1;
1604 /* Don't swap coordinates if x2 < x1! Because of linepattern! */
1606 if (x1 < x2)
1608 x2++;
1609 dx = 1;
1611 else
1613 x2--;
1614 dx = -1;
1617 for(i = x1; i != x2; i += dx)
1619 /* Pixel inside ? */
1621 if (!doclip || !POINT_OUTSIDE_CLIP(gc, i, y ))
1623 if(GC_LINEPAT(gc) & maskLine)
1625 HIDD_BM_DrawPixel(obj, gc, i, y);
1627 else if (opaque)
1629 GC_FG(gc) = GC_BG(gc);
1630 HIDD_BM_DrawPixel(obj, gc, i, y);
1631 GC_FG(gc) = fg;
1635 maskLine = maskLine >> 1;
1636 if (!maskLine) maskLine = 1L << 15;
1639 else if (x1 == x2)
1642 Vertical line drawing code.
1644 x = x1;
1646 /* Don't swap coordinates if y2 < y1! Because of linepattern! */
1648 if (y1 < y2)
1650 y2++;
1651 dy = 1;
1653 else
1655 y2--;
1656 dy = -1;
1659 for(i = y1; i != y2; i += dy)
1661 /* Pixel inside ? */
1662 if (!doclip || !POINT_OUTSIDE_CLIP(gc, x, i ))
1664 if(GC_LINEPAT(gc) & maskLine)
1666 HIDD_BM_DrawPixel(obj, gc, x, i);
1668 else if (opaque)
1670 GC_FG(gc) = GC_BG(gc);
1671 HIDD_BM_DrawPixel(obj, gc, x, i);
1672 GC_FG(gc) = fg;
1676 maskLine = maskLine >> 1;
1677 if (!maskLine) maskLine = 1L << 15;
1681 else
1684 Generic line drawing code.
1686 /* Calculate slope */
1687 dx = abs(x2 - x1);
1688 dy = abs(y2 - y1);
1690 /* which direction? */
1691 if((x2 - x1) > 0) s1 = 1; else s1 = - 1;
1692 if((y2 - y1) > 0) s2 = 1; else s2 = - 1;
1694 /* change axes if dx < dy */
1695 if(dx < dy)
1697 d = dx;
1698 dx = dy;
1699 dy = d;
1700 t = 0;
1702 else
1704 t = 1;
1707 d = 2 * dy - dx; /* initial value of d */
1709 incrE = 2 * dy; /* Increment use for move to E */
1710 incrNE = 2 * (dy - dx); /* Increment use for move to NE */
1712 x = x1; y = y1;
1714 for(i = 0; i <= dx; i++)
1716 /* Pixel inside ? */
1717 if (!doclip || !POINT_OUTSIDE_CLIP(gc, x, y ))
1719 if(GC_LINEPAT(gc) & maskLine)
1721 HIDD_BM_DrawPixel(obj, gc, x, y);
1723 else if (opaque)
1725 GC_FG(gc) = GC_BG(gc);
1726 HIDD_BM_DrawPixel(obj, gc, x, y);
1727 GC_FG(gc) = fg;
1731 if(d <= 0)
1733 if(t == 1)
1735 x = x + s1;
1737 else
1739 y = y + s2;
1742 d = d + incrE;
1744 else
1746 x = x + s1;
1747 y = y + s2;
1748 d = d + incrNE;
1751 maskLine = maskLine >> 1;
1752 if (!maskLine) maskLine = 1L << 15;
1757 ReturnVoid("BitMap::DrawLine ");
1760 /*****************************************************************************************
1762 NAME
1763 moHidd_BitMap_DrawRect
1765 SYNOPSIS
1766 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawRect *msg);
1768 VOID HIDD_BM_DrawRect (OOP_Object *obj, OOP_Object *gc, WORD minX, WORD minY,
1769 WORD maxX, WORD maxY);
1771 LOCATION
1772 hidd.graphics.bitmap
1774 FUNCTION
1775 Draws a hollow rectangle. minX and minY specifies the upper
1776 left corner of the rectangle. minY and maxY specifies the lower
1777 right corner of the rectangle.
1778 The function does not clip the rectangle against the drawing area.
1780 INPUTS
1781 obj - A bitmap to draw on
1782 gc - A GC object to use for drawing
1783 minX, minY - upper left corner of the rectangle in pixels
1784 maxX, maxY - lower right corner of the rectangle in pixels
1786 RESULT
1787 None.
1789 NOTES
1790 This method is not used by the system and considered reserved.
1792 EXAMPLE
1794 BUGS
1796 SEE ALSO
1798 INTERNALS
1800 TODO
1802 *****************************************************************************************/
1804 VOID BM__Hidd_BitMap__DrawRect(OOP_Class *cl, OOP_Object *obj,
1805 struct pHidd_BitMap_DrawRect *msg)
1807 #ifdef __RESERVED__
1808 OOP_Object *gc = msg->gc;
1809 WORD addX, addY;
1811 EnterFunc(bug("BitMap::DrawRect()"));
1813 if(msg->minX == msg->maxX) addX = 0; else addX = 1;
1814 if(msg->minY == msg->maxY) addY = 0; else addY = 1;
1816 HIDD_BM_DrawLine(obj, gc, msg->minX, msg->minY , msg->maxX, msg->minY);
1817 HIDD_BM_DrawLine(obj, gc, msg->maxX, msg->minY + addY, msg->maxX, msg->maxY);
1818 HIDD_BM_DrawLine(obj, gc, msg->maxX - addX, msg->maxY, msg->minX, msg->maxY);
1819 HIDD_BM_DrawLine(obj, gc, msg->minX, msg->maxY - addY, msg->minX, msg->minY + addY);
1820 #endif
1822 ReturnVoid("BitMap::DrawRect");
1825 /*****************************************************************************************
1827 NAME
1828 moHidd_BitMap_FillRect
1830 SYNOPSIS
1831 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawRect *msg);
1833 VOID HIDD_BM_FillRect (OOP_Object *obj, OOP_Object *gc, WORD minX, WORD minY,
1834 WORD maxX, WORD maxY);
1836 LOCATION
1837 hidd.graphics.bitmap
1839 FUNCTION
1841 Draws a solid rectangle. minX and minY specifies the upper
1842 left corner of the rectangle. maxX and maxY specifies the lower
1843 right corner of the rectangle.
1844 The function does not clip the rectangle against the drawing area.
1846 INPUTS
1847 obj - A bitmap to draw on
1848 gc - A GC object to use for drawing
1849 minX, minY - upper left corner of the rectangle in pixels
1850 maxX, maxY - lower right corner of the rectangle in pixels
1852 RESULT
1853 None.
1855 NOTES
1857 EXAMPLE
1859 BUGS
1861 SEE ALSO
1863 INTERNALS
1865 TODO
1866 Fill with pattern
1868 *****************************************************************************************/
1870 VOID BM__Hidd_BitMap__FillRect(OOP_Class *cl, OOP_Object *obj,
1871 struct pHidd_BitMap_DrawRect *msg)
1873 OOP_Object *gc = msg->gc;
1874 WORD y = msg->minY;
1875 UWORD linepat;
1877 EnterFunc(bug("BitMap::FillRect()"));
1879 linepat = GC_LINEPAT(gc);
1880 GC_LINEPAT(gc) = ~0;
1882 for(; y <= msg->maxY; y++)
1884 HIDD_BM_DrawLine(obj, gc, msg->minX, y, msg->maxX, y);
1887 GC_LINEPAT(gc) = linepat;
1889 ReturnVoid("BitMap::FillRect");
1892 /*****************************************************************************************
1894 NAME
1895 moHidd_BitMap_DrawEllipse
1897 SYNOPSIS
1898 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawEllipse *msg);
1900 VOID HIDD_BM_DrawEllipse (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
1901 WORD rx, WORD ry);
1903 LOCATION
1904 hidd.graphics.bitmap
1906 FUNCTION
1907 Draws a hollow ellipse from the center point (x,y) with the radii
1908 rx and ry in the specified bitmap.
1909 The function does not clip the ellipse against the drawing area.
1911 INPUTS
1912 obj - A bitmap to draw on
1913 gc - A GC object to use for drawing
1914 x,y - Coordinates of center point in pixels
1915 rx,ry - ry and ry radius in pixels
1917 RESULT
1918 None.
1920 NOTES
1922 EXAMPLE
1924 BUGS
1925 Because of overflow the current code do not work with big
1926 values of rx and ry.
1928 SEE ALSO
1930 INTERNALS
1932 TODO
1933 Bugfix
1935 *****************************************************************************************/
1937 /* TODO: Try to opimize clipping here */
1939 VOID BM__Hidd_BitMap__DrawEllipse(OOP_Class *cl, OOP_Object *obj,
1940 struct pHidd_BitMap_DrawEllipse *msg)
1942 OOP_Object *gc = msg->gc;
1943 WORD x = msg->rx, y = 0; /* ellipse points */
1945 /* intermediate terms to speed up loop */
1946 LONG t1 = msg->rx * msg->rx, t2 = t1 << 1, t3 = t2 << 1;
1947 LONG t4 = msg->ry * msg->ry, t5 = t4 << 1, t6 = t5 << 1;
1948 LONG t7 = msg->rx * t5, t8 = t7 << 1, t9 = 0L;
1949 LONG d1 = t2 - t7 + (t4 >> 1); /* error terms */
1950 LONG d2 = (t1 >> 1) - t8 + t5;
1952 APTR doclip = GC_DOCLIP(gc);
1955 EnterFunc(bug("BitMap::DrawEllipse()"));
1957 while (d2 < 0) /* till slope = -1 */
1959 /* draw 4 points using symmetry */
1961 if (doclip)
1964 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y + y))
1965 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
1967 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y - y))
1968 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
1970 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y + y))
1971 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
1973 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y - y))
1974 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
1977 else
1979 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
1980 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
1981 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
1982 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
1985 y++; /* always move up here */
1986 t9 = t9 + t3;
1987 if (d1 < 0) /* move straight up */
1989 d1 = d1 + t9 + t2;
1990 d2 = d2 + t9;
1992 else /* move up and left */
1994 x--;
1995 t8 = t8 - t6;
1996 d1 = d1 + t9 + t2 - t8;
1997 d2 = d2 + t9 + t5 - t8;
2001 do /* rest of top right quadrant */
2003 /* draw 4 points using symmetry */
2004 #if 1
2005 if (doclip)
2008 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y + y))
2009 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
2011 if (!POINT_OUTSIDE_CLIP(gc, msg->x + x, msg->y - y))
2012 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
2014 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y + y))
2015 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
2017 if (!POINT_OUTSIDE_CLIP(gc, msg->x - x, msg->y - y))
2018 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
2021 else
2024 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
2025 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
2026 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
2027 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
2029 #else
2031 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y + y);
2032 HIDD_BM_DrawPixel(obj, gc, msg->x + x, msg->y - y);
2033 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y + y);
2034 HIDD_BM_DrawPixel(obj, gc, msg->x - x, msg->y - y);
2035 #endif
2036 x--; /* always move left here */
2037 t8 = t8 - t6;
2038 if (d2 < 0) /* move up and left */
2040 y++;
2041 t9 = t9 + t3;
2042 d2 = d2 + t9 + t5 - t8;
2044 else /* move straight left */
2046 d2 = d2 + t5 - t8;
2049 } while (x >= 0);
2052 ReturnVoid("BitMap::DrawEllipse");
2055 /*****************************************************************************************
2057 NAME
2058 moHidd_BitMap_FillEllipse
2060 SYNOPSIS
2061 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawEllipse *msg);
2063 VOID HIDD_BM_FillEllipse (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2064 WORD ry, WORD rx);
2066 LOCATION
2067 hidd.graphics.bitmap
2069 FUNCTION
2070 Draws a solid ellipse from the center point (x,y) with the radii
2071 rx and ry in the specified bitmap.
2072 The function does not clip the ellipse against the drawing area.
2074 INPUTS
2075 obj - A bitmap to draw on
2076 gc - A GC object to use for drawing
2077 x,y - Coordinates of center point in pixels
2078 rx,ry - ry and ry radius in pixels
2080 RESULT
2081 None.
2083 NOTES
2084 This method is not used by the system and considered reserved.
2086 EXAMPLE
2088 Because of overflow the current code do not work with big
2089 values of rx and ry.
2091 SEE ALSO
2093 INTERNALS
2095 TODO
2096 Bugfix
2098 *****************************************************************************************/
2100 VOID BM__Hidd_BitMap__FillEllipse(OOP_Class *cl, OOP_Object *obj,
2101 struct pHidd_BitMap_DrawEllipse *msg)
2103 #ifdef __RESERVED__
2104 OOP_Object *gc = msg->gc;
2105 WORD x = msg->rx, y = 0; /* ellipse points */
2107 /* intermediate terms to speed up loop */
2108 LONG t1 = msg->rx * msg->rx, t2 = t1 << 1, t3 = t2 << 1;
2109 LONG t4 = msg->ry * msg->ry, t5 = t4 << 1, t6 = t5 << 1;
2110 LONG t7 = msg->rx * t5, t8 = t7 << 1, t9 = 0L;
2111 LONG d1 = t2 - t7 + (t4 >> 1); /* error terms */
2112 LONG d2 = (t1 >> 1) - t8 + t5;
2114 EnterFunc(bug("BitMap::FillEllipse()"));
2116 while (d2 < 0) /* till slope = -1 */
2118 /* draw 4 points using symmetry */
2119 HIDD_BM_DrawLine(obj, gc, msg->x - x, msg->y + y, msg->x + x, msg->y + y);
2120 HIDD_BM_DrawLine(obj, gc, msg->x - x, msg->y - y, msg->x + x, msg->y - y);
2122 y++; /* always move up here */
2123 t9 = t9 + t3;
2124 if (d1 < 0) /* move straight up */
2126 d1 = d1 + t9 + t2;
2127 d2 = d2 + t9;
2129 else /* move up and left */
2131 x--;
2132 t8 = t8 - t6;
2133 d1 = d1 + t9 + t2 - t8;
2134 d2 = d2 + t9 + t5 - t8;
2138 do /* rest of top right quadrant */
2140 /* draw 4 points using symmetry */
2141 HIDD_BM_DrawLine(obj, gc, msg->x - x, msg->y + y, msg->x + x, msg->y + y);
2142 HIDD_BM_DrawLine(obj, gc, msg->x - x, msg->y - y, msg->x + x, msg->y - y);
2144 x--; /* always move left here */
2145 t8 = t8 - t6;
2146 if (d2 < 0) /* move up and left */
2148 y++;
2149 t9 = t9 + t3;
2150 d2 = d2 + t9 + t5 - t8;
2152 else /* move straight left */
2154 d2 = d2 + t5 - t8;
2157 } while (x >= 0);
2158 #endif
2160 ReturnVoid("BitMap::FillEllipse");
2163 /*****************************************************************************************
2165 NAME
2166 moHidd_BitMap_DrawPolygon
2168 SYNOPSIS
2169 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg);
2171 VOID HIDD_BM_DrawPolygon (OOP_Object *obj, OOP_Object *gc, UWORD n, WORD *coords);
2173 LOCATION
2174 hidd.graphics.bitmap
2176 FUNCTION
2177 Draws a hollow polygon from the list of coordinates in coords[].
2178 The function does not clip the polygon against the drawing area.
2180 INPUTS
2181 obj - A bitmap to draw on
2182 gc - A GC object to use for drawing
2183 n - number of coordinate pairs
2184 coords - array of n (x, y) coordinates in pixels
2186 RESULT
2187 None.
2189 NOTES
2190 This method is not used by the system and considered reserved.
2192 EXAMPLE
2194 BUGS
2196 SEE ALSO
2198 INTERNALS
2200 TODO
2202 *****************************************************************************************/
2204 VOID BM__Hidd_BitMap__DrawPolygon(OOP_Class *cl, OOP_Object *obj,
2205 struct pHidd_BitMap_DrawPolygon *msg)
2207 #ifdef __RESERVED__
2208 OOP_Object *gc = msg->gc;
2209 WORD i;
2211 EnterFunc(bug("BitMap::DrawPolygon()"));
2213 for(i = 2; i < (2 * msg->n); i = i + 2)
2215 HIDD_BM_DrawLine(obj, gc, msg->coords[i - 2], msg->coords[i - 1],
2216 msg->coords[i], msg->coords[i + 1]);
2218 #endif
2220 ReturnVoid("BitMap::DrawPolygon");
2223 /*****************************************************************************************
2225 NAME
2226 moHidd_BitMap_FillPolygon
2228 SYNOPSIS
2229 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg);
2231 VOID HIDD_BM_FillPolygon (OOP_Object *obj, OOP_Object *gc, UWORD n, WORD *coords);
2233 LOCATION
2234 hidd.graphics.bitmap
2236 FUNCTION
2237 This method was initially designed for drawing solid polygons, however it was never
2238 used and implemented. At the moment it is considered reserved, its synopsis and
2239 semantics may change in future.
2241 INPUTS
2242 obj - A bitmap to draw on
2243 gc - A GC object to use for drawing
2244 n - number of coordinate pairs
2245 coords - array of n (x, y) coordinates in pixels
2247 RESULT
2248 None
2250 NOTES
2252 EXAMPLE
2254 BUGS
2255 Never used and implemented
2257 SEE ALSO
2259 INTERNALS
2261 TODO
2263 *****************************************************************************************/
2265 VOID BM__Hidd_BitMap__FillPolygon(OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_DrawPolygon *msg)
2267 D(bug("Sorry, FillPolygon() not implemented yet in bitmap baseclass\n"));
2270 /*****************************************************************************************
2272 NAME
2273 moHidd_BitMap_DrawText
2275 SYNOPSIS
2276 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2278 VOID HIDD_BM_DrawText (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2279 STRPTR text, UWORD length);
2281 LOCATION
2282 hidd.graphics.bitmap
2284 FUNCTION
2285 Draws the first length characters of text at (x, y).
2286 The function does not clip the text against the drawing area.
2288 INPUTS
2289 obj - A bitmap to draw on
2290 gc - A GC object to use for drawing and font specification
2291 x, y - Position to start drawing in pixels. The x
2292 coordinate is relativ to the left side of the
2293 first character.
2294 The y coordinate is relative to the baseline of the font.
2295 text - Pointer to a Latin 1 string
2296 length - Number of characters to draw
2298 RESULT
2299 None.
2301 NOTES
2302 At the moment text drawing is processed entirely by graphics.library
2303 using BltTemplate(), which in turn uses moHodd_BitMap_PutTemplate.
2304 This method is considered obsolete.
2306 EXAMPLE
2308 BUGS
2309 The default implementation in the base class does not process styles,
2310 color and alpha-blended fonts.
2312 SEE ALSO
2314 INTERNALS
2316 TODO
2318 *****************************************************************************************/
2320 VOID BM__Hidd_BitMap__DrawText(OOP_Class *cl, OOP_Object *obj,
2321 struct pHidd_BitMap_DrawText *msg)
2323 #ifdef __RESERVED__
2324 OOP_Object *gc = msg->gc;
2325 struct TextFont *font = GC_FONT(gc);
2326 UBYTE *charPatternPtr = font->tf_CharData;
2327 UWORD modulo = font->tf_Modulo;
2328 ULONG charLog;
2329 UBYTE ch; /* current character to print */
2330 WORD fx, fx2, fy, fw; /* position and length of character in the */
2331 /* character bitmap */
2332 WORD xMem = msg->x; /* position in bitmap */
2333 WORD yMem = msg->y - font->tf_Baseline;
2334 WORD x, y, i;
2337 EnterFunc(bug("BitMap::DrawText()"));
2339 for(i = 0; i < msg->length; i++)
2341 ch = msg->text[i];
2343 if((ch < font->tf_LoChar) || (ch > font->tf_HiChar))
2345 ch = font->tf_HiChar - font->tf_LoChar + 1;
2347 else
2349 ch = ch - font->tf_LoChar;
2352 if(font->tf_Flags & FPF_PROPORTIONAL)
2354 xMem = xMem + ((UWORD *) font->tf_CharKern)[ch];
2357 charLog = ((ULONG *) font->tf_CharLoc)[ch];
2358 fx2 = charLog >> 16; /* x position of character pattern in character bitmap */
2359 fw = (UWORD) charLog; /* width of character pattern in character bitmap */
2361 y = yMem;
2363 for(fy = 0; fy < font->tf_YSize; fy ++)
2365 x = xMem;
2367 for(fx = fx2; fx < fw + fx2; fx++)
2369 if(*(charPatternPtr + fx / 8 + fy * modulo) & (128 >> (fx % 8)))
2371 HIDD_BM_DrawPixel(obj, msg->gc, x, y);
2373 x++;
2376 y++;
2379 if(font->tf_Flags & FPF_PROPORTIONAL)
2381 xMem = xMem + ((UWORD *) font->tf_CharSpace)[ch];
2383 else
2385 xMem = xMem + font->tf_XSize;
2388 #endif
2389 ReturnVoid("BitMap::DrawText");
2392 /*****************************************************************************************
2394 NAME
2395 moHidd_BitMap_FillText
2397 SYNOPSIS
2398 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2400 VOID HIDD_BM_FillText (OOP_Object *obj, OOP_Object *gc, WORD x, WORD y,
2401 STRPTR text, UWORD length);
2403 LOCATION
2404 hidd.graphics.bitmap
2406 FUNCTION
2407 Historically this method was designed to draw a text with background.
2408 It was never implemented.
2410 Currently this method is considered reserved. Its synopsis and semantics
2411 may change in future.
2413 INPUTS
2414 obj - A bitmap to draw on
2415 gc - A GC object to use for drawing
2416 x, y - Position to start drawing in pixels. The x
2417 coordinate is relative to the left side of the
2418 first character.
2419 The y coordinate is relative to the baseline of the font.
2420 text - Pointer to a Latin 1 string
2421 length - Number of characters to draw
2423 RESULT
2425 NOTES
2427 EXAMPLE
2429 BUGS
2431 SEE ALSO
2433 INTERNALS
2435 TODO
2437 *****************************************************************************************/
2439 VOID BM__Hidd_BitMap__FillText(OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_DrawText *msg)
2441 D(bug("Sorry, FillText() not implemented yet in bitmap baseclass\n"));
2444 /*****************************************************************************************
2446 NAME
2447 moHidd_BitMap_FillSpan
2449 SYNOPSIS
2450 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_DrawText *msg);
2452 LOCATION
2453 hidd.graphics.bitmap
2455 FUNCTION
2456 Reserved, never implemented method. The definition will change in future.
2458 INPUTS
2460 RESULT
2461 None.
2463 NOTES
2465 EXAMPLE
2467 BUGS
2469 SEE ALSO
2471 INTERNALS
2473 TODO
2475 *****************************************************************************************/
2477 VOID BM__Hidd_BitMap__FillSpan(OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_DrawText *msg)
2479 D(bug("Sorry, FillSpan() not implemented yet\n"));
2482 /*****************************************************************************************
2484 NAME
2485 moHidd_BitMap_Clear
2487 SYNOPSIS
2488 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_Clear *msg);
2490 VOID HIDD_BM_Clear (OOP_Object *obj, OOP_Object *gc);
2492 LOCATION
2493 hidd.graphics.bitmap
2495 FUNCTION
2496 Sets all pixels of the drawing area to the background color.
2498 INPUTS
2499 obj - A bitmap to clear.
2500 gc - A GC object, specifies background color value
2502 RESULT
2504 NOTES
2505 This method is not used by the system and considered reserved. However it can
2506 be useful for display driver's own needs.
2508 EXAMPLE
2510 BUGS
2511 Default implementation in the base class sets all pixels to zero color instead of
2512 the background color from GC
2514 SEE ALSO
2516 INTERNALS
2518 TODO
2520 *****************************************************************************************/
2522 VOID BM__Hidd_BitMap__Clear(OOP_Class *cl, OOP_Object *obj, struct pHidd_BitMap_Clear *msg)
2524 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
2525 WORD x, y;
2526 IPTR width, height;
2528 EnterFunc(bug("BitMap::Clear()\n"));
2530 OOP_GetAttr(obj, aHidd_BitMap_Width, &width);
2531 OOP_GetAttr(obj, aHidd_BitMap_Height, &height);
2533 for(y = 0; y < height; y++)
2535 for(x = 0; x < width; x++)
2537 HIDD_BM_PutPixel(obj, x, y, 0);
2541 ReturnVoid("BitMap::Clear");
2544 /****************************************************************************************/
2546 static LONG inline getpixfmtbpp(OOP_Class *cl, OOP_Object *o, HIDDT_StdPixFmt stdpf)
2548 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
2549 OOP_Object *pf;
2550 struct HIDDBitMapData *data;
2551 SIPTR bpp = -1;
2553 data = OOP_INST_DATA(cl, o);
2555 switch (stdpf)
2557 case vHidd_StdPixFmt_Native:
2558 OOP_GetAttr(data->prot.pixfmt, aHidd_PixFmt_BytesPerPixel, &bpp);
2559 break;
2561 case vHidd_StdPixFmt_Native32:
2562 bpp = sizeof (HIDDT_Pixel);
2563 break;
2565 default:
2566 pf = HIDD_Gfx_GetPixFmt(data->gfxhidd, stdpf);
2568 if (NULL == pf)
2570 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", stdpf));
2572 else
2574 OOP_GetAttr(pf, aHidd_PixFmt_BytesPerPixel, &bpp);
2576 break;
2579 return bpp;
2582 /*****************************************************************************************
2584 NAME
2585 moHidd_BitMap_GetImage
2587 SYNOPSIS
2588 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_GetImage *msg);
2590 VOID HIDD_BM_GetImage (OOP_Object *obj, UBYTE *pixels, ULONG modulo, WORD x, WORD y,
2591 WORD width, WORD height, HIDDT_StdPixFmt pixFmt);
2593 LOCATION
2594 hidd.graphics.bitmap
2596 FUNCTION
2598 INPUTS
2599 obj -
2600 pixels -
2601 modulo -
2602 x, y -
2603 width -
2604 height -
2605 pixFmt -
2607 RESULT
2609 NOTES
2611 EXAMPLE
2613 BUGS
2615 SEE ALSO
2617 INTERNALS
2619 *****************************************************************************************/
2621 VOID BM__Hidd_BitMap__GetImage(OOP_Class *cl, OOP_Object *o,
2622 struct pHidd_BitMap_GetImage *msg)
2624 WORD x, y;
2625 UBYTE *pixarray = (UBYTE *)msg->pixels;
2626 APTR ppixarray = &pixarray;
2627 WORD bpp;
2628 struct HIDDBitMapData *data;
2630 data = OOP_INST_DATA(cl, o);
2632 EnterFunc(bug("BitMap::GetImage(x=%d, y=%d, width=%d, height=%d)\n"
2633 , msg->x, msg->y, msg->width, msg->height));
2636 bpp = getpixfmtbpp(cl, o, msg->pixFmt);
2637 if (-1 == bpp)
2639 D(bug("!!! INVALID PIXFMT IN BitMap::GetImage(): %d !!!\n", msg->pixFmt));
2640 return;
2644 switch(msg->pixFmt)
2646 case vHidd_StdPixFmt_Native:
2647 case vHidd_StdPixFmt_Native32:
2648 for (y = 0; y < msg->height; y ++)
2650 for (x = 0; x < msg->width; x ++)
2652 register HIDDT_Pixel pix;
2654 pix = HIDD_BM_GetPixel(o, x + msg->x , y + msg->y);
2656 switch (bpp)
2658 case 1:
2659 *pixarray++ = pix;
2660 break;
2662 case 2:
2663 *((UWORD *)pixarray) = pix;
2664 pixarray += 2;
2665 break;
2667 case 3:
2668 #if AROS_BIG_ENDIAN
2669 pixarray[0] = (pix >> 16) & 0xFF;
2670 pixarray[1] = (pix >> 8) & 0xFF;
2671 pixarray[2] = pix & 0xFF;
2672 #else
2673 pixarray[0] = pix & 0xFF;
2674 pixarray[1] = (pix >> 8) & 0xFF;
2675 pixarray[2] = (pix >> 16) & 0xFF;
2676 #endif
2677 pixarray += 3;
2678 break;
2680 case 4:
2681 *(ULONG *)pixarray = pix;
2682 pixarray += 4;
2683 break;
2688 pixarray += (msg->modulo - msg->width * bpp);
2691 break;
2693 default:
2695 OOP_Object *dstpf;
2696 APTR buf, srcPixels;
2698 dstpf = HIDD_Gfx_GetPixFmt(data->gfxhidd, msg->pixFmt);
2700 buf = srcPixels = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
2701 if (buf)
2703 for(y = 0; y < msg->height; y++)
2705 HIDD_BM_GetImage(o,
2706 buf,
2708 msg->x,
2709 msg->y + y,
2710 msg->width,
2712 vHidd_StdPixFmt_Native);
2714 HIDD_BM_ConvertPixels(o,
2715 &srcPixels,
2716 (HIDDT_PixelFormat *)data->prot.pixfmt,
2718 (APTR *)ppixarray,
2719 (HIDDT_PixelFormat *)dstpf,
2720 msg->modulo,
2721 msg->width,
2723 NULL);
2726 FreeVec(buf);
2729 break;
2731 } /* switch(msg->pixFmt) */
2733 ReturnVoid("BitMap::GetImage");
2736 /*****************************************************************************************
2738 NAME
2739 moHidd_BitMap_PutImage
2741 SYNOPSIS
2742 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutImage *msg);
2744 VOID HIDD_BM_PutImage (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
2745 WORD x, WORD y, WORD width, WORD height, HIDDT_StdPixFmt pixFmt);
2747 LOCATION
2748 hidd.graphics.bitmap
2750 FUNCTION
2752 INPUTS
2753 obj -
2754 gc -
2755 pixels -
2756 modulo -
2757 x, y -
2758 width -
2759 height -
2760 pixFmt -
2762 RESULT
2764 NOTES
2766 EXAMPLE
2768 BUGS
2770 SEE ALSO
2772 INTERNALS
2774 *****************************************************************************************/
2776 VOID BM__Hidd_BitMap__PutImage(OOP_Class *cl, OOP_Object *o,
2777 struct pHidd_BitMap_PutImage *msg)
2779 WORD x, y;
2780 UBYTE *pixarray = (UBYTE *)msg->pixels;
2781 APTR ppixarray = &pixarray;
2782 ULONG old_fg;
2783 WORD bpp;
2784 struct HIDDBitMapData *data;
2785 OOP_Object *gc = msg->gc;
2787 data = OOP_INST_DATA(cl, o);
2789 EnterFunc(bug("BitMap::PutImage(x=%d, y=%d, width=%d, height=%d)\n"
2790 , msg->x, msg->y, msg->width, msg->height));
2792 if (msg->width <= 0 || msg->height <= 0)
2793 return;
2795 bpp = getpixfmtbpp(cl, o, msg->pixFmt);
2796 if (-1 == bpp)
2798 D(bug("!!! INVALID PIXFMT IN BitMap::PutImage(): %d !!!\n", msg->pixFmt));
2799 return;
2802 switch(msg->pixFmt)
2804 case vHidd_StdPixFmt_Native:
2805 case vHidd_StdPixFmt_Native32:
2807 /* Preserve old fg pen */
2808 old_fg = GC_FG(gc);
2810 for (y = 0; y < msg->height; y ++)
2812 for (x = 0; x < msg->width; x ++)
2814 register HIDDT_Pixel pix = 0;
2816 switch (bpp)
2818 case 1:
2819 pix = *((UBYTE *)pixarray);
2820 pixarray ++;
2821 break;
2823 case 2:
2824 pix = *((UWORD *)pixarray);
2825 pixarray += 2;
2826 break;
2828 case 3:
2829 #if AROS_BIG_ENDIAN
2830 pix = ((UBYTE *)pixarray)[0] << 16;
2831 pix |= ((UBYTE *)pixarray)[1] << 8;
2832 pix |= ((UBYTE *)pixarray)[2];
2833 #else
2834 pix = ((UBYTE *)pixarray)[2] << 16;
2835 pix |= ((UBYTE *)pixarray)[1] << 8;
2836 pix |= ((UBYTE *)pixarray)[0];
2837 #endif
2838 pixarray += 3;
2839 break;
2841 case 4:
2842 pix = *((ULONG *)pixarray); pixarray += 4;
2843 break;
2847 GC_FG(gc) = pix;
2849 HIDD_BM_DrawPixel(o, gc, x + msg->x , y + msg->y);
2851 pixarray += (msg->modulo - msg->width * bpp);
2854 GC_FG(gc) = old_fg;
2855 break;
2857 default:
2859 OOP_Object *srcpf;
2860 APTR buf, destPixels;
2862 srcpf = HIDD_Gfx_GetPixFmt(data->gfxhidd, msg->pixFmt);
2864 buf = destPixels = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
2865 if (buf)
2867 for(y = 0; y < msg->height; y++)
2869 HIDD_BM_ConvertPixels(o,
2870 (APTR *)ppixarray,
2871 (HIDDT_PixelFormat *)srcpf,
2872 msg->modulo,
2873 &destPixels,
2874 (HIDDT_PixelFormat *)data->prot.pixfmt,
2876 msg->width,
2878 NULL);
2880 HIDD_BM_PutImage(o,
2881 msg->gc,
2882 buf,
2884 msg->x,
2885 msg->y + y,
2886 msg->width,
2888 vHidd_StdPixFmt_Native);
2890 FreeVec(buf);
2893 break;
2895 } /* switch(msg->pixFmt) */
2897 ReturnVoid("BitMap::PutImage");
2900 /****************************************************************************************/
2902 int static inline
2903 __attribute__((always_inline, const)) do_alpha(int a, int v)
2905 int tmp = (a*v);
2906 return ((tmp<<8) + tmp + 32768)>>16;
2909 #if AROS_BIG_ENDIAN
2911 #define RGB32_DECOMPOSE(red, green, blue, pix) \
2912 red = ((pix) & 0x00FF0000) >> 16; \
2913 green = ((pix) & 0x0000FF00) >> 8; \
2914 blue = ((pix) & 0x000000FF);
2916 #define ARGB32_ALPHA(pix) ((pix) & 0xFF000000)
2918 #define ARGB32_DECOMPOSE(alpha, red, green, blue, pix) \
2919 alpha = ((pix) & 0xFF000000) >> 24; \
2920 red = ((pix) & 0x00FF0000) >> 16; \
2921 green = ((pix) & 0x0000FF00) >> 8; \
2922 blue = ((pix) & 0x000000FF);
2924 #define ARGB32_COMPOSE(red, green, blue, old) (((old) & 0xFF000000) + ((red) << 16) + ((green) << 8) + (blue))
2926 #else
2928 #define RGB32_DECOMPOSE(red, green, blue, pix) \
2929 red = (pix & 0x0000FF00) >> 8; \
2930 green = (pix & 0x00FF0000) >> 16; \
2931 blue = (pix & 0xFF000000) >> 24
2933 #define ARGB32_ALPHA(pix) ((pix) & 0x000000FF)
2935 #define ARGB32_DECOMPOSE(alpha, red, green, blue, pix) \
2936 alpha = (pix & 0x000000FF); \
2937 red = (pix & 0x0000FF00) >> 8; \
2938 green = (pix & 0x00FF0000) >> 16; \
2939 blue = (pix & 0xFF000000) >> 24
2941 #define ARGB32_COMPOSE(red, green, blue, old) (((blue) << 24) + ((green) << 16) + ((red) << 8) + ((old) & 0x000000FF))
2943 #endif
2945 /*****************************************************************************************
2947 NAME
2948 moHidd_BitMap_PutAlphaImage
2950 SYNOPSIS
2951 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutAlphaImage *msg);
2953 VOID HIDD_BM_PutAlphaImage (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
2954 WORD x, WORD y, WORD width, WORD height);
2956 LOCATION
2957 hidd.graphics.bitmap
2959 FUNCTION
2960 Perform an alpha-blending operation between a bitmap and ARGB pixel array.
2962 INPUTS
2963 obj - A bitmap to operate on
2964 gc - A GC object, internally needed to perform the operation. All its attributes
2965 are ignored.
2966 pixels - A pointer to an array of pixels
2967 modulo - Number of bytes per row in pixel array
2968 x, y - Top-left corner of affected bitmap's region
2969 width - Width of the modified rectangle.
2970 height - Height of the modified rectangle.
2972 RESULT
2973 None.
2975 NOTES
2976 Do not rely on 'gc' parameter being valid when implementing this method in own
2977 display driver. This parameter is actually obsolete, and will be set to NULL in
2978 future AROS versions. Current base class implementation ignores it.
2980 EXAMPLE
2982 BUGS
2984 SEE ALSO
2986 INTERNALS
2988 *****************************************************************************************/
2990 struct paib_data
2992 void *pixels;
2993 ULONG modulo;
2997 * TODOs:
2998 * 1. Merge buffered and slow versions of PutAlphaImage(), use the same processing algorithm
2999 * (convert array's pixels to bitmap's format, not vice versa)
3000 * 2. Make DoBufferedOperation() public, to be used for cybergraphics.library/ProcessPixelArray()
3001 * implementation, and for some other functions in graphics.library and cybergraphics.library,
3002 * currently using own implementation of pixel buffer.
3003 * 3. Reuse the new code for other buffered operations (currently using old macros).
3006 static void PutAlphaImageBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct paib_data *data)
3008 UWORD x, y;
3010 for (y = 0; y < height; y++)
3012 ULONG *pixarray = data->pixels;
3014 for (x = 0; x < width; x++)
3016 ULONG destpix;
3017 ULONG srcpix;
3018 ULONG src_red, src_green, src_blue, src_alpha;
3019 ULONG dst_red, dst_green, dst_blue;
3021 srcpix = *pixarray++;
3023 if (ARGB32_ALPHA(srcpix) == ARGB32_ALPHA(0xFFFFFFFF))
3025 xbuf[x] = srcpix;
3027 else if (ARGB32_ALPHA(srcpix) != 0)
3029 ARGB32_DECOMPOSE(src_alpha, src_red, src_green, src_blue, srcpix);
3031 destpix = xbuf[x];
3032 RGB32_DECOMPOSE(dst_red, dst_green, dst_blue, destpix);
3034 dst_red += do_alpha(src_alpha, src_red - dst_red);
3035 dst_green += do_alpha(src_alpha, src_green - dst_green);
3036 dst_blue += do_alpha(src_alpha, src_blue - dst_blue);
3038 xbuf[x] = ARGB32_COMPOSE(dst_red, dst_green, dst_blue, destpix);
3042 xbuf += width;
3043 data->pixels += data->modulo;
3047 VOID BM__Hidd_BitMap__PutAlphaImage(OOP_Class *cl, OOP_Object *o,
3048 struct pHidd_BitMap_PutAlphaImage *msg)
3050 WORD x, y;
3051 struct paib_data data = {msg->pixels, msg->modulo};
3053 EnterFunc(bug("BitMap::PutAlphaImage(x=%d, y=%d, width=%d, height=%d)\n"
3054 , msg->x, msg->y, msg->width, msg->height));
3056 if (msg->width <= 0 || msg->height <= 0)
3057 return;
3059 if (!DoBufferedOperation(cl, o, msg->x, msg->y, msg->width, msg->height, TRUE, vHidd_StdPixFmt_ARGB32,
3060 (VOID_FUNC)PutAlphaImageBuffered, &data))
3062 /* Buffered method failed, use slow pixel-by-pixel method */
3063 for (y = msg->y; y < msg->y + msg->height; y++)
3065 ULONG *pixarray = data.pixels;
3067 for (x = msg->x; x < msg->x + msg->width; x++)
3069 HIDDT_Pixel destpix;
3070 HIDDT_Color col;
3071 ULONG srcpix;
3072 LONG src_red, src_green, src_blue, src_alpha;
3073 LONG dst_red, dst_green, dst_blue;
3075 destpix = HIDD_BM_GetPixel(o, x, y);
3076 HIDD_BM_UnmapPixel(o, destpix, &col);
3078 srcpix = *pixarray++;
3079 ARGB32_DECOMPOSE(src_alpha, src_red, src_green, src_blue, srcpix);
3081 dst_red = col.red >> 8;
3082 dst_green = col.green >> 8;
3083 dst_blue = col.blue >> 8;
3085 dst_red += do_alpha(src_alpha, src_red - dst_red);
3086 dst_green += do_alpha(src_alpha, src_green - dst_green);
3087 dst_blue += do_alpha(src_alpha, src_blue - dst_blue);
3089 col.red = dst_red << 8;
3090 col.green = dst_green << 8;
3091 col.blue = dst_blue << 8;
3093 HIDD_BM_PutPixel(o, x, y, HIDD_BM_MapColor(o, &col));
3095 } /* for(x = msg->x; x < msg->x + msg->width; x++) */
3097 data.pixels += msg->modulo;
3099 } /* for(y = msg->y; y < msg->y + msg->height; y++) */
3101 ReturnVoid("BitMap::PutAlphaImage");
3104 /*****************************************************************************************
3106 NAME
3107 moHidd_BitMap_PutTemplate
3109 SYNOPSIS
3110 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutTemplate *msg);
3112 VOID HIDD_BM_PutTemplate (OOP_Object *obj, OOP_Object *gc, UBYTE *masktemplate, ULONG modulo,
3113 WORD srcx, WORD x, WORD y, WORD width, WORD height, BOOL inverttemplate);
3115 LOCATION
3116 hidd.graphics.bitmap
3118 FUNCTION
3119 Apply a single-bit mask to the given portion of the bitmap. Pixels set to 1 in the mask will be filled
3120 by foreground color. Pixels set to 0 in the mask will be filled by background color or left unchanged,
3121 according to the following GC attributes:
3122 Foreground - a foreground color
3123 Background - a background color
3124 DrawMode - if set to Invert, foreground and background colors will be ignored. Instead,
3125 pixels which are set to 1 in the mask, will be inverted. Other pixels will be
3126 left unchanged.
3127 ColorExpansion - if set to Transparent, only pixels which are set to 1 in the mask, will be modified.
3128 Other pixels will not be changed (background color will be ignored).
3130 INPUTS
3131 obj - A bitmap to draw on
3132 gc - A GC object, holding operation parameters
3133 masktemplate - A pointer to a bit mask
3134 modulo - Number of bytes per line in the mask
3135 srcx - Horizontal offset of the mask
3136 x, y - Top-left corner of the bitmap's region to affect
3137 width - Width of the affected region
3138 height - Height of the affected region
3139 inverttemplate - If set to TRUE, bit mask will be interpreted in inverted form
3141 RESULT
3142 None
3144 NOTES
3146 EXAMPLE
3148 BUGS
3150 SEE ALSO
3152 INTERNALS
3154 *****************************************************************************************/
3156 struct ptb_data
3158 void *bitarray;
3159 ULONG bitmask;
3160 ULONG modulo;
3161 ULONG fg;
3162 ULONG bg;
3163 UWORD invert;
3166 static void JAM1TemplateBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ptb_data *data)
3168 UWORD x, y;
3170 for (y = 0; y < height; y++)
3172 ULONG mask = data->bitmask;
3173 UWORD *array = data->bitarray;
3174 UWORD bitword = AROS_BE2WORD(*array);
3176 for (x = 0; x < width; x++)
3178 if ((bitword & mask) == (data->invert & mask))
3179 xbuf[x] = data->fg;
3181 mask >>= 1;
3182 if (!mask)
3184 mask = 0x8000;
3185 array++;
3186 bitword = AROS_BE2WORD(*array);
3190 xbuf += width;
3191 data->bitarray += data->modulo;
3195 static void ComplementTemplateBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ptb_data *data)
3197 UWORD x, y;
3199 for (y = 0; y < height; y++)
3201 ULONG mask = data->bitmask;
3202 UWORD *array = data->bitarray;
3203 UWORD bitword = AROS_BE2WORD(*array);
3205 for (x = 0; x < width; x++)
3207 if ((bitword & mask) == (data->invert & mask))
3208 xbuf[x] = ~xbuf[x];
3210 mask >>= 1;
3211 if (!mask)
3213 mask = 0x8000;
3214 array++;
3215 bitword = AROS_BE2WORD(*array);
3219 xbuf += width;
3220 data->bitarray += data->modulo;
3224 static void JAM2TemplateBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ptb_data *data)
3226 UWORD x, y;
3228 for (y = 0; y < height; y++)
3230 ULONG mask = data->bitmask;
3231 UWORD *array = data->bitarray;
3232 UWORD bitword = AROS_BE2WORD(*array);
3234 for (x = 0; x < width; x++)
3236 if ((bitword & mask) == (data->invert & mask))
3237 xbuf[x] = data->fg;
3238 else
3239 xbuf[x] = data->bg;
3241 mask >>= 1;
3242 if (!mask)
3244 mask = 0x8000;
3245 array++;
3246 bitword = AROS_BE2WORD(*array);
3250 xbuf += width;
3251 data->bitarray += data->modulo;
3255 VOID BM__Hidd_BitMap__PutTemplate(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_PutTemplate *msg)
3257 OOP_Object *gc = msg->gc;
3258 BOOL get = TRUE;
3259 void (*op)(ULONG *, UWORD, UWORD, UWORD, struct ptb_data *);
3260 struct ptb_data data;
3262 EnterFunc(bug("BitMap::PutTemplate(x=%d, y=%d, width=%d, height=%d)\n"
3263 , msg->x, msg->y, msg->width, msg->height));
3265 if (msg->width <= 0 || msg->height <= 0)
3266 return;
3268 if (GC_COLEXP(gc) == vHidd_GC_ColExp_Transparent)
3270 op = JAM1TemplateBuffered;
3272 else if (GC_DRMD(gc) == vHidd_GC_DrawMode_Invert)
3274 op = ComplementTemplateBuffered;
3276 else
3278 op = JAM2TemplateBuffered;
3279 get = FALSE;
3282 data.bitarray = msg->masktemplate + ((msg->srcx / 16) * 2);
3283 data.bitmask = 0x8000 >> (msg->srcx & 0xF);
3284 data.modulo = msg->modulo;
3285 data.fg = GC_FG(msg->gc);
3286 data.bg = GC_BG(msg->gc);
3287 data.invert = msg->inverttemplate ? 0 : 0xFFFF;
3289 DoBufferedOperation(cl, o, msg->x, msg->y, msg->width, msg->height, get, vHidd_StdPixFmt_Native32, (VOID_FUNC)op, &data);
3291 /* TODO: write fallback */
3293 ReturnVoid("BitMap::PutTemplate");
3296 /*****************************************************************************************
3298 NAME
3299 moHidd_BitMap_PutAlphaTemplate
3301 SYNOPSIS
3302 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutAlphaTemplate *msg);
3304 VOID HIDD_BM_PutAlphaTemplate (OOP_Object *obj, OOP_Object *gc, UBYTE *alpha, ULONG modulo,
3305 WORD x, WORD y, WORD width, WORD height, BOOL invertalpha);
3307 LOCATION
3308 hidd.graphics.bitmap
3310 FUNCTION
3311 Perform a drawing with current foreground color, using 8-bit alpha channel mask. The following
3312 GC attributes are considered:
3313 Foreground - a foreground color
3314 Background - a background color
3315 DrawMode - if set to Invert, foreground and background colors will be ignored. Instead,
3316 pixels, for which alpha channel value is greater than 127, will be inverted.
3317 Other pixels will be left unchanged.
3318 ColorExpansion - if set to Opaque, alpha blending will happen between foreground and background
3319 colors, instead of between foreground color and old bitmap contents.
3321 INPUTS
3322 obj - A bitmap to draw on
3323 gc - A GC object specifying drawing parameters
3324 alpha - A pointer to an 8-bit per pixel alpha channel mask
3325 modulo - Number of bytes per line in the mask
3326 x, y - Top-left corner of the affected bitmap's region
3327 width - Width of the affected bitmap's region
3328 height - Height of the affected bitmap's region
3329 invertalpha - If set to TRUE, alpha mask values will be treated in inverted form
3331 RESULT
3332 None
3334 NOTES
3336 EXAMPLE
3338 BUGS
3340 SEE ALSO
3342 INTERNALS
3344 *****************************************************************************************/
3346 struct patb_data
3348 UBYTE *pixarray;
3349 ULONG modulo;
3350 LONG a_red, a_green, a_blue;
3351 LONG b_red, b_green, b_blue;
3352 UBYTE invert;
3355 static void JAM1AlphaTemplateBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct patb_data *data)
3357 UWORD x, y;
3359 for (y = 0; y < height; y++)
3361 UBYTE *pixarray = data->pixarray;
3363 for (x = 0; x < width; x++)
3365 LONG dst_red, dst_green, dst_blue, alpha;
3367 alpha = (*pixarray++) ^ data->invert;
3368 RGB32_DECOMPOSE(dst_red, dst_green, dst_blue, xbuf[x]);
3370 dst_red += do_alpha(alpha, data->a_red - dst_red);
3371 dst_green += do_alpha(alpha, data->a_green - dst_green);
3372 dst_blue += do_alpha(alpha, data->a_blue - dst_blue);
3374 xbuf[x] = ARGB32_COMPOSE(dst_red, dst_green, dst_blue, 0);
3377 xbuf += width;
3378 data->pixarray += data->modulo;
3382 static void ComplementAlphaTemplateBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct patb_data *data)
3384 UWORD x, y;
3386 for (y = 0; y < height; y++)
3388 UBYTE *pixarray = data->pixarray;
3390 for (x = 0; x < width; x++)
3392 UBYTE alpha = (*pixarray++) ^ data->invert;
3394 if (alpha >= 0x80)
3395 xbuf[x] = ~xbuf[x];
3398 xbuf += width;
3399 data->pixarray += data->modulo;
3403 static void JAM2AlphaTemplateBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct patb_data *data)
3405 UWORD x, y;
3407 for (y = 0; y < height; y++)
3409 UBYTE *pixarray = data->pixarray;
3411 for (x = 0; x < width; x++)
3413 LONG dst_red, dst_green, dst_blue, alpha;
3415 alpha = (*pixarray++) ^ data->invert;
3417 dst_red = data->b_red + ((data->a_red - data->b_red) * alpha) / 256;
3418 dst_green = data->b_green + ((data->a_green - data->b_green) * alpha) / 256;
3419 dst_blue = data->b_blue + ((data->a_blue - data->b_blue) * alpha) / 256;
3421 xbuf[x] = ARGB32_COMPOSE(dst_red, dst_green, dst_blue, 0);
3424 xbuf += width;
3425 data->pixarray += data->modulo;
3429 VOID BM__Hidd_BitMap__PutAlphaTemplate(OOP_Class *cl, OOP_Object *o,
3430 struct pHidd_BitMap_PutAlphaTemplate *msg)
3432 OOP_Object *gc = msg->gc;
3433 BOOL get = TRUE;
3434 void (*op)(ULONG *, UWORD, UWORD, UWORD, struct patb_data *);
3435 struct patb_data data;
3436 HIDDT_Color color;
3438 EnterFunc(bug("BitMap::PutAlphaTemplate(x=%d, y=%d, width=%d, height=%d)\n"
3439 , msg->x, msg->y, msg->width, msg->height));
3441 if (msg->width <= 0 || msg->height <= 0)
3442 return;
3444 HIDD_BM_UnmapPixel(o, GC_FG(gc), &color);
3445 data.a_red = color.red >> 8;
3446 data.a_green = color.green >> 8;
3447 data.a_blue = color.blue >> 8;
3449 if (GC_COLEXP(gc) == vHidd_GC_ColExp_Transparent)
3451 op = JAM1AlphaTemplateBuffered;
3453 else if (GC_DRMD(gc) == vHidd_GC_DrawMode_Invert)
3455 op = ComplementAlphaTemplateBuffered;
3457 else
3459 op = JAM2AlphaTemplateBuffered;
3460 get = FALSE;
3462 HIDD_BM_UnmapPixel(o, GC_BG(gc), &color);
3463 data.b_red = color.red >> 8;
3464 data.b_green = color.green >> 8;
3465 data.b_blue = color.blue >> 8;
3468 data.pixarray = msg->alpha;
3469 data.modulo = msg->modulo;
3470 data.invert = msg->invertalpha ? 255 : 0;
3472 DoBufferedOperation(cl, o, msg->x, msg->y, msg->width, msg->height, get, vHidd_StdPixFmt_ARGB32, (VOID_FUNC)op, &data);
3474 /* TODO: write fallback */
3476 ReturnVoid("BitMap::PutAlphaTemplate");
3479 /*****************************************************************************************
3481 NAME
3482 moHidd_BitMap_PutPattern
3484 SYNOPSIS
3485 VOID OOP_DoMethod(OOP_Object *o, struct pHidd_BitMap_PutPattern *msg);
3487 VOID HIDD_BM_PutPattern(OOP_Object *obj, OOP_Object *gc, UBYTE *pattern,
3488 WORD patternsrcx, WORD patternsrcy, WORD patternheight, WORD patterndepth,
3489 HIDDT_PixelLUT *patternlut, BOOL invertpattern, UBYTE *mask,
3490 ULONG maskmodulo, WORD masksrcx, WORD x, WORD y,
3491 WORD width, WORD height);
3493 LOCATION
3494 hidd.graphics.bitmap
3496 FUNCTION
3498 INPUTS
3499 obj - A bitmap to draw on
3500 gc - A GC object to use for drawing
3501 pattern -
3502 patternsrcx -
3503 patternsrcy -
3504 patternheight -
3505 patterndepth -
3506 patternlut -
3507 invertpattern -
3508 mask -
3509 maskmodulo -
3510 masksrcx -
3511 x, y -
3512 width -
3513 height -
3515 RESULT
3516 None
3518 NOTES
3520 EXAMPLE
3522 BUGS
3524 SEE ALSO
3526 INTERNALS
3528 *****************************************************************************************/
3530 struct ppb_data
3532 UWORD *patarray;
3533 void *maskarray;
3534 ULONG *patternlut;
3535 UWORD patternsrcy;
3536 UWORD desty;
3537 UWORD patternheight;
3538 ULONG maskmodulo;
3539 ULONG fg;
3540 ULONG bg;
3541 UWORD patmask;
3542 UWORD maskmask;
3543 UWORD patterndepth;
3544 UWORD invert;
3547 static void JAM1PatternBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ppb_data *data)
3549 UWORD x, y;
3551 for (y = 0; y < height; y++)
3553 UWORD pmask = data->patmask;
3554 UWORD mmask = data->maskmask;
3555 UWORD *parray = data->patarray + ((y + starty + data->patternsrcy - data->desty) % data->patternheight);
3556 UWORD patword = AROS_BE2WORD(*parray);
3557 UWORD *marray = data->maskarray;
3558 UWORD maskword = marray ? AROS_BE2WORD(*marray) : 0xFFFF;
3560 for (x = 0; x < width; x++)
3562 if (maskword & mmask)
3564 if ((patword & pmask) == (data->invert & pmask))
3565 xbuf[x] = data->fg;
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 ComplementPatternBuffered(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 if ((patword & pmask) == (data->invert & pmask))
3610 xbuf[x] = ~xbuf[x];
3613 if (marray)
3615 mmask >>= 1;
3616 if (!mmask)
3618 mmask = 0x8000;
3619 marray++;
3620 maskword = AROS_BE2WORD(*marray);
3624 pmask >>= 1;
3625 if (!pmask)
3626 pmask = 0x8000;
3628 } /* for (x) */
3630 xbuf += width;
3631 if (data->maskarray)
3632 data->maskarray += data->maskmodulo;
3634 } /* for (y) */
3637 static void JAM2PatternBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ppb_data *data)
3639 UWORD x, y;
3641 for (y = 0; y < height; y++)
3643 UWORD pmask = data->patmask;
3644 UWORD mmask = data->maskmask;
3645 UWORD *parray = data->patarray + ((y + starty + data->patternsrcy - data->desty) % data->patternheight);
3646 UWORD patword = AROS_BE2WORD(*parray);
3647 UWORD *marray = data->maskarray;
3648 UWORD maskword = marray ? AROS_BE2WORD(*marray) : 0xFFFF;
3650 for (x = 0; x < width; x++)
3652 if (maskword & mmask)
3654 if ((patword & pmask) == (data->invert & pmask))
3655 xbuf[x] = data->fg;
3656 else
3657 xbuf[x] = data->bg;
3660 if (marray)
3662 mmask >>= 1;
3663 if (!mmask)
3665 mmask = 0x8000;
3666 marray++;
3667 maskword = AROS_BE2WORD(*marray);
3671 pmask >>= 1;
3672 if (!pmask)
3673 pmask = 0x8000;
3675 } /* for (x) */
3677 xbuf += width;
3678 if (data->maskarray)
3679 data->maskarray += data->maskmodulo;
3681 } /* for (y) */
3684 static void ColorPatternBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ppb_data *data)
3686 UWORD x, y;
3688 for (y = 0; y < height; y++)
3690 UWORD pmask = data->patmask;
3691 UWORD mmask = data->maskmask;
3692 UWORD *parray = data->patarray + ((y + starty + data->patternsrcy - data->desty) % data->patternheight);
3693 UWORD patword = AROS_BE2WORD(*parray);
3694 UWORD *marray = data->maskarray;
3695 UWORD maskword = marray ? AROS_BE2WORD(*marray) : 0xFFFF;
3697 for (x = 0; x < width; x++)
3699 if (maskword & mmask)
3701 UWORD plane;
3702 ULONG pixel = (patword & pmask) ? 1 : 0; /* CHECKME: Shouldn't we handle INVERSVID here too ? */
3704 for (plane = 1; plane < data->patterndepth; plane++)
3706 UWORD *_parray = parray + plane * data->patternheight;
3707 UWORD _patword = AROS_BE2WORD(*_parray);
3709 if (_patword & pmask)
3710 pixel |= 1L << plane;
3713 if (data->patternlut)
3714 pixel = data->patternlut[pixel];
3716 xbuf[x] = pixel;
3719 if (marray)
3721 mmask >>= 1;
3722 if (!mmask)
3724 mmask = 0x8000;
3725 marray++;
3726 maskword = AROS_BE2WORD(*marray);
3730 pmask >>= 1;
3731 if (!pmask)
3732 pmask = 0x8000;
3734 } /* for (x) */
3736 xbuf += width;
3737 if (data->maskarray)
3738 data->maskarray += data->maskmodulo;
3740 } /* for (y) */
3743 VOID BM__Hidd_BitMap__PutPattern(OOP_Class *cl, OOP_Object *o,
3744 struct pHidd_BitMap_PutPattern *msg)
3746 void (*op)(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ppb_data *data);
3747 BOOL get = TRUE;
3748 struct ppb_data data;
3750 DPUTPATTERN(bug("BitMap::PutPattern(x=%d, y=%d, width=%d, height=%d)\n",
3751 msg->x, msg->y, msg->width, msg->height));
3753 if (msg->width <= 0 || msg->height <= 0)
3754 return;
3756 if (msg->patterndepth > 1)
3758 DPUTPATTERN(bug("[PutPattern] Color\n"));
3759 op = ColorPatternBuffered;
3760 get = FALSE;
3762 else if (GC_COLEXP(msg->gc) == vHidd_GC_ColExp_Transparent)
3764 DPUTPATTERN(bug("[PutPattern] JAM1\n"));
3765 op = JAM1PatternBuffered;
3767 else if (GC_DRMD(msg->gc) == vHidd_GC_DrawMode_Invert)
3769 DPUTPATTERN(bug("[PutPattern] Complement\n"));
3770 op = ComplementPatternBuffered;
3772 else
3774 DPUTPATTERN(bug("[PutPattern] JAM2\n"));
3775 op = JAM2PatternBuffered;
3776 get = FALSE;
3779 data.patarray = (UWORD *)msg->pattern;
3780 data.patmask = 0x8000 >> (msg->patternsrcx & 0xF);
3781 data.maskarray = msg->mask;
3782 data.patternlut = msg->patternlut ? msg->patternlut->pixels : NULL;
3783 data.patternsrcy = msg->patternsrcy;
3784 data.desty = msg->y;
3785 data.patternheight = msg->patternheight;
3786 data.patterndepth = msg->patterndepth;
3787 data.maskmodulo = msg->maskmodulo;
3788 data.fg = GC_FG(msg->gc);
3789 data.bg = GC_BG(msg->gc);
3790 data.invert = msg->invertpattern ? 0 : 0xFFFF;
3792 if (data.maskarray)
3794 data.maskarray += (msg->masksrcx / 16) * 2;
3795 data.maskmask = 0x8000 >> (msg->masksrcx & 0xF);
3796 get = TRUE;
3798 else
3799 data.maskmask = 0xFFFF;
3801 DPUTPATTERN(bug("[PutPattern] MaskArray 0x%p, MaskMask 0x%04X\n", data.maskarray, data.maskmask));
3803 DoBufferedOperation(cl, o, msg->x, msg->y, msg->width, msg->height, get, vHidd_StdPixFmt_Native32, (VOID_FUNC)op, &data);
3805 /* TODO: Write fallback */
3807 ReturnVoid("BitMap::PutPattern");
3810 /*****************************************************************************************
3812 NAME
3813 moHidd_BitMap_PutImageLUT
3815 SYNOPSIS
3816 VOID OOP_DoMethod(OOP_Object *o, struct pHidd_BitMap_PutImageLUT *msg);
3818 VOID HIDD_BM_PutImageLUT (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels, ULONG modulo,
3819 WORD x, WORD y, WORD width, WORD height, HIDDT_PixelLUT *pixlut);
3821 LOCATION
3822 hidd.graphics.bitmap
3824 FUNCTION
3826 INPUTS
3827 obj -
3828 gc -
3829 pixels -
3830 modulo -
3831 x, y -
3832 width -
3833 height -
3834 pixlut -
3836 RESULT
3838 NOTES
3840 EXAMPLE
3842 BUGS
3844 SEE ALSO
3846 INTERNALS
3848 *****************************************************************************************/
3850 VOID BM__Hidd_BitMap__PutImageLUT(OOP_Class *cl, OOP_Object *o,
3851 struct pHidd_BitMap_PutImageLUT *msg)
3853 WORD x, y;
3854 UBYTE *pixarray = (UBYTE *)msg->pixels;
3855 HIDDT_PixelLUT *pixlut = msg->pixlut;
3856 HIDDT_Pixel *lut = pixlut ? pixlut->pixels : NULL;
3857 HIDDT_Pixel *linebuf;
3858 OOP_Object *gc = msg->gc;
3860 EnterFunc(bug("BitMap::PutImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
3861 , msg->x, msg->y, msg->width, msg->height));
3863 if (msg->width <= 0 || msg->height <= 0)
3864 return;
3866 linebuf = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
3868 for(y = 0; y < msg->height; y++)
3870 if (linebuf)
3872 if (lut)
3874 for(x = 0; x < msg->width; x++)
3876 linebuf[x] = lut[pixarray[x]];
3879 else
3881 for(x = 0; x < msg->width; x++)
3883 linebuf[x] = pixarray[x];
3886 pixarray += msg->modulo;
3888 HIDD_BM_PutImage(o,
3889 msg->gc,
3890 (UBYTE *)linebuf,
3892 msg->x,
3893 msg->y + y,
3894 msg->width,
3896 vHidd_StdPixFmt_Native32);
3898 } /* if (linebuf) */
3899 else
3901 ULONG old_fg;
3903 /* Preserve old fg pen */
3904 old_fg = GC_FG(gc);
3906 if (lut)
3908 for(x = 0; x < msg->width; x++)
3910 GC_FG(gc) = lut[pixarray[x]];
3911 HIDD_BM_DrawPixel(o, gc, msg->x + x, msg->y + y);
3914 else
3916 for(x = 0; x < msg->width; x++)
3918 GC_FG(gc) = pixarray[x];
3919 HIDD_BM_DrawPixel(o, gc, msg->x + x, msg->y + y);
3922 GC_FG(gc) = old_fg;
3924 pixarray += msg->modulo;
3926 } /* if (linebuf) else ... */
3928 } /* for(y = 0; y < msg->height; y++) */
3930 FreeVec(linebuf);
3932 ReturnVoid("BitMap::PutImageLUT");
3934 /*****************************************************************************************
3936 NAME
3937 moHidd_BitMap_PutTranspImageLUT
3939 SYNOPSIS
3940 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_PutTranspImageLUT *msg);
3942 VOID HIDD_BM_PutTranspImageLUT (OOP_Object *obj, OOP_Object *gc, UBYTE *pixels,
3943 ULONG modulo, WORD x, WORD y, WORD width, WORD height,
3944 HIDDT_PixelLUT *pixlut, UBYTE transparent);
3946 LOCATION
3947 hidd.graphics.bitmap
3949 FUNCTION
3950 Copy an array of 8-bit LUT pixels to the bitmap at the specified position making
3951 one of colors transparent.
3953 Pixels are converted to bitmap's native format using either user-supplied LUT (if
3954 given) or bitmap's own colormap.
3956 Draw mode of the supplied GC is ignored, the operation is always bulk copy.
3958 INPUTS
3959 obj - A bitmap to draw image on
3960 gc - A GC used for drawing
3961 pixels - A pointer to source pixel array
3962 modulo - Total number of bytes per line in the source array
3963 x, y - Top-left corner of the destination rectangle
3964 width - Width of the image to draw
3965 height - Height of the image to draw
3966 pixlut - An optional pointer to a LUT to use. NULL means using bitmap's
3967 own colormap (if available)
3968 transparent - Value of pixels in the source array which will be made
3969 transparent
3971 RESULT
3972 None
3974 NOTES
3976 EXAMPLE
3978 BUGS
3980 SEE ALSO
3982 INTERNALS
3984 *****************************************************************************************/
3986 #undef csd /* Bad hack, but there's no other way */
3988 struct ptilb_data
3990 UBYTE *pixarray;
3991 ULONG *lut;
3992 OOP_Object *colmap;
3993 struct class_static_data *csd;
3994 ULONG modulo;
3995 UBYTE transparent;
3998 static void PutTranspImageLUTBuffered(ULONG *xbuf, UWORD starty, UWORD width, UWORD height, struct ptilb_data *data)
4000 struct class_static_data *csd = data->csd;
4001 UWORD x, y;
4003 for (y = 0; y < height; y++)
4005 UBYTE *pixarray = data->pixarray;
4007 if (data->lut)
4009 for (x = 0; x < width; x++)
4011 UBYTE pix = *pixarray++;
4013 if (pix != data->transparent)
4014 xbuf[x] = data->lut[pix];
4016 } /* for (x) */
4018 else
4020 for (x = 0; x < width; x++)
4022 UBYTE pix = *pixarray++;
4024 if (pix != data->transparent)
4026 if (data->colmap)
4027 pix = HIDD_CM_GetPixel(data->colmap, pix);
4029 xbuf[x] = pix;
4032 } /* for (x) */
4035 xbuf += width;
4036 data->pixarray += data->modulo;
4037 } /* for (y) */
4040 VOID BM__Hidd_BitMap__PutTranspImageLUT(OOP_Class *cl, OOP_Object *o,
4041 struct pHidd_BitMap_PutTranspImageLUT *msg)
4043 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
4044 struct ptilb_data userdata =
4046 msg->pixels,
4047 NULL,
4048 data->colmap,
4049 CSD(cl),
4050 msg->modulo,
4051 msg->transparent
4054 EnterFunc(bug("BitMap::PutTranspImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
4055 , msg->x, msg->y, msg->width, msg->height));
4057 if (msg->width <= 0 || msg->height <= 0)
4058 return;
4060 if (msg->pixlut)
4061 userdata.lut = msg->pixlut->pixels;
4063 DoBufferedOperation(cl, o, msg->x, msg->y, msg->width, msg->height, TRUE, vHidd_StdPixFmt_Native32,
4064 (VOID_FUNC)PutTranspImageLUTBuffered, &userdata);
4066 /* TODO: Write fallback */
4068 ReturnVoid("BitMap::PutTranspImageLUT");
4071 #define csd CSD(cl)
4073 /*****************************************************************************************
4075 NAME
4076 moHidd_BitMap_GetImageLUT
4078 SYNOPSIS
4079 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_GetImageLUT *msg);
4081 VOID HIDD_BM_GetImageLUT (OOP_Object *obj, UBYTE *pixels, ULONG modulo, WORD x, WORD y,
4082 WORD width, WORD height, HIDDT_PixelLUT *pixlut);
4084 LOCATION
4085 hidd.graphics.bitmap
4087 FUNCTION
4089 INPUTS
4090 obj -
4091 pixels -
4092 modulo -
4093 x, y -
4094 width -
4095 height -
4096 pixlut -
4098 RESULT
4100 NOTES
4102 EXAMPLE
4104 BUGS
4106 SEE ALSO
4108 INTERNALS
4110 *****************************************************************************************/
4112 VOID BM__Hidd_BitMap__GetImageLUT(OOP_Class *cl, OOP_Object *o,
4113 struct pHidd_BitMap_GetImageLUT *msg)
4115 WORD x, y;
4116 UBYTE *pixarray = (UBYTE *)msg->pixels;
4117 HIDDT_PixelLUT *pixlut = msg->pixlut;
4118 HIDDT_Pixel *lut = pixlut ? pixlut->pixels : NULL;
4119 HIDDT_Pixel *linebuf;
4121 EnterFunc(bug("BitMap::GetImageLUT(x=%d, y=%d, width=%d, height=%d)\n"
4122 , msg->x, msg->y, msg->width, msg->height));
4124 linebuf = AllocVec(msg->width * sizeof(HIDDT_Pixel), MEMF_PUBLIC);
4126 for(y = 0; y < msg->height; y++)
4128 if (linebuf)
4130 HIDD_BM_GetImage(o,
4131 (UBYTE *)linebuf,
4133 msg->x,
4134 msg->y + y,
4135 msg->width,
4137 vHidd_StdPixFmt_Native32);
4138 if (lut)
4140 /* FIXME: This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway */
4141 for(x = 0; x < msg->width; x++)
4143 pixarray[x] = (UBYTE)linebuf[x];
4146 else
4148 for(x = 0; x < msg->width; x++)
4150 pixarray[x] = (UBYTE)linebuf[x];
4153 pixarray += msg->modulo;
4155 } /* if (linebuf) */
4156 else
4158 if (lut)
4160 /* FIXME: This is wrong, but HIDD_BM_GetImageLUT on hi/truecolor screens does not really make sense anyway */
4161 for(x = 0; x < msg->width; x++)
4163 pixarray[x] = (UBYTE)HIDD_BM_GetPixel(o, msg->x + x, msg->y + y);
4166 else
4168 for(x = 0; x < msg->width; x++)
4170 pixarray[x] = (UBYTE)HIDD_BM_GetPixel(o, msg->x + x, msg->y + y);
4174 pixarray += msg->modulo;
4176 } /* if (linebuf) else ... */
4178 } /* for(y = 0; y < msg->height; y++) */
4180 FreeVec(linebuf);
4182 ReturnVoid("BitMap::GetImageLUT");
4185 /*****************************************************************************************
4187 NAME
4188 moHidd_BitMap_BlitColorExpansion
4190 SYNOPSIS
4191 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BlitColorExpansion *msg);
4193 VOID HIDD_BM_BlitColorExpansion (OOP_Object *obj, OOP_Object *gc, OOP_Object *srcBitMap,
4194 WORD srcX, WORD srcY, WORD destX, WORD destY,
4195 UWORD width, UWORD height);
4197 LOCATION
4198 hidd.graphics.bitmap
4200 FUNCTION
4201 Perform a color expansion of the mask in srcBitMap according to foreground and background
4202 colors and expansion mode specified by the supplied GC. Pixels which are set to zero in
4203 the mask bitmap will be either painted by background (in opaque mode) or left without
4204 change (in transparent mode). Pixels which are set to nonzero in the mask will be painted
4205 by foreground color.
4207 The result of expansion is blitted onto the destination bitmap accorging to GC's draw mode.
4209 INPUTS
4210 obj - A bitmap to draw on
4211 gc - A GC object to use for drawing
4212 srcBitMap - A bitmap object containing mask image.
4213 srcX, srcY - A top-left coordinate of the used rectangle in the source bitmap
4214 destX, destY - A top-left coordinate of the destination rectangle to draw in
4215 width, height - A size of the rectangle to blit
4217 RESULT
4218 None.
4220 NOTES
4221 This method was previously used by graphics.library/Text() to draw fonts with no
4222 styles specified. Currently graphics.library always uses BltTemplate() and this
4223 method is considered obsolete.
4225 EXAMPLE
4227 BUGS
4229 SEE ALSO
4231 INTERNALS
4233 *****************************************************************************************/
4235 VOID BM__Hidd_BitMap__BlitColorExpansion(OOP_Class *cl, OOP_Object *o,
4236 struct pHidd_BitMap_BlitColorExpansion *msg)
4238 #ifdef __RESERVED__
4239 ULONG cemd;
4240 ULONG fg, bg;
4241 WORD x, y;
4243 OOP_Object *gc = msg->gc;
4245 EnterFunc(bug("BitMap::BlitColorExpansion(srcBM=%p, srcX=%d, srcY=%d, destX=%d, destY=%d, width=%d, height=%d)\n",
4246 msg->srcBitMap, msg->srcX, msg->srcY, msg->destX, msg->destY, msg->width, msg->height));
4248 cemd = GC_COLEXP(gc);
4249 fg = GC_FG(gc);
4250 bg = GC_BG(gc);
4252 /* bug("------------- Blit_ColExp: (%d, %d, %d, %d, %d, %d) cemd=%d, fg=%p, bg=%p -------------\n"
4253 , msg->srcX, msg->srcY, msg->destX, msg->destY, msg->width, msg->height
4254 , cemd, fg, bg);
4256 for (y = 0; y < msg->height; y ++)
4258 for (x = 0; x < msg->width; x ++)
4260 ULONG is_set;
4262 /* Pixel value is either 0 or 1 for BM of depth 1 */
4263 is_set = HIDD_BM_GetPixel(msg->srcBitMap, x + msg->srcX, y + msg->srcY);
4266 if (is_set)
4267 bug("#");
4268 else
4269 bug(" ");
4271 if (is_set)
4273 HIDD_BM_DrawPixel(o, gc, x + msg->destX, y + msg->destY);
4275 else
4277 if (cemd & vHidd_GC_ColExp_Opaque)
4279 /* Write bixel with BG pen */
4280 GC_FG(gc) = bg;
4281 HIDD_BM_DrawPixel(o, gc, x + msg->destX, y + msg->destY);
4282 /* Reset to FG pen */
4283 GC_FG(gc) = fg;
4286 } /* if () */
4288 } /* for (each x) */
4290 bug("\n");
4292 } /* for ( each y ) */
4293 #endif
4295 ReturnVoid("BitMap::BlitColorExpansion");
4298 /*****************************************************************************************
4300 NAME
4301 moHidd_BitMap_BytesPerLine
4303 SYNOPSIS
4304 ULONG OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BytesPerLine *msg);
4306 ULONG HIDD_BM_BytesPerLine(OOP_Object *obj, HIDDT_StdPixFmt pixFmt, UWORD width);
4308 LOCATION
4309 hidd.graphics.bitmap
4311 FUNCTION
4312 This method is currently not used and reserved.
4314 INPUTS
4315 obj -
4316 pixFmt -
4317 width -
4319 RESULT
4321 NOTES
4323 EXAMPLE
4325 BUGS
4327 SEE ALSO
4329 INTERNALS
4331 *****************************************************************************************/
4333 ULONG BM__Hidd_BitMap__BytesPerLine(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_BytesPerLine *msg)
4335 #ifdef __RESERVED__
4336 ULONG bpl;
4338 switch (msg->pixFmt)
4340 case vHidd_StdPixFmt_Native32:
4341 bpl = sizeof (HIDDT_Pixel) * msg->width;
4342 break;
4344 case vHidd_StdPixFmt_Native:
4346 struct HIDDBitMapData *data;
4348 data = OOP_INST_DATA(cl, o);
4350 bpl = ((HIDDT_PixelFormat *)data->prot.pixfmt)->bytes_per_pixel * msg->width;
4351 break;
4354 default:
4356 OOP_Object *pf;
4357 struct HIDDBitMapData *data;
4359 data = OOP_INST_DATA(cl, o);
4361 pf = HIDD_Gfx_GetPixFmt(data->gfxhidd, msg->pixFmt);
4363 if (NULL == pf)
4365 D(bug("!!! COULD NOT GET STD PIXFMT IN BitMap::BytesPerLine() !!!\n"));
4366 return 0;
4369 bpl = ((HIDDT_PixelFormat *)pf)->bytes_per_pixel * msg->width;
4370 break;
4374 return bpl;
4375 #else
4376 return 0;
4377 #endif
4381 /****************************************************************************************/
4384 This makes it easier to create a subclass of the graphics hidd.
4385 It is only allowed to use this method in the p_RootNew method of a
4386 bitmap subclass.
4389 /****************************************************************************************/
4391 IPTR BM__Root__Set(OOP_Class *cl, OOP_Object *obj, struct pRoot_Set *msg)
4393 struct Library *UtilityBase = CSD(cl)->cs_UtilityBase;
4394 struct Library *OOPBase = CSD(cl)->cs_OOPBase;
4395 struct HIDDBitMapData *data = OOP_INST_DATA(cl, obj);
4396 struct TagItem *tag, *tstate;
4397 ULONG idx;
4398 WORD xoffset, yoffset;
4400 if (data->framebuffer)
4403 * If this is a framebuffer, we can process ModeID change.
4404 * We do it before parsing the rest of tags, because here we retrieve
4405 * defaults for new bitmap parameters (size and pixelformat).
4406 * They can be overridden by other tags. For example we can imagine
4407 * a hardware scrollable framebuffer whose width and height are larger
4408 * than visible part.
4410 HIDDT_ModeID modeid = GetTagData(aHidd_BitMap_ModeID, vHidd_ModeID_Invalid, msg->attrList);
4411 OOP_Object *sync, *pixfmt;
4413 if (HIDD_Gfx_GetMode(data->gfxhidd, modeid, &sync, &pixfmt))
4415 data->modeid = modeid;
4417 * Set defaults based on the ModeID.
4418 * They can be overriden lated, in SetBitMapTags.
4420 data->width = OOP_GET(sync, aHidd_Sync_HDisp);
4421 data->height = OOP_GET(sync, aHidd_Sync_VDisp);
4422 data->bytesPerRow = GetBytesPerRow(data, CSD(cl));
4423 data->prot.pixfmt = pixfmt;
4425 else
4427 /* Bad ModeID given, request rejected */
4428 return FALSE;
4431 /* Process the rest of tags. */
4432 BM__Hidd_BitMap__SetBitMapTags(cl, obj, msg->attrList);
4434 else
4437 * This is not a framebuffer.
4438 * We can modify size data (CHECKME: is it really used anywhere ?)
4439 * and also we can scroll (makes sense only if this is displayable
4440 * bitmap in mirrored framebuffer mode.
4442 BM__Hidd_BitMap__SetBitMapTags(cl, obj, msg->attrList);
4445 * And now we process position change.
4446 * One trick: we store our 'display' rectangle in bitmap's coordinates.
4447 * In other words, these are screen coordinates relative to bitmap, not
4448 * bitmap's ones relative to screen. As a result, we have to invert the sign.
4449 * This is done in order to simplify calculations in UpdateBitMap method of
4450 * graphics base class. It needs to perform intersection of update rectangle
4451 * with display rectangle, and they need to be in the same coordinate system
4452 * in order to be able to do this.
4453 * Update operation is performance-critical, so we perform this conversion
4454 * for display rectangle here.
4456 xoffset = data->display.MinX;
4457 yoffset = data->display.MinY;
4458 tstate = msg->attrList;
4459 while ((tag = NextTagItem(&tstate)))
4461 Hidd_BitMap_Switch(tag->ti_Tag, idx)
4463 case aoHidd_BitMap_LeftEdge:
4464 xoffset = tag->ti_Data;
4466 * FIXME:
4467 * Our bitmap cannot be smaller than display size because of fakegfx.hidd
4468 * limitations (it can't place cursor beyond bitmap edges). Otherwise Intuition
4469 * will provide strange user experience (mouse cursor will disappear)
4471 if (xoffset >= (WORD)data->displayWidth)
4472 xoffset = data->displayWidth - 1;
4473 else if (xoffset <= (WORD)-data->width)
4474 xoffset = -(data->width - 1);
4475 xoffset = -xoffset;
4476 D(bug("[BitMap] xoffset requested %ld, got %d\n", -tag->ti_Data, xoffset));
4477 break;
4479 case aoHidd_BitMap_TopEdge:
4480 /* Only offsets that ensure at least some of the bitmap is
4481 seen are valid */
4482 yoffset = tag->ti_Data;
4483 if (yoffset >= (WORD)data->displayHeight)
4484 yoffset = data->displayHeight - 1;
4485 else if (yoffset <= (WORD)-data->height)
4486 yoffset = -(data->height - 1);
4487 yoffset = -yoffset;
4488 D(bug("[BitMap] yoffset requested %ld, got %d\n", -tag->ti_Data, yoffset));
4489 break;
4493 if ((xoffset != data->display.MinX) || (yoffset != data->display.MinY))
4495 ObtainSemaphore(&data->lock);
4497 data->display.MinX = xoffset;
4498 data->display.MinY = yoffset;
4499 data->display.MaxX = xoffset + data->displayWidth;
4500 data->display.MaxY = yoffset + data->displayHeight;
4502 if (data->visible)
4504 GFX__Hidd_Gfx__UpdateFB(CSD(cl)->gfxhiddclass, data->gfxhidd,
4505 obj, data->display.MinX, data->display.MinY,
4506 0, 0, data->displayWidth, data->displayHeight);
4509 ReleaseSemaphore(&data->lock);
4513 /* There's no superclass above us */
4514 return TRUE;
4517 /*****************************************************************************************
4519 NAME
4520 moHidd_BitMap_SetColorMap
4522 SYNOPSIS
4523 OOP_Object * OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetColorMap *msg);
4525 OOP_Object * HIDD_BM_SetColorMap(OOP_Object *obj, OOP_Object *colorMap);
4527 LOCATION
4528 hidd.graphics.bitmap
4530 FUNCTION
4532 INPUTS
4533 obj -
4534 colorMap -
4536 RESULT
4538 NOTES
4540 EXAMPLE
4542 BUGS
4544 SEE ALSO
4546 INTERNALS
4548 *****************************************************************************************/
4550 OOP_Object *BM__Hidd_BitMap__SetColorMap(OOP_Class *cl, OOP_Object *o,
4551 struct pHidd_BitMap_SetColorMap *msg)
4553 struct HIDDBitMapData *data;
4554 OOP_Object *old;
4556 data = OOP_INST_DATA(cl, o);
4558 old = data->colmap;
4559 data->colmap = msg->colorMap;
4561 return old;
4564 /*****************************************************************************************
4566 NAME
4567 moHidd_BitMap_MapColor
4569 SYNOPSIS
4570 HIDDT_Pixel OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_MapColor *msg);
4572 HIDDT_Pixel HIDD_BM_MapColor(OOP_Object *obj, HIDDT_Color *color);
4574 LOCATION
4575 hidd.graphics.bitmap
4577 FUNCTION
4579 INPUTS
4580 obj -
4581 color -
4583 RESULT
4585 NOTES
4587 EXAMPLE
4589 BUGS
4591 SEE ALSO
4593 INTERNALS
4595 *****************************************************************************************/
4597 /* We only care about magnitudes here, so we don't
4598 * have to perform the square root operation to get
4599 * the real distance.
4601 static ULONG colorDistance(HIDDT_Color *a, HIDDT_Color *b)
4603 #define SQR(x) ((x) * (x))
4604 return SQR((int)a->red - (int)b->red) +
4605 SQR((int)a->blue - (int)b->blue) +
4606 SQR((int)a->green - (int)b->green) +
4607 SQR((int)a->alpha - (int)b->alpha);
4608 #undef SQR
4611 HIDDT_Pixel BM__Hidd_BitMap__MapColor(OOP_Class *cl, OOP_Object *o,
4612 struct pHidd_BitMap_MapColor *msg)
4614 HIDDT_PixelFormat *pf = BM_PIXFMT(o);
4616 HIDDT_Pixel red = msg->color->red;
4617 HIDDT_Pixel green = msg->color->green;
4618 HIDDT_Pixel blue = msg->color->blue;
4619 HIDDT_Pixel alpha = msg->color->alpha;
4621 /* This code assumes that sizeof(HIDDT_Pixel) is a multiple of sizeof(col->#?),
4622 which should be true for most (all?) systems. I have never heard
4623 of any system with for example 3 byte types.
4626 if (IS_TRUECOLOR(pf))
4628 if (HIDD_PF_SWAPPIXELBYTES(pf))
4630 /* FIXME: BM__Hidd_BitMap__MapColor assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats */
4632 HIDDT_Pixel pixel = MAP_RGBA(red, green, blue, alpha, pf);
4634 msg->color->pixval = SWAPBYTES_WORD(pixel);
4636 else
4638 msg->color->pixval = MAP_RGBA(red, green, blue, alpha, pf);
4641 else
4643 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
4644 HIDDT_Color *ctab;
4645 HIDDT_ColorLUT *cmap;
4646 UWORD i;
4647 ULONG best_ndx = ~0, best_dist = ~0;
4649 cmap = (HIDDT_ColorLUT *)data->colmap;
4650 ctab = cmap->colors;
4651 /* Search for the best match in the color table */
4652 for (i = 0; i < cmap->entries; i++) {
4653 ULONG dist;
4655 dist = colorDistance(&ctab[i], msg->color);
4656 if (dist < best_dist) {
4657 best_dist = dist;
4658 best_ndx = i;
4662 if (best_dist != ~0)
4663 msg->color->pixval = ctab[best_ndx].pixval;
4666 return msg->color->pixval;
4669 /*****************************************************************************************
4671 NAME
4672 moHidd_BitMap_UnmapPixel
4674 SYNOPSIS
4675 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_UnmapPixel *msg);
4677 VOID HIDD_BM_UnmapPixel(OOP_Object *obj, HIDDT_Pixel pixel, HIDDT_Color *color);
4679 LOCATION
4680 hidd.graphics.bitmap
4682 FUNCTION
4684 INPUTS
4685 obj -
4686 pixel -
4687 color -
4689 RESULT
4691 NOTES
4693 EXAMPLE
4695 BUGS
4697 SEE ALSO
4699 INTERNALS
4701 *****************************************************************************************/
4703 VOID BM__Hidd_BitMap__UnmapPixel(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_UnmapPixel *msg)
4706 HIDDT_PixelFormat *pf = BM_PIXFMT(o);
4708 if (IS_TRUECOLOR(pf))
4710 HIDDT_Pixel pixel = msg->pixel;
4712 if (HIDD_PF_SWAPPIXELBYTES(pf))
4714 /* FIXME: bitmap_unmappixel assuming that SwapPixelBytes flag only set for 2-byte/16-bit pixel formats */
4715 pixel = SWAPBYTES_WORD(pixel);
4718 msg->color->red = RED_COMP (pixel, pf);
4719 msg->color->green = GREEN_COMP (pixel, pf);
4720 msg->color->blue = BLUE_COMP (pixel, pf);
4721 msg->color->alpha = ALPHA_COMP (pixel, pf);
4723 else
4725 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
4726 HIDDT_ColorLUT *clut;
4728 clut = (HIDDT_ColorLUT *)data->colmap;
4732 /* FIXME: Use CLUT shift and CLUT mask here */
4733 if (msg->pixel < 0 || msg->pixel >= clut->entries)
4734 return;
4736 *msg->color = clut->colors[msg->pixel];
4740 /* Unnecessary, but... */
4741 msg->color->pixval = msg->pixel;
4744 /*****************************************************************************************
4746 NAME
4747 moHidd_BitMap_ObtainDirectAccess
4749 SYNOPSIS
4750 BOOL OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_ObtainDirectAccess *msg);
4752 BOOL HIDD_BM_ObtainDirectAccess(OOP_Object *obj, UBYTE **addressReturn,
4753 ULONG *widthReturn, ULONG *heightReturn,
4754 ULONG *bankSizeReturn, ULONG *memSizeReturn);
4756 LOCATION
4757 hidd.graphics.bitmap
4759 FUNCTION
4761 INPUTS
4762 obj -
4763 addressReturn -
4764 widthReturn -
4765 heightReturn -
4766 bankSizeReturn -
4767 memSizeReturn -
4769 RESULT
4770 BOOL
4772 NOTES
4774 EXAMPLE
4776 BUGS
4778 SEE ALSO
4780 INTERNALS
4782 *****************************************************************************************/
4784 BOOL BM__Hidd_BitMap__ObtainDirectAccess(OOP_Class *cl, OOP_Object *o,
4785 struct pHidd_BitMap_ObtainDirectAccess *msg)
4787 /* Default implementation of direct access funcs. Just return FALSE */
4788 return FALSE;
4791 /*****************************************************************************************
4793 NAME
4794 moHidd_BitMap_ReleaseDirectAccess
4796 SYNOPSIS
4797 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_ReleaseDirectAccess *msg);
4799 VOID HIDD_BM_ReleaseDirectAccess(OOP_Object *obj);
4801 LOCATION
4802 hidd.graphics.bitmap
4804 FUNCTION
4806 INPUTS
4807 obj -
4809 RESULT
4811 NOTES
4813 EXAMPLE
4815 BUGS
4817 SEE ALSO
4819 INTERNALS
4821 *****************************************************************************************/
4823 VOID BM__Hidd_BitMap__ReleaseDirectAccess(OOP_Class *cl, OOP_Object *o,
4824 struct pHidd_BitMap_ReleaseDirectAccess *msg)
4826 D(bug("!!! BitMap BaseClasse ReleaseDirectAccess() called !!!\n"));
4827 D(bug("!!! This should never happen and is probably due to a buggy implementation in the subclass !!!\n"));
4829 return;
4832 /*****************************************************************************************
4834 NAME
4835 moHidd_BitMap_BitMapScale
4837 SYNOPSIS
4838 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_BitMapScale * msg);
4840 VOID HIDD_BM_BitMapScale(OOP_Object *obj, OOP_Object *src, OOP_Object *dest,
4841 struct BitScaleArgs * bsa, OOP_Object *gc);
4843 LOCATION
4844 hidd.graphics.bitmap
4846 FUNCTION
4848 INPUTS
4849 obj -
4850 src -
4851 dest -
4852 bsa -
4853 gc -
4855 RESULT
4857 NOTES
4859 EXAMPLE
4861 BUGS
4863 SEE ALSO
4865 INTERNALS
4867 *****************************************************************************************/
4869 VOID BM__Hidd_BitMap__BitMapScale(OOP_Class * cl, OOP_Object *o,
4870 struct pHidd_BitMap_BitMapScale * msg)
4872 struct BitScaleArgs *bsa = msg->bsa;
4873 ULONG *srcbuf, *dstbuf;
4874 WORD srcline = -1;
4875 UWORD *linepattern;
4876 UWORD count;
4877 UWORD ys = bsa->bsa_SrcY;
4878 UWORD xs = bsa->bsa_SrcX;
4879 UWORD dyd = bsa->bsa_DestHeight;
4880 UWORD dxd = bsa->bsa_DestWidth;
4881 LONG accuys = dyd;
4882 LONG accuxs = dxd;
4883 UWORD dxs = bsa->bsa_SrcWidth;
4884 UWORD dys = bsa->bsa_SrcHeight;
4885 LONG accuyd = - (dys >> 1);
4886 LONG accuxd = - (dxs >> 1);
4887 UWORD x;
4889 if ((srcbuf = AllocVec(bsa->bsa_SrcWidth * sizeof(ULONG), 0)) == NULL)
4890 return;
4892 if ((dstbuf = AllocVec(bsa->bsa_DestWidth * sizeof(ULONG), 0)) == NULL) {
4893 FreeVec(srcbuf);
4894 return;
4897 if ((linepattern = (UWORD *) AllocVec(bsa->bsa_DestWidth * sizeof(UWORD), 0)) == NULL) {
4898 FreeVec(dstbuf);
4899 FreeVec(srcbuf);
4900 return;
4903 count = 0;
4904 while (count < bsa->bsa_DestWidth) {
4905 accuxd += dxs;
4906 while (accuxd > accuxs) {
4907 xs++;
4908 accuxs += dxd;
4911 linepattern[count] = xs;
4913 count++;
4916 count = bsa->bsa_DestY;
4917 while (count < bsa->bsa_DestHeight + bsa->bsa_DestY) {
4918 accuyd += dys;
4919 while (accuyd > accuys) {
4920 ys++;
4921 accuys += dyd;
4924 if (srcline != ys) {
4925 HIDD_BM_GetImage(msg->src, (UBYTE *) srcbuf, bsa->bsa_SrcWidth * sizeof(ULONG), bsa->bsa_SrcX, bsa->bsa_SrcY + ys, bsa->bsa_SrcWidth, 1, vHidd_StdPixFmt_Native32);
4926 srcline = ys;
4928 for (x = 0; x < bsa->bsa_DestWidth; x++)
4929 dstbuf[x] = srcbuf[linepattern[x]];
4932 HIDD_BM_PutImage(msg->dst, msg->gc, (UBYTE *) dstbuf, bsa->bsa_DestWidth * sizeof(ULONG), bsa->bsa_DestX, count, bsa->bsa_DestWidth, 1, vHidd_StdPixFmt_Native32);
4934 count++;
4937 FreeVec(linepattern);
4939 FreeVec(dstbuf);
4940 FreeVec(srcbuf);
4943 /*****************************************************************************************
4945 NAME
4946 moHidd_BitMap_SetRGBConversionFunction
4948 SYNOPSIS
4949 HIDDT_RGBConversionFunction
4950 OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_SetRGBConversionFunction *msg);
4952 HIDDT_RGBConversionFunction
4953 HIDD_BM_SetRGBConversionFunction(OOP_Object *obj, HIDDT_StdPixFmt srcPixFmt,
4954 HIDDT_StdPixFmt dstPixFmt,
4955 HIDDT_RGBConversionFunction function);
4957 LOCATION
4958 hidd.graphics.bitmap
4960 FUNCTION
4962 INPUTS
4964 RESULT
4966 NOTES
4968 EXAMPLE
4970 BUGS
4972 SEE ALSO
4974 INTERNALS
4976 *****************************************************************************************/
4978 HIDDT_RGBConversionFunction BM__Hidd_BitMap__SetRGBConversionFunction(OOP_Class * cl, OOP_Object *o,
4979 struct pHidd_BitMap_SetRGBConversionFunction * msg)
4981 HIDDT_RGBConversionFunction old;
4983 if ((msg->srcPixFmt < FIRST_RGB_STDPIXFMT) ||
4984 (msg->dstPixFmt < FIRST_RGB_STDPIXFMT) ||
4985 (msg->srcPixFmt > LAST_RGB_STDPIXFMT) ||
4986 (msg->dstPixFmt > LAST_RGB_STDPIXFMT))
4988 return (HIDDT_RGBConversionFunction)-1;
4990 else
4992 ObtainSemaphore(&CSD(cl)->rgbconvertfuncs_sem);
4993 old = CSD(cl)->rgbconvertfuncs[msg->srcPixFmt - FIRST_RGB_STDPIXFMT][msg->dstPixFmt - FIRST_RGB_STDPIXFMT];
4994 CSD(cl)->rgbconvertfuncs[msg->srcPixFmt - FIRST_RGB_STDPIXFMT][msg->dstPixFmt - FIRST_RGB_STDPIXFMT] = msg->function;
4995 ReleaseSemaphore(&CSD(cl)->rgbconvertfuncs_sem);
4997 return old;
5001 /*****************************************************************************************
5003 NAME
5004 moHidd_BitMap_UpdateRect
5006 SYNOPSIS
5007 VOID OOP_DoMethod(OOP_Object *obj, struct pHidd_BitMap_UpdateRect *msg);
5009 VOID HIDD_BM_UpdateRect(OOP_Object *obj, WORD x, WORD y, WORD width, WORD height);
5011 LOCATION
5012 hidd.graphics.bitmap
5014 FUNCTION
5015 Update displayed image of the given rectangle.
5017 Some drivers (like VGA and VESA) may work not with VRAM directly, but with a mirrored
5018 copy of it. Usually it is done in case if VRAM reading is slow. This method is called
5019 by the system after it completes any drawing operation, in order to make sure that
5020 changes made are visible on the actual screen. If your driver uses mirroring, this method
5021 should copy the given rectangle (at least) from the mirror buffer to the actual VRAM.
5023 This method is also called after changing currently visible bitmap (after moHidd_Gfx_Show
5024 method call) in order to allow the mirroring driver to refresh the screen after current bitmap
5025 changed. Note that moHidd_Gfx_ShowViewPorts is very different and moHidd_BitMap_UpdateRect
5026 will not be called if it succeeded!
5028 INPUTS
5029 obj - an object whose image to refresh
5030 x, y - A top-left edge of the rectangle to refresh
5031 width - Width of the rectangle to refresh
5032 height - Height of the rectangle to refresh
5034 RESULT
5035 None.
5037 NOTES
5038 This method is called also on offscreen bitmaps. You should track visible state of your bitmap
5039 and ignore these calls if it's not currently visible on the screen.
5041 EXAMPLE
5043 BUGS
5045 SEE ALSO
5047 INTERNALS
5049 *****************************************************************************************/
5051 VOID BM__Hidd_BitMap__UpdateRect(OOP_Class *cl, OOP_Object *o, struct pHidd_BitMap_UpdateRect *msg)
5053 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
5055 DUPDATE(bug("[BitMap] UpdateRect(0x%p, %d, %d, %d, %d)\n", o, msg->x, msg->y, msg->width, msg->height));
5058 * We check data->visible twice in order to avoid unnecessary locking
5059 * when our bitmap is not on display (it may be not displayable at all).
5060 * However the second check is still needed in order to make sure that
5061 * this bitmap is still on display, because we could be preempted between
5062 * the test and ObtainSemaphoreShared() by concurrently running Show() call.
5063 * We use shared lock because it's safe to have two concurrently running
5064 * updates even on the same region.
5066 if (data->visible)
5068 ObtainSemaphoreShared(&data->lock);
5070 if (data->visible)
5073 * Complete update rectangle.
5074 * Display rectangle is already in bitmap's coordinates.
5076 UWORD srcX = msg->x;
5077 UWORD srcY = msg->y;
5078 UWORD xLimit = srcX + msg->width;
5079 UWORD yLimit = srcY + msg->height;
5081 /* Intersect rectangles */
5082 if (data->display.MinX > srcX)
5083 srcX = data->display.MinX;
5084 if (data->display.MinY > srcY)
5085 srcY = data->display.MinY;
5086 if (data->display.MaxX < xLimit)
5087 xLimit = data->display.MaxX;
5088 if (data->display.MaxY < yLimit)
5089 yLimit = data->display.MaxY;
5091 /* Update the intersection region, if any */
5092 if ((xLimit > srcX) && (yLimit > srcY))
5094 GFX__Hidd_Gfx__UpdateFB(CSD(cl)->gfxhiddclass, data->gfxhidd,
5095 o, srcX, srcY,
5096 srcX - data->display.MinX, srcY - data->display.MinY,
5097 xLimit - srcX, yLimit - srcY);
5101 ReleaseSemaphore(&data->lock);
5105 /****************************************************************************************/
5108 * Private methods follow.
5109 * They are implemented as non-virtual, for speed up.
5112 /* This is a private form of Set method. Doesn't need a standard message. */
5113 void BM__Hidd_BitMap__SetBitMapTags(OOP_Class *cl, OOP_Object *o, struct TagItem *bitMapTags)
5115 struct Library *UtilityBase = CSD(cl)->cs_UtilityBase;
5116 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
5117 struct TagItem *tag;
5119 while ((tag = NextTagItem(&bitMapTags)))
5121 ULONG idx;
5123 if (IS_BITMAP_ATTR(tag->ti_Tag, idx))
5125 switch (idx)
5127 case aoHidd_BitMap_Width:
5128 data->width = tag->ti_Data;
5129 break;
5131 case aoHidd_BitMap_Height:
5132 data->height = tag->ti_Data;
5133 break;
5135 case aoHidd_BitMap_BytesPerRow:
5136 data->bytesPerRow = tag->ti_Data;
5137 break;
5139 case aoHidd_BitMap_Compositable:
5140 data->compositable = tag->ti_Data;
5141 if (data->compositable)
5143 HIDDT_ModeID compositmodeid;
5144 struct Library *OOPBase = csd->cs_OOPBase;
5146 if (data->friend)
5148 OOP_GetAttr(data->friend, aHidd_BitMap_ModeID, &compositmodeid);
5150 else
5151 compositmodeid = data->modeid;
5153 if (compositmodeid == vHidd_ModeID_Invalid)
5155 data->compositable = FALSE;
5157 else
5159 OOP_Object *sync, *pf;
5161 if (!HIDD_Gfx_GetMode(data->gfxhidd, compositmodeid, &sync, &pf))
5163 data->compositable = FALSE;
5165 else
5167 /* Get display size from the modeid */
5168 OOP_GetAttr(sync, aHidd_Sync_HDisp, &data->displayWidth);
5169 OOP_GetAttr(sync, aHidd_Sync_VDisp, &data->displayHeight);
5170 data->display.MaxX = data->displayWidth;
5171 data->display.MaxY = data->displayHeight;
5173 D(bug("[BitMap] Bitmap %dx%d, display %dx%d\n",
5174 data->width, data->height,
5175 data->displayWidth, data->displayHeight));
5185 * Updates bitmap's pixelformat.
5186 * Used from within planarbm subclass, and would be extremely dangerous to expose
5187 * as setable aHidd_BitMap_PixFmt, so implemented as a separate method.
5189 void BM__Hidd_BitMap__SetPixFmt(OOP_Class *cl, OOP_Object *o, OOP_Object *pf)
5191 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
5193 /* Already a pixfmt registered? */
5194 if (data->pf_registered)
5195 GFX__Hidd_Gfx__ReleasePixFmt(CSD(cl)->gfxhiddclass, data->prot.pixfmt);
5197 /* Remember the new pixelformat */
5198 data->prot.pixfmt = pf;
5201 * This pixelformat was obtained using GFX__Hidd_Gfx__RegisterPixFmt().
5202 * It increases number of pixfmt users, so we'll need to release it when
5203 * not used any more.
5205 data->pf_registered = TRUE;
5209 * Change visible state of the bitmap.
5210 * Used in mirrored framebuffer mode. Actually needed because
5211 * of semaphore barrier, which makes sure that bitmap state does
5212 * not change during scrolling or updating operation. Prevents possibilities
5213 * of screen corruption during concurrently running scrolling with Show.
5215 void BM__Hidd_BitMap__SetVisible(OOP_Class *cl, OOP_Object *o, BOOL val)
5217 struct HIDDBitMapData *data = OOP_INST_DATA(cl, o);
5219 ObtainSemaphore(&data->lock);
5220 data->visible = val;
5221 ReleaseSemaphore(&data->lock);