2 Copyright © 2002-2006, 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
;
36 static void remap_bitmap(struct IClass
*cl
, Object
*obj
)
38 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
39 struct BitMap
*friendbm
= NULL
;
40 struct RastPort temprp
, bmrp
, *scrrp
;
42 ULONG
*cgfxcoltab
= NULL
;
44 WORD bmdepth
, bmwidth
, bmheight
, bmcols
, x
, y
;
46 if (!data
->mappingtable
&& !data
->sourcecolors
) return;
47 if (!data
->bm
|| (data
->width
< 1) || (data
->height
< 1)) return;
49 /* Don't remap if bitmap is hicolor/truecolor */
50 if (GetBitMapAttr(data
->bm
, BMA_DEPTH
) > 8) return;
52 if (!data
->mappingtable
&& !data
->remaptable
)
54 data
->remaptable
= AllocVec(256 * sizeof(WORD
), MEMF_PUBLIC
| MEMF_CLEAR
);
55 if (!data
->remaptable
) return;
58 scrrp
= &_screen(obj
)->RastPort
;
62 friendbm
= scrrp
->BitMap
;
63 bmflags
|= BMF_MINPLANES
;
66 linebuffer
= AllocVec(data
->width
+ 16, MEMF_PUBLIC
);
67 if (!linebuffer
) return;
69 bmdepth
= GetBitMapAttr(scrrp
->BitMap
, BMA_DEPTH
);
70 if (bmdepth
> 8) bmdepth
= 8;
72 bmcols
= 1L << bmdepth
;
74 data
->remapped_bm
= AllocBitMap(data
->width
, data
->height
, bmdepth
, bmflags
, friendbm
);
76 if (!data
->remapped_bm
)
82 bmwidth
= GetBitMapAttr(data
->remapped_bm
, BMA_WIDTH
);
83 bmheight
= GetBitMapAttr(data
->remapped_bm
, BMA_HEIGHT
);
85 if (data
->transparent
!= -1)
87 data
->mask
= AllocRaster(bmwidth
,bmheight
);
88 memset(data
->mask
, 0xff, RASSIZE(bmwidth
, bmheight
));
92 !data
->mappingtable
&&
93 (GetBitMapAttr(data
->remapped_bm
, BMA_DEPTH
) >= 15))
95 cgfxcoltab
= AllocVec(bmcols
* sizeof(ULONG
), MEMF_ANY
);
99 for(y
= 0; y
< bmcols
; y
++)
101 ULONG red
= data
->sourcecolors
[y
* 3] & 0xFF000000;
102 ULONG green
= data
->sourcecolors
[y
* 3 + 1] & 0xFF000000;
103 ULONG blue
= data
->sourcecolors
[y
* 3 + 2] & 0xFF000000;
105 cgfxcoltab
[y
] = (red
>> 8) | (green
>> 16) | (blue
>> 24);
111 InitRastPort(&temprp
);
112 temprp
.BitMap
= AllocBitMap(data
->width
, 1, 1, 0, NULL
);
116 for(y
= 0; y
< data
->height
; y
++)
118 /* Read a line from source bitmap */
120 bmrp
.BitMap
= data
->bm
;
123 ReadPixelLine8(&bmrp
, 0, y
, data
->width
, linebuffer
, &temprp
);
127 for(x
= 0; x
< data
->width
; x
++)
129 linebuffer
[x
] = ReadPixel(&bmrp
, x
, y
);
133 /* Build the mask, totaly slow but works */
136 UBYTE
*mask
= data
->mask
+ y
* bmwidth
/ 8;
139 for(x
= 0; x
< data
->width
; x
++)
141 if (linebuffer
[x
] == data
->transparent
)
156 if (data
->mappingtable
)
158 for(x
= 0; x
< data
->width
; x
++)
160 linebuffer
[x
] = data
->mappingtable
[linebuffer
[x
]];
163 else if (!cgfxcoltab
)
165 for(x
= 0; x
< data
->width
; x
++)
167 UBYTE pixel
= linebuffer
[x
];
168 UBYTE remappixel
= data
->remaptable
[pixel
];
172 struct TagItem tags
[3];
173 tags
[0].ti_Tag
= OBP_Precision
;
174 tags
[0].ti_Data
= data
->precision
;
175 tags
[1].ti_Tag
= OBP_FailIfBad
;
176 tags
[1].ti_Data
= FALSE
;
179 data
->remaptable
[pixel
] = remappixel
= ObtainBestPenA(_screen(obj
)->ViewPort
.ColorMap
,
180 data
->sourcecolors
[pixel
* 3],
181 data
->sourcecolors
[pixel
* 3 + 1],
182 data
->sourcecolors
[pixel
* 3 + 2],
186 linebuffer
[x
] = (remappixel
& 0xFF);
189 } /* else if (!cgfxcoltab) */
191 /* Write line into destination bitmap */
193 bmrp
.BitMap
= data
->remapped_bm
;
197 WriteLUTPixelArray(linebuffer
,
211 bmrp
.BitMap
= data
->remapped_bm
;
214 WritePixelLine8(&bmrp
, 0, y
, data
->width
, linebuffer
, &temprp
);
218 for(x
= 0; x
< data
->width
; x
++)
220 SetAPen(&bmrp
, linebuffer
[x
]);
221 WritePixel(&bmrp
, x
, y
);
227 } /* for(y = 0; y < data->height; y++) */
229 DeinitRastPort(&temprp
);
230 DeinitRastPort(&bmrp
);
235 FreeBitMap(temprp
.BitMap
);
242 /**************************************************************************
244 **************************************************************************/
245 IPTR
Bitmap__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
247 struct MUI_BitmapData
*data
;
248 struct TagItem
*tag
, *tags
;
250 obj
= (Object
*)DoSuperMethodA(cl
, obj
, (Msg
)msg
);
251 if (!obj
) return FALSE
;
253 data
= INST_DATA(cl
, obj
);
255 data
->precision
= PRECISION_GUI
;
256 data
->transparent
= -1;
258 /* parse initial taglist */
260 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
)); )
264 case MUIA_Bitmap_Bitmap
:
265 data
->bm
= (struct BitMap
*)tag
->ti_Data
;
268 case MUIA_Bitmap_Height
:
269 data
->height
= (LONG
)tag
->ti_Data
;
272 case MUIA_Bitmap_MappingTable
:
273 data
->mappingtable
= (UBYTE
*)tag
->ti_Data
;
276 case MUIA_Bitmap_Precision
:
277 data
->precision
= (LONG
)tag
->ti_Data
;
280 case MUIA_Bitmap_SourceColors
:
281 data
->sourcecolors
= (ULONG
*)tag
->ti_Data
;
284 case MUIA_Bitmap_Transparent
:
285 data
->transparent
= (LONG
)tag
->ti_Data
;
288 case MUIA_Bitmap_UseFriend
:
289 data
->usefriend
= (tag
->ti_Data
!= 0);
292 case MUIA_Bitmap_Width
:
293 data
->width
= (LONG
)tag
->ti_Data
;
302 /**************************************************************************
304 **************************************************************************/
305 IPTR
Bitmap__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
307 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
309 if (data
->remapped_bm
)
312 FreeBitMap(data
->remapped_bm
);
314 if (data
->remaptable
) FreeVec(data
->remaptable
);
316 return DoSuperMethodA(cl
, obj
, msg
);
319 /**************************************************************************
321 **************************************************************************/
322 IPTR
Bitmap__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
324 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
325 struct TagItem
*tags
= msg
->ops_AttrList
;
328 while ((tag
= NextTagItem((const struct TagItem
**)&tags
)) != NULL
)
332 case MUIA_Bitmap_Bitmap
:
333 if (!data
->remapped_bm
)
335 data
->bm
= (struct BitMap
*)tag
->ti_Data
;
339 case MUIA_Bitmap_Height
:
340 data
->height
= (LONG
)tag
->ti_Data
;
343 case MUIA_Bitmap_MappingTable
:
344 data
->mappingtable
= (UBYTE
*)tag
->ti_Data
;
347 case MUIA_Bitmap_Precision
:
348 data
->precision
= (LONG
)tag
->ti_Data
;
351 case MUIA_Bitmap_SourceColors
:
352 data
->sourcecolors
= (ULONG
*)tag
->ti_Data
;
355 case MUIA_Bitmap_Transparent
:
356 data
->transparent
= (LONG
)tag
->ti_Data
;
359 case MUIA_Bitmap_Width
:
360 data
->width
= (LONG
)tag
->ti_Data
;
366 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
369 /**************************************************************************
371 **************************************************************************/
372 IPTR
Bitmap__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
374 #define STORE *(msg->opg_Storage)
376 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
378 switch(msg
->opg_AttrID
)
380 case MUIA_Bitmap_Bitmap
:
381 STORE
= (IPTR
)data
->bm
;
384 case MUIA_Bitmap_Height
:
385 STORE
= (IPTR
)data
->height
;
388 case MUIA_Bitmap_MappingTable
:
389 STORE
= (IPTR
)data
->mappingtable
;
392 case MUIA_Bitmap_Precision
:
393 STORE
= (IPTR
)data
->precision
;
396 case MUIA_Bitmap_RemappedBitmap
:
397 STORE
= (IPTR
)data
->remapped_bm
;
400 case MUIA_Bitmap_SourceColors
:
401 STORE
= (IPTR
)data
->sourcecolors
;
404 case MUIA_Bitmap_Transparent
:
405 STORE
= (IPTR
)data
->transparent
;
408 case MUIA_Bitmap_Width
:
409 STORE
= (IPTR
)data
->width
;
413 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
417 /**************************************************************************
419 **************************************************************************/
420 IPTR
Bitmap__MUIM_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
422 //struct MUI_BitmapData *data = INST_DATA(cl, obj);
424 if (!DoSuperMethodA(cl
, obj
, (Msg
)msg
))
427 remap_bitmap(cl
, obj
);
432 /**************************************************************************
434 **************************************************************************/
435 IPTR
Bitmap__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
437 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
441 LONG bmwidth
= GetBitMapAttr(data
->remapped_bm
, BMA_WIDTH
);
442 LONG bmheight
= GetBitMapAttr(data
->remapped_bm
, BMA_HEIGHT
);
443 FreeRaster(data
->mask
,bmwidth
,bmheight
);
448 if (data
->remapped_bm
)
451 FreeBitMap(data
->remapped_bm
);
452 data
->remapped_bm
= NULL
;
454 if (data
->remaptable
)
458 for(i
= 0; i
< 256; i
++)
460 if (data
->remaptable
[i
])
462 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
, data
->remaptable
[i
] & 0xFF);
463 data
->remaptable
[i
] = 0;
469 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
472 /**************************************************************************
474 **************************************************************************/
475 IPTR
Bitmap__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
, struct MUIP_AskMinMax
*msg
)
477 DoSuperMethodA(cl
, obj
, (Msg
)msg
);
479 msg
->MinMaxInfo
->MinWidth
+= 1;
480 msg
->MinMaxInfo
->MinHeight
+= 1;
482 msg
->MinMaxInfo
->DefWidth
+= 1;
483 msg
->MinMaxInfo
->DefHeight
+= 1;
485 msg
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
486 msg
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
491 /**************************************************************************
493 **************************************************************************/
494 IPTR
Bitmap__MUIM_Draw(struct IClass
*cl
, Object
*obj
, struct MUIP_Draw
*msg
)
496 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
499 DoSuperMethodA(cl
,obj
,(Msg
)msg
);
501 bm
= data
->remapped_bm
? data
->remapped_bm
: data
->bm
;
507 height
= data
->height
;
509 if (width
> _mwidth(obj
)) width
= _mwidth(obj
);
510 if (height
> _mheight(obj
)) height
= _mheight(obj
);
512 if ((width
> 0) && (height
> 0))
516 BltMaskBitMapRastPort(bm
, 0, 0, _rp(obj
), _mleft(obj
), _mtop(obj
), width
, height
, 0xE0, data
->mask
);
520 BltBitMapRastPort(bm
, 0, 0, _rp(obj
), _mleft(obj
), _mtop(obj
), width
, height
, 0xC0);
529 BOOPSI_DISPATCHER(IPTR
, Bitmap_Dispatcher
, cl
, obj
, msg
)
531 switch (msg
->MethodID
)
533 case OM_NEW
: return Bitmap__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
534 case OM_DISPOSE
: return Bitmap__OM_DISPOSE(cl
, obj
, msg
);
535 case OM_SET
: return Bitmap__OM_SET(cl
, obj
, (struct opSet
*)msg
);
536 case OM_GET
: return Bitmap__OM_GET(cl
, obj
, (struct opGet
*)msg
);
537 case MUIM_Setup
: return Bitmap__MUIM_Setup(cl
, obj
, msg
);
538 case MUIM_Cleanup
: return Bitmap__MUIM_Cleanup(cl
, obj
, msg
);
539 case MUIM_AskMinMax
: return Bitmap__MUIM_AskMinMax(cl
, obj
, (struct MUIP_AskMinMax
*)msg
);
540 case MUIM_Draw
: return Bitmap__MUIM_Draw(cl
, obj
, (struct MUIP_Draw
*)msg
);
543 return DoSuperMethodA(cl
, obj
, msg
);
545 BOOPSI_DISPATCHER_END
550 const struct __MUIBuiltinClass _MUI_Bitmap_desc
= {
553 sizeof(struct MUI_BitmapData
),
554 (void*)Bitmap_Dispatcher