2 Copyright © 2002-2011, The AROS Development Team. All rights reserved.
6 #include <graphics/gfx.h>
7 #include <graphics/view.h>
8 #include <clib/alib_protos.h>
9 #include <cybergraphx/cybergraphics.h>
10 #include <proto/exec.h>
11 #include <proto/graphics.h>
12 #include <proto/utility.h>
13 #include <proto/cybergraphics.h>
14 #include <proto/intuition.h>
15 #include <proto/muimaster.h>
18 #include "muimaster_intern.h"
23 extern struct Library
*MUIMasterBase
;
27 struct BitMap
*bm
, *remapped_bm
;
29 LONG width
, height
, precision
, transparent
;
38 static void remap_bitmap(struct IClass
*cl
, Object
*obj
)
40 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
41 struct BitMap
*friendbm
= NULL
;
42 struct RastPort temprp
, bmrp
, *scrrp
;
44 ULONG
*cgfxcoltab
= NULL
;
46 WORD bmdepth
, bmwidth
, bmheight
, bmcols
, x
, y
;
48 if (!data
->mappingtable
&& !data
->sourcecolors
)
50 if (!data
->bm
|| (data
->width
< 1) || (data
->height
< 1))
53 /* Don't remap if bitmap is hicolor/truecolor */
54 if (GetBitMapAttr(data
->bm
, BMA_DEPTH
) > 8)
57 if (!data
->mappingtable
&& !data
->remaptable
)
60 AllocVec(256 * sizeof(WORD
), MEMF_PUBLIC
| MEMF_CLEAR
);
61 if (!data
->remaptable
)
65 scrrp
= &_screen(obj
)->RastPort
;
69 friendbm
= scrrp
->BitMap
;
70 bmflags
|= BMF_MINPLANES
;
73 linebuffer
= AllocVec(data
->width
+ 16, MEMF_PUBLIC
);
77 bmdepth
= GetBitMapAttr(scrrp
->BitMap
, BMA_DEPTH
);
81 bmcols
= 1L << bmdepth
;
84 AllocBitMap(data
->width
, data
->height
, bmdepth
, bmflags
, friendbm
);
86 if (!data
->remapped_bm
)
92 bmwidth
= GetBitMapAttr(data
->remapped_bm
, BMA_WIDTH
);
93 bmheight
= GetBitMapAttr(data
->remapped_bm
, BMA_HEIGHT
);
95 if (data
->transparent
!= -1)
97 data
->mask
= AllocRaster(bmwidth
, bmheight
);
98 memset(data
->mask
, 0xff, RASSIZE(bmwidth
, bmheight
));
102 !data
->mappingtable
&&
103 (GetBitMapAttr(data
->remapped_bm
, BMA_DEPTH
) >= 15))
105 cgfxcoltab
= AllocVec(bmcols
* sizeof(ULONG
), MEMF_ANY
);
109 for (y
= 0; y
< bmcols
; y
++)
111 ULONG red
= data
->sourcecolors
[y
* 3] & 0xFF000000;
112 ULONG green
= data
->sourcecolors
[y
* 3 + 1] & 0xFF000000;
113 ULONG blue
= data
->sourcecolors
[y
* 3 + 2] & 0xFF000000;
115 cgfxcoltab
[y
] = (red
>> 8) | (green
>> 16) | (blue
>> 24);
121 InitRastPort(&temprp
);
122 temprp
.BitMap
= AllocBitMap(data
->width
, 1, 1, 0, NULL
);
126 for (y
= 0; y
< data
->height
; y
++)
128 /* Read a line from source bitmap */
130 bmrp
.BitMap
= data
->bm
;
133 ReadPixelLine8(&bmrp
, 0, y
, data
->width
, linebuffer
, &temprp
);
137 for (x
= 0; x
< data
->width
; x
++)
139 linebuffer
[x
] = ReadPixel(&bmrp
, x
, y
);
143 /* Build the mask, totaly slow but works */
146 UBYTE
*mask
= data
->mask
+ y
* bmwidth
/ 8;
149 for (x
= 0; x
< data
->width
; x
++)
151 if (linebuffer
[x
] == data
->transparent
)
166 if (data
->mappingtable
)
168 for (x
= 0; x
< data
->width
; x
++)
170 linebuffer
[x
] = data
->mappingtable
[linebuffer
[x
]];
173 else if (!cgfxcoltab
)
175 for (x
= 0; x
< data
->width
; x
++)
177 UBYTE pixel
= linebuffer
[x
];
178 UBYTE remappixel
= data
->remaptable
[pixel
];
182 struct TagItem tags
[3];
183 tags
[0].ti_Tag
= OBP_Precision
;
184 tags
[0].ti_Data
= data
->precision
;
185 tags
[1].ti_Tag
= OBP_FailIfBad
;
186 tags
[1].ti_Data
= FALSE
;
189 data
->remaptable
[pixel
] = remappixel
=
190 ObtainBestPenA(_screen(obj
)->ViewPort
.ColorMap
,
191 data
->sourcecolors
[pixel
* 3],
192 data
->sourcecolors
[pixel
* 3 + 1],
193 data
->sourcecolors
[pixel
* 3 + 2], tags
) | 0x100;
196 linebuffer
[x
] = (remappixel
& 0xFF);
201 /* Write line into destination bitmap */
203 bmrp
.BitMap
= data
->remapped_bm
;
207 WriteLUTPixelArray(linebuffer
,
211 &bmrp
, cgfxcoltab
, 0, y
, data
->width
, 1, CTABFMT_XRGB8
);
215 bmrp
.BitMap
= data
->remapped_bm
;
218 WritePixelLine8(&bmrp
, 0, y
, data
->width
, linebuffer
,
223 for (x
= 0; x
< data
->width
; x
++)
225 SetAPen(&bmrp
, linebuffer
[x
]);
226 WritePixel(&bmrp
, x
, y
);
237 FreeBitMap(temprp
.BitMap
);
244 /**************************************************************************
246 **************************************************************************/
247 IPTR
Bitmap__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
249 struct MUI_BitmapData
*data
;
250 struct TagItem
*tag
, *tags
;
252 obj
= (Object
*) DoSuperMethodA(cl
, obj
, (Msg
) msg
);
256 data
= INST_DATA(cl
, obj
);
258 data
->precision
= PRECISION_GUI
;
259 data
->transparent
= -1;
260 data
->alpha
= 0xffffffff;
261 data
->use_alpha
= FALSE
;
263 /* parse initial taglist */
265 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
269 case MUIA_Bitmap_Alpha
:
270 data
->alpha
= tag
->ti_Data
;
271 data
->use_alpha
= TRUE
;
274 case MUIA_Bitmap_Bitmap
:
275 data
->bm
= (struct BitMap
*)tag
->ti_Data
;
278 case MUIA_Bitmap_Height
:
279 data
->height
= (LONG
) tag
->ti_Data
;
282 case MUIA_Bitmap_MappingTable
:
283 data
->mappingtable
= (UBYTE
*) tag
->ti_Data
;
286 case MUIA_Bitmap_Precision
:
287 data
->precision
= (LONG
) tag
->ti_Data
;
290 case MUIA_Bitmap_SourceColors
:
291 data
->sourcecolors
= (ULONG
*) tag
->ti_Data
;
294 case MUIA_Bitmap_Transparent
:
295 data
->transparent
= (LONG
) tag
->ti_Data
;
298 case MUIA_Bitmap_UseFriend
:
299 data
->usefriend
= (tag
->ti_Data
!= 0);
302 case MUIA_Bitmap_Width
:
303 data
->width
= (LONG
) tag
->ti_Data
;
312 /**************************************************************************
314 **************************************************************************/
315 IPTR
Bitmap__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
317 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
319 if (data
->remapped_bm
)
322 FreeBitMap(data
->remapped_bm
);
324 if (data
->remaptable
)
325 FreeVec(data
->remaptable
);
327 return DoSuperMethodA(cl
, obj
, msg
);
330 /**************************************************************************
332 **************************************************************************/
333 IPTR
Bitmap__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
335 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
336 struct TagItem
*tags
= msg
->ops_AttrList
;
339 while ((tag
= NextTagItem(&tags
)) != NULL
)
343 case MUIA_Bitmap_Alpha
:
344 data
->alpha
= tag
->ti_Data
;
345 data
->use_alpha
= TRUE
;
348 case MUIA_Bitmap_Bitmap
:
349 if (!data
->remapped_bm
)
351 data
->bm
= (struct BitMap
*)tag
->ti_Data
;
355 case MUIA_Bitmap_Height
:
356 data
->height
= (LONG
) tag
->ti_Data
;
359 case MUIA_Bitmap_MappingTable
:
360 data
->mappingtable
= (UBYTE
*) tag
->ti_Data
;
363 case MUIA_Bitmap_Precision
:
364 data
->precision
= (LONG
) tag
->ti_Data
;
367 case MUIA_Bitmap_SourceColors
:
368 data
->sourcecolors
= (ULONG
*) tag
->ti_Data
;
371 case MUIA_Bitmap_Transparent
:
372 data
->transparent
= (LONG
) tag
->ti_Data
;
375 case MUIA_Bitmap_Width
:
376 data
->width
= (LONG
) tag
->ti_Data
;
382 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
385 /**************************************************************************
387 **************************************************************************/
388 IPTR
Bitmap__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
390 #define STORE *(msg->opg_Storage)
392 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
394 switch (msg
->opg_AttrID
)
396 case MUIA_Bitmap_Alpha
:
400 case MUIA_Bitmap_Bitmap
:
401 STORE
= (IPTR
) data
->bm
;
404 case MUIA_Bitmap_Height
:
405 STORE
= (IPTR
) data
->height
;
408 case MUIA_Bitmap_MappingTable
:
409 STORE
= (IPTR
) data
->mappingtable
;
412 case MUIA_Bitmap_Precision
:
413 STORE
= (IPTR
) data
->precision
;
416 case MUIA_Bitmap_RemappedBitmap
:
417 STORE
= (IPTR
) data
->remapped_bm
;
420 case MUIA_Bitmap_SourceColors
:
421 STORE
= (IPTR
) data
->sourcecolors
;
424 case MUIA_Bitmap_Transparent
:
425 STORE
= (IPTR
) data
->transparent
;
428 case MUIA_Bitmap_Width
:
429 STORE
= (IPTR
) data
->width
;
433 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
437 /**************************************************************************
439 **************************************************************************/
440 IPTR
Bitmap__MUIM_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
442 //struct MUI_BitmapData *data = INST_DATA(cl, obj);
444 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
))
447 remap_bitmap(cl
, obj
);
452 /**************************************************************************
454 **************************************************************************/
455 IPTR
Bitmap__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
457 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
461 LONG bmwidth
= GetBitMapAttr(data
->remapped_bm
, BMA_WIDTH
);
462 LONG bmheight
= GetBitMapAttr(data
->remapped_bm
, BMA_HEIGHT
);
463 FreeRaster(data
->mask
, bmwidth
, bmheight
);
468 if (data
->remapped_bm
)
471 FreeBitMap(data
->remapped_bm
);
472 data
->remapped_bm
= NULL
;
474 if (data
->remaptable
)
478 for (i
= 0; i
< 256; i
++)
480 if (data
->remaptable
[i
])
482 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
,
483 data
->remaptable
[i
] & 0xFF);
484 data
->remaptable
[i
] = 0;
490 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
493 /**************************************************************************
495 **************************************************************************/
496 IPTR
Bitmap__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
,
497 struct MUIP_AskMinMax
*msg
)
499 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
501 msg
->MinMaxInfo
->MinWidth
+= 1;
502 msg
->MinMaxInfo
->MinHeight
+= 1;
504 msg
->MinMaxInfo
->DefWidth
+= 1;
505 msg
->MinMaxInfo
->DefHeight
+= 1;
507 msg
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
508 msg
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
513 /**************************************************************************
515 **************************************************************************/
516 IPTR
Bitmap__MUIM_Draw(struct IClass
*cl
, Object
*obj
,
517 struct MUIP_Draw
*msg
)
519 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
522 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
524 bm
= data
->remapped_bm
? data
->remapped_bm
: data
->bm
;
530 height
= data
->height
;
532 if (width
> _mwidth(obj
))
533 width
= _mwidth(obj
);
534 if (height
> _mheight(obj
))
535 height
= _mheight(obj
);
537 if ((width
> 0) && (height
> 0))
545 BltMaskBitMapRastPort(bm
, 0, 0, _rp(obj
), _mleft(obj
),
546 _mtop(obj
), width
, height
, 0xE0, data
->mask
);
550 BltBitMapRastPort(bm
, 0, 0, _rp(obj
), _mleft(obj
),
551 _mtop(obj
), width
, height
, 0xC0);
560 BOOPSI_DISPATCHER(IPTR
, Bitmap_Dispatcher
, cl
, obj
, msg
)
562 switch (msg
->MethodID
)
565 return Bitmap__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
567 return Bitmap__OM_DISPOSE(cl
, obj
, msg
);
569 return Bitmap__OM_SET(cl
, obj
, (struct opSet
*)msg
);
571 return Bitmap__OM_GET(cl
, obj
, (struct opGet
*)msg
);
573 return Bitmap__MUIM_Setup(cl
, obj
, msg
);
575 return Bitmap__MUIM_Cleanup(cl
, obj
, msg
);
577 return Bitmap__MUIM_AskMinMax(cl
, obj
,
578 (struct MUIP_AskMinMax
*)msg
);
580 return Bitmap__MUIM_Draw(cl
, obj
, (struct MUIP_Draw
*)msg
);
583 return DoSuperMethodA(cl
, obj
, msg
);
585 BOOPSI_DISPATCHER_END
590 const struct __MUIBuiltinClass _MUI_Bitmap_desc
=
594 sizeof(struct MUI_BitmapData
),
595 (void *) Bitmap_Dispatcher