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
;
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
)
48 if (!data
->bm
|| (data
->width
< 1) || (data
->height
< 1))
51 /* Don't remap if bitmap is hicolor/truecolor */
52 if (GetBitMapAttr(data
->bm
, BMA_DEPTH
) > 8)
55 if (!data
->mappingtable
&& !data
->remaptable
)
58 AllocVec(256 * sizeof(WORD
), MEMF_PUBLIC
| MEMF_CLEAR
);
59 if (!data
->remaptable
)
63 scrrp
= &_screen(obj
)->RastPort
;
67 friendbm
= scrrp
->BitMap
;
68 bmflags
|= BMF_MINPLANES
;
71 linebuffer
= AllocVec(data
->width
+ 16, MEMF_PUBLIC
);
75 bmdepth
= GetBitMapAttr(scrrp
->BitMap
, BMA_DEPTH
);
79 bmcols
= 1L << bmdepth
;
82 AllocBitMap(data
->width
, data
->height
, bmdepth
, bmflags
, friendbm
);
84 if (!data
->remapped_bm
)
90 bmwidth
= GetBitMapAttr(data
->remapped_bm
, BMA_WIDTH
);
91 bmheight
= GetBitMapAttr(data
->remapped_bm
, BMA_HEIGHT
);
93 if (data
->transparent
!= -1)
95 data
->mask
= AllocRaster(bmwidth
, bmheight
);
96 memset(data
->mask
, 0xff, RASSIZE(bmwidth
, bmheight
));
100 !data
->mappingtable
&&
101 (GetBitMapAttr(data
->remapped_bm
, BMA_DEPTH
) >= 15))
103 cgfxcoltab
= AllocVec(bmcols
* sizeof(ULONG
), MEMF_ANY
);
107 for (y
= 0; y
< bmcols
; y
++)
109 ULONG red
= data
->sourcecolors
[y
* 3] & 0xFF000000;
110 ULONG green
= data
->sourcecolors
[y
* 3 + 1] & 0xFF000000;
111 ULONG blue
= data
->sourcecolors
[y
* 3 + 2] & 0xFF000000;
113 cgfxcoltab
[y
] = (red
>> 8) | (green
>> 16) | (blue
>> 24);
119 InitRastPort(&temprp
);
120 temprp
.BitMap
= AllocBitMap(data
->width
, 1, 1, 0, NULL
);
124 for (y
= 0; y
< data
->height
; y
++)
126 /* Read a line from source bitmap */
128 bmrp
.BitMap
= data
->bm
;
131 ReadPixelLine8(&bmrp
, 0, y
, data
->width
, linebuffer
, &temprp
);
135 for (x
= 0; x
< data
->width
; x
++)
137 linebuffer
[x
] = ReadPixel(&bmrp
, x
, y
);
141 /* Build the mask, totaly slow but works */
144 UBYTE
*mask
= data
->mask
+ y
* bmwidth
/ 8;
147 for (x
= 0; x
< data
->width
; x
++)
149 if (linebuffer
[x
] == data
->transparent
)
164 if (data
->mappingtable
)
166 for (x
= 0; x
< data
->width
; x
++)
168 linebuffer
[x
] = data
->mappingtable
[linebuffer
[x
]];
171 else if (!cgfxcoltab
)
173 for (x
= 0; x
< data
->width
; x
++)
175 UBYTE pixel
= linebuffer
[x
];
176 UBYTE remappixel
= data
->remaptable
[pixel
];
180 struct TagItem tags
[3];
181 tags
[0].ti_Tag
= OBP_Precision
;
182 tags
[0].ti_Data
= data
->precision
;
183 tags
[1].ti_Tag
= OBP_FailIfBad
;
184 tags
[1].ti_Data
= FALSE
;
187 data
->remaptable
[pixel
] = remappixel
=
188 ObtainBestPenA(_screen(obj
)->ViewPort
.ColorMap
,
189 data
->sourcecolors
[pixel
* 3],
190 data
->sourcecolors
[pixel
* 3 + 1],
191 data
->sourcecolors
[pixel
* 3 + 2], tags
) | 0x100;
194 linebuffer
[x
] = (remappixel
& 0xFF);
199 /* Write line into destination bitmap */
201 bmrp
.BitMap
= data
->remapped_bm
;
205 WriteLUTPixelArray(linebuffer
,
209 &bmrp
, cgfxcoltab
, 0, y
, data
->width
, 1, CTABFMT_XRGB8
);
213 bmrp
.BitMap
= data
->remapped_bm
;
216 WritePixelLine8(&bmrp
, 0, y
, data
->width
, linebuffer
,
221 for (x
= 0; x
< data
->width
; x
++)
223 SetAPen(&bmrp
, linebuffer
[x
]);
224 WritePixel(&bmrp
, x
, y
);
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
);
254 data
= INST_DATA(cl
, obj
);
256 data
->precision
= PRECISION_GUI
;
257 data
->transparent
= -1;
259 /* parse initial taglist */
261 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem(&tags
));)
265 case MUIA_Bitmap_Bitmap
:
266 data
->bm
= (struct BitMap
*)tag
->ti_Data
;
269 case MUIA_Bitmap_Height
:
270 data
->height
= (LONG
) tag
->ti_Data
;
273 case MUIA_Bitmap_MappingTable
:
274 data
->mappingtable
= (UBYTE
*) tag
->ti_Data
;
277 case MUIA_Bitmap_Precision
:
278 data
->precision
= (LONG
) tag
->ti_Data
;
281 case MUIA_Bitmap_SourceColors
:
282 data
->sourcecolors
= (ULONG
*) tag
->ti_Data
;
285 case MUIA_Bitmap_Transparent
:
286 data
->transparent
= (LONG
) tag
->ti_Data
;
289 case MUIA_Bitmap_UseFriend
:
290 data
->usefriend
= (tag
->ti_Data
!= 0);
293 case MUIA_Bitmap_Width
:
294 data
->width
= (LONG
) tag
->ti_Data
;
303 /**************************************************************************
305 **************************************************************************/
306 IPTR
Bitmap__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
308 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
310 if (data
->remapped_bm
)
313 FreeBitMap(data
->remapped_bm
);
315 if (data
->remaptable
)
316 FreeVec(data
->remaptable
);
318 return DoSuperMethodA(cl
, obj
, msg
);
321 /**************************************************************************
323 **************************************************************************/
324 IPTR
Bitmap__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
326 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
327 struct TagItem
*tags
= msg
->ops_AttrList
;
330 while ((tag
= NextTagItem(&tags
)) != NULL
)
334 case MUIA_Bitmap_Bitmap
:
335 if (!data
->remapped_bm
)
337 data
->bm
= (struct BitMap
*)tag
->ti_Data
;
341 case MUIA_Bitmap_Height
:
342 data
->height
= (LONG
) tag
->ti_Data
;
345 case MUIA_Bitmap_MappingTable
:
346 data
->mappingtable
= (UBYTE
*) tag
->ti_Data
;
349 case MUIA_Bitmap_Precision
:
350 data
->precision
= (LONG
) tag
->ti_Data
;
353 case MUIA_Bitmap_SourceColors
:
354 data
->sourcecolors
= (ULONG
*) tag
->ti_Data
;
357 case MUIA_Bitmap_Transparent
:
358 data
->transparent
= (LONG
) tag
->ti_Data
;
361 case MUIA_Bitmap_Width
:
362 data
->width
= (LONG
) tag
->ti_Data
;
368 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
371 /**************************************************************************
373 **************************************************************************/
374 IPTR
Bitmap__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
376 #define STORE *(msg->opg_Storage)
378 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
380 switch (msg
->opg_AttrID
)
382 case MUIA_Bitmap_Bitmap
:
383 STORE
= (IPTR
) data
->bm
;
386 case MUIA_Bitmap_Height
:
387 STORE
= (IPTR
) data
->height
;
390 case MUIA_Bitmap_MappingTable
:
391 STORE
= (IPTR
) data
->mappingtable
;
394 case MUIA_Bitmap_Precision
:
395 STORE
= (IPTR
) data
->precision
;
398 case MUIA_Bitmap_RemappedBitmap
:
399 STORE
= (IPTR
) data
->remapped_bm
;
402 case MUIA_Bitmap_SourceColors
:
403 STORE
= (IPTR
) data
->sourcecolors
;
406 case MUIA_Bitmap_Transparent
:
407 STORE
= (IPTR
) data
->transparent
;
410 case MUIA_Bitmap_Width
:
411 STORE
= (IPTR
) data
->width
;
415 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
419 /**************************************************************************
421 **************************************************************************/
422 IPTR
Bitmap__MUIM_Setup(struct IClass
*cl
, Object
*obj
, Msg msg
)
424 //struct MUI_BitmapData *data = INST_DATA(cl, obj);
426 if (!DoSuperMethodA(cl
, obj
, (Msg
) msg
))
429 remap_bitmap(cl
, obj
);
434 /**************************************************************************
436 **************************************************************************/
437 IPTR
Bitmap__MUIM_Cleanup(struct IClass
*cl
, Object
*obj
, Msg msg
)
439 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
443 LONG bmwidth
= GetBitMapAttr(data
->remapped_bm
, BMA_WIDTH
);
444 LONG bmheight
= GetBitMapAttr(data
->remapped_bm
, BMA_HEIGHT
);
445 FreeRaster(data
->mask
, bmwidth
, bmheight
);
450 if (data
->remapped_bm
)
453 FreeBitMap(data
->remapped_bm
);
454 data
->remapped_bm
= NULL
;
456 if (data
->remaptable
)
460 for (i
= 0; i
< 256; i
++)
462 if (data
->remaptable
[i
])
464 ReleasePen(_screen(obj
)->ViewPort
.ColorMap
,
465 data
->remaptable
[i
] & 0xFF);
466 data
->remaptable
[i
] = 0;
472 return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
475 /**************************************************************************
477 **************************************************************************/
478 IPTR
Bitmap__MUIM_AskMinMax(struct IClass
*cl
, Object
*obj
,
479 struct MUIP_AskMinMax
*msg
)
481 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
483 msg
->MinMaxInfo
->MinWidth
+= 1;
484 msg
->MinMaxInfo
->MinHeight
+= 1;
486 msg
->MinMaxInfo
->DefWidth
+= 1;
487 msg
->MinMaxInfo
->DefHeight
+= 1;
489 msg
->MinMaxInfo
->MaxWidth
= MUI_MAXMAX
;
490 msg
->MinMaxInfo
->MaxHeight
= MUI_MAXMAX
;
495 /**************************************************************************
497 **************************************************************************/
498 IPTR
Bitmap__MUIM_Draw(struct IClass
*cl
, Object
*obj
,
499 struct MUIP_Draw
*msg
)
501 struct MUI_BitmapData
*data
= INST_DATA(cl
, obj
);
504 DoSuperMethodA(cl
, obj
, (Msg
) msg
);
506 bm
= data
->remapped_bm
? data
->remapped_bm
: data
->bm
;
512 height
= data
->height
;
514 if (width
> _mwidth(obj
))
515 width
= _mwidth(obj
);
516 if (height
> _mheight(obj
))
517 height
= _mheight(obj
);
519 if ((width
> 0) && (height
> 0))
523 BltMaskBitMapRastPort(bm
, 0, 0, _rp(obj
), _mleft(obj
),
524 _mtop(obj
), width
, height
, 0xE0, data
->mask
);
528 BltBitMapRastPort(bm
, 0, 0, _rp(obj
), _mleft(obj
),
529 _mtop(obj
), width
, height
, 0xC0);
538 BOOPSI_DISPATCHER(IPTR
, Bitmap_Dispatcher
, cl
, obj
, msg
)
540 switch (msg
->MethodID
)
543 return Bitmap__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
545 return Bitmap__OM_DISPOSE(cl
, obj
, msg
);
547 return Bitmap__OM_SET(cl
, obj
, (struct opSet
*)msg
);
549 return Bitmap__OM_GET(cl
, obj
, (struct opGet
*)msg
);
551 return Bitmap__MUIM_Setup(cl
, obj
, msg
);
553 return Bitmap__MUIM_Cleanup(cl
, obj
, msg
);
555 return Bitmap__MUIM_AskMinMax(cl
, obj
,
556 (struct MUIP_AskMinMax
*)msg
);
558 return Bitmap__MUIM_Draw(cl
, obj
, (struct MUIP_Draw
*)msg
);
561 return DoSuperMethodA(cl
, obj
, msg
);
563 BOOPSI_DISPATCHER_END
568 const struct __MUIBuiltinClass _MUI_Bitmap_desc
=
572 sizeof(struct MUI_BitmapData
),
573 (void *) Bitmap_Dispatcher