Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / muimaster / classes / bitmap.c
blob483281fe92341979618f773d4ea0d37609e6752a
1 /*
2 Copyright © 2002-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
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>
17 #include "mui.h"
18 #include "muimaster_intern.h"
19 #include "support.h"
21 #include <string.h>
23 extern struct Library *MUIMasterBase;
25 struct MUI_BitmapData
27 struct BitMap *bm, *remapped_bm;
28 ULONG *sourcecolors;
29 LONG width, height, precision, transparent;
30 UBYTE *mappingtable;
31 PLANEPTR mask;
32 WORD *remaptable;
33 BYTE usefriend;
34 ULONG alpha;
35 BOOL use_alpha;
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;
43 UBYTE *linebuffer;
44 ULONG *cgfxcoltab = NULL;
45 LONG bmflags = 0;
46 WORD bmdepth, bmwidth, bmheight, bmcols, x, y;
48 if (!data->mappingtable && !data->sourcecolors)
49 return;
50 if (!data->bm || (data->width < 1) || (data->height < 1))
51 return;
53 /* Don't remap if bitmap is hicolor/truecolor */
54 if (GetBitMapAttr(data->bm, BMA_DEPTH) > 8)
55 return;
57 if (!data->mappingtable && !data->remaptable)
59 data->remaptable =
60 AllocVec(256 * sizeof(WORD), MEMF_PUBLIC | MEMF_CLEAR);
61 if (!data->remaptable)
62 return;
65 scrrp = &_screen(obj)->RastPort;
67 if (data->usefriend)
69 friendbm = scrrp->BitMap;
70 bmflags |= BMF_MINPLANES;
73 linebuffer = AllocVec(data->width + 16, MEMF_PUBLIC);
74 if (!linebuffer)
75 return;
77 bmdepth = GetBitMapAttr(scrrp->BitMap, BMA_DEPTH);
78 if (bmdepth > 8)
79 bmdepth = 8;
81 bmcols = 1L << bmdepth;
83 data->remapped_bm =
84 AllocBitMap(data->width, data->height, bmdepth, bmflags, friendbm);
86 if (!data->remapped_bm)
88 FreeVec(linebuffer);
89 return;
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));
101 if (CyberGfxBase &&
102 !data->mappingtable &&
103 (GetBitMapAttr(data->remapped_bm, BMA_DEPTH) >= 15))
105 cgfxcoltab = AllocVec(bmcols * sizeof(ULONG), MEMF_ANY);
107 if (cgfxcoltab)
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);
124 InitRastPort(&bmrp);
126 for (y = 0; y < data->height; y++)
128 /* Read a line from source bitmap */
130 bmrp.BitMap = data->bm;
131 if (temprp.BitMap)
133 ReadPixelLine8(&bmrp, 0, y, data->width, linebuffer, &temprp);
135 else
137 for (x = 0; x < data->width; x++)
139 linebuffer[x] = ReadPixel(&bmrp, x, y);
143 /* Build the mask, totaly slow but works */
144 if (data->mask)
146 UBYTE *mask = data->mask + y * bmwidth / 8;
147 UBYTE xmask = 0x80;
149 for (x = 0; x < data->width; x++)
151 if (linebuffer[x] == data->transparent)
153 *mask &= ~xmask;
156 xmask >>= 1;
157 if (!xmask)
159 xmask = 0x80;
160 mask++;
165 /* Remap the line */
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];
180 if (!remappixel)
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;
187 tags[2].ti_Tag = 0;
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;
205 if (cgfxcoltab)
207 WriteLUTPixelArray(linebuffer,
210 data->width,
211 &bmrp, cgfxcoltab, 0, y, data->width, 1, CTABFMT_XRGB8);
213 else
215 bmrp.BitMap = data->remapped_bm;
216 if (temprp.BitMap)
218 WritePixelLine8(&bmrp, 0, y, data->width, linebuffer,
219 &temprp);
221 else
223 for (x = 0; x < data->width; x++)
225 SetAPen(&bmrp, linebuffer[x]);
226 WritePixel(&bmrp, x, y);
234 if (temprp.BitMap)
236 WaitBlit();
237 FreeBitMap(temprp.BitMap);
240 FreeVec(cgfxcoltab);
241 FreeVec(linebuffer);
244 /**************************************************************************
245 OM_NEW
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);
253 if (!obj)
254 return FALSE;
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));)
267 switch (tag->ti_Tag)
269 case MUIA_Bitmap_Alpha:
270 data->alpha = tag->ti_Data;
271 data->use_alpha = TRUE;
272 break;
274 case MUIA_Bitmap_Bitmap:
275 data->bm = (struct BitMap *)tag->ti_Data;
276 break;
278 case MUIA_Bitmap_Height:
279 data->height = (LONG) tag->ti_Data;
280 break;
282 case MUIA_Bitmap_MappingTable:
283 data->mappingtable = (UBYTE *) tag->ti_Data;
284 break;
286 case MUIA_Bitmap_Precision:
287 data->precision = (LONG) tag->ti_Data;
288 break;
290 case MUIA_Bitmap_SourceColors:
291 data->sourcecolors = (ULONG *) tag->ti_Data;
292 break;
294 case MUIA_Bitmap_Transparent:
295 data->transparent = (LONG) tag->ti_Data;
296 break;
298 case MUIA_Bitmap_UseFriend:
299 data->usefriend = (tag->ti_Data != 0);
300 break;
302 case MUIA_Bitmap_Width:
303 data->width = (LONG) tag->ti_Data;
304 break;
309 return (IPTR) obj;
312 /**************************************************************************
313 OM_DISPOSE
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)
321 WaitBlit();
322 FreeBitMap(data->remapped_bm);
324 if (data->remaptable)
325 FreeVec(data->remaptable);
327 return DoSuperMethodA(cl, obj, msg);
330 /**************************************************************************
331 OM_SET
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;
337 struct TagItem *tag;
339 while ((tag = NextTagItem(&tags)) != NULL)
341 switch (tag->ti_Tag)
343 case MUIA_Bitmap_Alpha:
344 data->alpha = tag->ti_Data;
345 data->use_alpha = TRUE;
346 break;
348 case MUIA_Bitmap_Bitmap:
349 if (!data->remapped_bm)
351 data->bm = (struct BitMap *)tag->ti_Data;
353 break;
355 case MUIA_Bitmap_Height:
356 data->height = (LONG) tag->ti_Data;
357 break;
359 case MUIA_Bitmap_MappingTable:
360 data->mappingtable = (UBYTE *) tag->ti_Data;
361 break;
363 case MUIA_Bitmap_Precision:
364 data->precision = (LONG) tag->ti_Data;
365 break;
367 case MUIA_Bitmap_SourceColors:
368 data->sourcecolors = (ULONG *) tag->ti_Data;
369 break;
371 case MUIA_Bitmap_Transparent:
372 data->transparent = (LONG) tag->ti_Data;
373 break;
375 case MUIA_Bitmap_Width:
376 data->width = (LONG) tag->ti_Data;
377 break;
382 return DoSuperMethodA(cl, obj, (Msg) msg);
385 /**************************************************************************
386 OM_GET
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:
397 STORE = data->alpha;
398 return TRUE;
400 case MUIA_Bitmap_Bitmap:
401 STORE = (IPTR) data->bm;
402 return TRUE;
404 case MUIA_Bitmap_Height:
405 STORE = (IPTR) data->height;
406 return TRUE;
408 case MUIA_Bitmap_MappingTable:
409 STORE = (IPTR) data->mappingtable;
410 return TRUE;
412 case MUIA_Bitmap_Precision:
413 STORE = (IPTR) data->precision;
414 return TRUE;
416 case MUIA_Bitmap_RemappedBitmap:
417 STORE = (IPTR) data->remapped_bm;
418 return TRUE;
420 case MUIA_Bitmap_SourceColors:
421 STORE = (IPTR) data->sourcecolors;
422 return TRUE;
424 case MUIA_Bitmap_Transparent:
425 STORE = (IPTR) data->transparent;
426 return TRUE;
428 case MUIA_Bitmap_Width:
429 STORE = (IPTR) data->width;
430 return TRUE;
433 return DoSuperMethodA(cl, obj, (Msg) msg);
434 #undef STORE
437 /**************************************************************************
438 MUIM_Setup
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))
445 return FALSE;
447 remap_bitmap(cl, obj);
449 return TRUE;
452 /**************************************************************************
453 MUIM_Cleanup
454 **************************************************************************/
455 IPTR Bitmap__MUIM_Cleanup(struct IClass *cl, Object *obj, Msg msg)
457 struct MUI_BitmapData *data = INST_DATA(cl, obj);
459 if (data->mask)
461 LONG bmwidth = GetBitMapAttr(data->remapped_bm, BMA_WIDTH);
462 LONG bmheight = GetBitMapAttr(data->remapped_bm, BMA_HEIGHT);
463 FreeRaster(data->mask, bmwidth, bmheight);
465 data->mask = NULL;
468 if (data->remapped_bm)
470 WaitBlit();
471 FreeBitMap(data->remapped_bm);
472 data->remapped_bm = NULL;
474 if (data->remaptable)
476 WORD i;
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 /**************************************************************************
494 MUIM_AskMinMax
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;
510 return TRUE;
513 /**************************************************************************
514 MUIM_Draw
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);
520 struct BitMap *bm;
522 DoSuperMethodA(cl, obj, (Msg) msg);
524 bm = data->remapped_bm ? data->remapped_bm : data->bm;
525 if (bm)
527 LONG width, height;
529 width = data->width;
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))
539 if (data->use_alpha)
541 // TODO: implement
543 else if (data->mask)
545 BltMaskBitMapRastPort(bm, 0, 0, _rp(obj), _mleft(obj),
546 _mtop(obj), width, height, 0xE0, data->mask);
548 else
550 BltBitMapRastPort(bm, 0, 0, _rp(obj), _mleft(obj),
551 _mtop(obj), width, height, 0xC0);
556 return TRUE;
560 BOOPSI_DISPATCHER(IPTR, Bitmap_Dispatcher, cl, obj, msg)
562 switch (msg->MethodID)
564 case OM_NEW:
565 return Bitmap__OM_NEW(cl, obj, (struct opSet *)msg);
566 case OM_DISPOSE:
567 return Bitmap__OM_DISPOSE(cl, obj, msg);
568 case OM_SET:
569 return Bitmap__OM_SET(cl, obj, (struct opSet *)msg);
570 case OM_GET:
571 return Bitmap__OM_GET(cl, obj, (struct opGet *)msg);
572 case MUIM_Setup:
573 return Bitmap__MUIM_Setup(cl, obj, msg);
574 case MUIM_Cleanup:
575 return Bitmap__MUIM_Cleanup(cl, obj, msg);
576 case MUIM_AskMinMax:
577 return Bitmap__MUIM_AskMinMax(cl, obj,
578 (struct MUIP_AskMinMax *)msg);
579 case MUIM_Draw:
580 return Bitmap__MUIM_Draw(cl, obj, (struct MUIP_Draw *)msg);
583 return DoSuperMethodA(cl, obj, msg);
585 BOOPSI_DISPATCHER_END
588 * Class descriptor.
590 const struct __MUIBuiltinClass _MUI_Bitmap_desc =
592 MUIC_Bitmap,
593 MUIC_Area,
594 sizeof(struct MUI_BitmapData),
595 (void *) Bitmap_Dispatcher