Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vdr] Re: AddColor() / SetColor()



Clemens Kirchgatterer wrote:
> 
> Klaus Schmidinger <Klaus.Schmidinger@cadsoft.de> wrote:
> 
> > > Ok this means if I have a cBitmap bm and want to set it into an area
> > > that has been drawn on before, I would do a DrawRectangle on the
> > > whole area bm covers with bm->Color(0) and then do DrawBitmap.
> > > Thanks for the Hint!:-)
> > >
> > > But wouldn't it make sense to do the same check (and possibly reset)
> > > in DrawBitmap, too? (Just a question)
> >
> > You're right, this makes sense in any function that covers the entire
> > bitmap. I'll implement this in the next version.
> 
> is it only me, who thinks the whole osd stuff is more complicated then
> it should be? ;-) AFAICS, the main thing about it, is that different
> areas on the osd can have different palettes. thats what this is the
> SetAreas() methode for. but why isn't the palette part of the Area
> struct?

Because the tArea is just a helper struct that allows for the definition
of areas defined by coordinates and color depths - it needs no knowledge
about palettes.

> also i don't understand why cBitmap is derived from cPalette.
> IMHO, a Bitmap HAS a Palette but it isn't one (OO has or is relation).

Well, there are always several ways to do things... ;-)

> all i want to do is:
> 
> open an osd with given x, y, w, h, depth
> set the palette for this osd (16/256 color table)

In general you cannot assume that an OSD has any such thing as a palette.
If it is a full 32 bit graphics display there will be no palette. I have
redesigned the OSD stuff in VDR 1.3.7 to make it as general as possible - and
in the general case there are no palettes. See below on how to work with
bitmaps and palettes.

> set pixels within the osd (x, y, idx)
> call an update function (Flush())
> close the osd
> 
> can anybody point me to the most fitting aproach to do this with the osd
> api? my current solution seems to be non optimal:
> 
> #define COLOR(R,G,B,A) (B+(G<<8)+(R<<16)+(A<<24))
> #define PALETTE(I)     ((tColor)colortable[I])
> 
> static cOsd *screen = NULL;
> static int W, H, colortable[COLORS];
> 
> int
> palette() {
>    colortable[0]  = COLOR(0x00, 0x00, 0x00, 0x7F); // Background
>    colortable[1]  = COLOR(0xFC, 0xFC, 0xFC, 0xFF); // White
>    colortable[2]  = COLOR(0xFC, 0x14, 0x14, 0xFF); // Red
>    colortable[3]  = COLOR(0x00, 0xFC, 0xFC, 0xFF); // Cyan
>    colortable[4]  = COLOR(0xB0, 0x00, 0xFC, 0xFF); // Magenta
>    colortable[5]  = COLOR(0x24, 0xFC, 0x24, 0xFF); // Green
>    colortable[6]  = COLOR(0x00, 0x00, 0xFC, 0xFF); // Blue
>    colortable[7]  = COLOR(0xFC, 0xC0, 0x24, 0xFF); // Yellow
>    colortable[8]  = COLOR(0xC0, 0xA0, 0x00, 0xFF); // Orange
>    colortable[9]  = COLOR(0xFF, 0xA0, 0x00, 0xFF); // Orange2
>    colortable[10] = COLOR(0xF0, 0x80, 0x80, 0xFF); // Pink
>    colortable[11] = COLOR(0x00, 0xFF, 0xFF, 0xFF); // Cyan2
>    colortable[12] = COLOR(0xFF, 0x00, 0xFF, 0xFF); // Purple2
>    colortable[13] = COLOR(0x00, 0xFF, 0x00, 0xFF); // Green2
>    colortable[14] = COLOR(0x00, 0xA0, 0xFF, 0xFF); // Blue2
>    colortable[15] = COLOR(0x00, 0x00, 0x00, 0xFF); // Black
>    for (int i=0; i<COLORS; i++) {
>       screen->GetBitmap(0)->SetColor(i, PALETTE(i));

The areas and bitmaps are actually just a means of allowing hardware
that is less "powerful" (like the full featured DVB cards with their
limited OSD RAM) to work in a decent way. At the (external) cOsd level
you should not access any internal bitmaps. cOsd::GetBitmap() is going
to be 'protected' in the next version. Your code might crash in case
screen->GetBitmap(0) returns NULL (which would be perfectly legal).

>    }
>    return (0);
> }
> 
> int
> pixel(int x, int y, int idx) {
>    screen->DrawPixel(x, y, PALETTE(idx));
>    return (0);
> }
> 
> int
> open(int x, int y, int w, int h) {
>    if (screen) return (-1);
>    tArea win = { 0, 0, w-1, h-1, DEPTH };

If DEPTH is larger than 2 and your w and h are somewhere in the
area of the full screen you might want to offer an alternative
setup with various areas. It's just a suggestion to allow your
program to work on as many devices as possible.

>    if (!(screen = cOsdProvider::NewOsd(x, y))) {
>       if (!(screen = cOsdProvider::NewOsd(x, y))) {
>          return(-1);
>       }

Why are you calling cOsdProvider::NewOsd() twice here?
If it doesn't give you one in the first call, it won't
give you one in the second call, either.

>    }
>    screen->SetAreas(&win, 1);

You may want to do a screen->CanHandleAreas() first, or at least
check the return value of screen->SetAreas() - unless you are
completely sure that this will work on the target platform(s).

>    palette(PAL_VDR);

What is PAL_VDR?

>    screen->Flush();
> }
> 
> int
> close(void) {
>    if (screen) {
>       delete (screen);
>       return (0);
>    }
>    return (-1);
> }
> 
> int
> update(void) {
>    if (screen) {
>       screen->Flush();
>       return (0);
>    }
>    return (-1);
> }

You should rather set up a cBitmap of your own, fill it with whatever you
want to display, and then call screen->DrawBitmap() with it. This is the
only way you can make sure that it gets displayed on VDR's cDvbOsd as well
as on some cFrameBufferOsd that might be implemented by a plugin, and which
doesn't by itself use any bitmaps or areas, but rather draws directly
into a frame buffer memory area.

Klaus


-- 
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe vdr" as subject.



Home | Main Index | Thread Index