lots of work required).
if (ptr)
ptr->Release();
}
+
+ T* grabRef() { if (!ptr) return 0; ptr->AddRef(); return ptr; }
T* &ptrref() { assert(!ptr); return ptr; }
ePtrHelper<T> operator->() { assert(ptr); return ePtrHelper<T>(ptr); }
noinst_LIBRARIES = libenigma_gdi.a
libenigma_gdi_a_SOURCES = \
- epng.cpp erect.cpp fb.cpp font.cpp font_arabic.cpp gfbdc.cpp \
+ region.cpp grc.cpp epng.cpp erect.cpp fb.cpp font.cpp font_arabic.cpp gfbdc.cpp \
glcddc.cpp gpixmap.cpp grc.cpp lcd.cpp
#include <lib/gdi/epng.h>
#include <unistd.h>
-gImage *loadPNG(const char *filename)
+int loadPNG(ePtr<gPixmap> &result, const char *filename)
{
__u8 header[8];
FILE *fp=fopen(filename, "rb");
- gImage *res=0;
-
if (!fp)
{
// eDebug("couldn't open %s", filename );
eDebug("das war wohl nix");
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
fclose(fp);
- if (res)
- delete res;
+ result = 0;
return 0;
}
png_init_io(png_ptr, fp);
if (color_type != 6)
{
- res=new gImage(eSize(width, height), bit_depth);
+ result=new gPixmap(eSize(width, height), bit_depth);
+ gSurface *surface = result->surface;
png_bytep *rowptr=new png_bytep[height];
for (unsigned int i=0; i<height; i++)
- rowptr[i]=((png_byte*)(res->data))+i*res->stride;
+ rowptr[i]=((png_byte*)(surface->data))+i*surface->stride;
png_read_rows(png_ptr, rowptr, 0, height);
- delete rowptr;
+ delete [] rowptr;
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE))
{
int num_palette;
png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
if (num_palette)
- res->clut.data=new gRGB[num_palette];
+ surface->clut.data=new gRGB[num_palette];
else
- res->clut.data=0;
- res->clut.colors=num_palette;
+ surface->clut.data=0;
+ surface->clut.colors=num_palette;
for (int i=0; i<num_palette; i++)
{
- res->clut.data[i].a=0;
- res->clut.data[i].r=palette[i].red;
- res->clut.data[i].g=palette[i].green;
- res->clut.data[i].b=palette[i].blue;
+ surface->clut.data[i].a=0;
+ surface->clut.data[i].r=palette[i].red;
+ surface->clut.data[i].g=palette[i].green;
+ surface->clut.data[i].b=palette[i].blue;
}
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
{
png_byte *trans;
png_get_tRNS(png_ptr, info_ptr, &trans, &num_palette, 0);
for (int i=0; i<num_palette; i++)
- res->clut.data[i].a=255-trans[i];
+ surface->clut.data[i].a=255-trans[i];
}
} else
{
- res->clut.data=0;
- res->clut.colors=0;
+ surface->clut.data=0;
+ surface->clut.colors=0;
}
png_read_end(png_ptr, end_info);
} else
- res=0;
+ result=0;
png_destroy_read_struct(&png_ptr, &info_ptr,&end_info);
fclose(fp);
- return res;
+ return 0;
}
int savePNG(const char *filename, gPixmap *pixmap)
FILE *fp=fopen(filename, "wb");
if (!fp)
return -1;
+
+ gSurface *surface = pixmap->surface;
+ if (!surface)
+ return -2;
+
png_structp png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
if (!png_ptr)
{
png_set_filter(png_ptr, 0, PNG_FILTER_NONE|PNG_FILTER_SUB|PNG_FILTER_PAETH);
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
- png_set_IHDR(png_ptr, info_ptr, pixmap->x, pixmap->y, pixmap->bpp,
- pixmap->clut.data ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_GRAY,
+ png_set_IHDR(png_ptr, info_ptr, surface->x, surface->y, surface->bpp,
+ surface->clut.data ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_GRAY,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
- if (pixmap->clut.data)
+ if (surface->clut.data)
{
- png_color palette[pixmap->clut.colors];
- png_byte trans[pixmap->clut.colors];
- for (int i=0; i<pixmap->clut.colors; ++i)
+ png_color palette[surface->clut.colors];
+ png_byte trans[surface->clut.colors];
+ for (int i=0; i<surface->clut.colors; ++i)
{
- palette[i].red=pixmap->clut.data[i].r;
- palette[i].green=pixmap->clut.data[i].g;
- palette[i].blue=pixmap->clut.data[i].b;
- trans[i]=255-pixmap->clut.data[i].a;
+ palette[i].red=surface->clut.data[i].r;
+ palette[i].green=surface->clut.data[i].g;
+ palette[i].blue=surface->clut.data[i].b;
+ trans[i]=255-surface->clut.data[i].a;
}
- png_set_PLTE(png_ptr, info_ptr, palette, pixmap->clut.colors);
- png_set_tRNS(png_ptr, info_ptr, trans, pixmap->clut.colors, 0);
+ png_set_PLTE(png_ptr, info_ptr, palette, surface->clut.colors);
+ png_set_tRNS(png_ptr, info_ptr, trans, surface->clut.colors, 0);
}
png_write_info(png_ptr, info_ptr);
png_set_packing(png_ptr);
- png_byte *row_pointers[pixmap->y];
- for (int i=0; i<pixmap->y; ++i)
- row_pointers[i]=((png_byte*)pixmap->data)+i*pixmap->stride;
+ png_byte *row_pointers[surface->y];
+ for (int i=0; i<surface->y; ++i)
+ row_pointers[i]=((png_byte*)surface->data)+i*surface->stride;
png_write_image(png_ptr, row_pointers);
png_write_end(png_ptr, info_ptr);
png_destroy_write_struct(&png_ptr, &info_ptr);
#include "grc.h"
-gImage *loadPNG(const char *filename);
+int loadPNG(ePtr<gPixmap> &pixmap, const char *filename);
int savePNG(const char *filename, gPixmap *pixmap);
#endif
class eRect // rectangle class
{
+ friend class gRegion;
public:
eRect() { x1 = y1 = x2 = y2 = 0; }
eRect( const ePoint &topleft, const ePoint &bottomright );
{
screeninfo.xres_virtual=screeninfo.xres=nxRes;
screeninfo.yres_virtual=screeninfo.yres=nyRes;
+ screeninfo.height=0;
+ screeninfo.width=0;
screeninfo.xoffset=screeninfo.yoffset=0;
screeninfo.bits_per_pixel=nbpp;
if (ioctl(fd, FBIOPUT_VSCREENINFO, &screeninfo)<0)
void fbClass::Box(int x, int y, int width, int height, int color, int backcolor)
{
- if (width<=2)
+ if (width<=2 || locked)
return;
int offset=y*stride+x/2;
int first=0xF0|((color&0xF0)>>4);
void fbClass::NBox(int x, int y, int width, int height, int color)
{
+ if (locked)
+ return;
int offset=y*stride+x/2;
int halfwidth=width/2;
for (int ay=y; ay<(y+height); ay++)
void fbClass::VLine(int x, int y, int sy, int color)
{
+ if (locked)
+ return;
int offset=y*stride+x/2;
while (sy--)
{
fb_cmap cmap;
__u16 red[256], green[256], blue[256], trans[256];
static fbClass *instance;
-
int locked;
public:
unsigned char *lfb;
int lock();
void unlock();
+ int islocked() { return locked; }
};
#endif
{
if (!instance)
return 0;
- Font *fnt = getFont( font.family.c_str(), font.pointSize);
+ ePtr<Font> fnt;
+ getFont(fnt, font.family.c_str(), font.pointSize);
if (!fnt)
return 0;
singleLock s(ftlock);
FT_Face current_face;
if (FTC_Manager_Lookup_Size(cacheManager, &fnt->font.font, ¤t_face, &fnt->size)<0)
{
+ delete fnt;
eDebug("FTC_Manager_Lookup_Size failed!");
return 0;
}
fontRenderClass::~fontRenderClass()
{
singleLock s(ftlock);
+ while(font)
+ {
+ fontListEntry *f=font;
+ font=font->next;
+ delete f;
+ }
// auskommentiert weil freetype und enigma die kritische masse des suckens ueberschreiten.
// FTC_Manager_Done(cacheManager);
// FT_Done_FreeType(library);
}
-Font *fontRenderClass::getFont(const eString &face, int size, int tabwidth)
+int fontRenderClass::getFont(ePtr<Font> &font, const eString &face, int size, int tabwidth)
{
FTC_FaceID id=getFaceID(face);
if (!id)
- return 0;
- return new Font(this, id, size * ((fontListEntry*)id)->scale / 100, tabwidth);
+ {
+ font = 0;
+ return -1;
+ }
+ font = new Font(this, id, size * ((fontListEntry*)id)->scale / 100, tabwidth);
+ return 0;
}
-Font::Font(fontRenderClass *render, FTC_FaceID faceid, int isize, int tw): tabwidth(tw)
+DEFINE_REF(Font);
+
+Font::Font(fontRenderClass *render, FTC_FaceID faceid, int isize, int tw): ref(0), tabwidth(tw)
{
renderer=render;
font.font.face_id=faceid;
{
}
-void Font::lock()
-{
- ref++;
-}
-
-void Font::unlock()
-{
- ref--;
- if (!ref)
- delete this;
-}
-
int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt glyphIndex, int flags, int rflags)
{
FTC_SBit glyph;
)
{
int cnt = 0;
- glyphString::iterator i(glyphs.end());
- --i;
- while (i != glyphs.begin())
+ glyphString::reverse_iterator i(glyphs.rbegin());
+ while (i != glyphs.rend())
{
if (i->flags&(GS_ISSPACE|GS_ISFIRST))
break;
cnt++;
- --i;
+ ++i;
}
- if (i != glyphs.begin() && ((i->flags&(GS_ISSPACE|GS_ISFIRST))==GS_ISSPACE) && (++i != glyphs.end())) // skip space
+ if (i != glyphs.rend()
+ && ((i->flags&(GS_ISSPACE|GS_ISFIRST))==GS_ISSPACE)
+ && cnt )
{
+ --i;
int linelength=cursor.x()-i->x;
i->flags|=GS_ISFIRST;
ePoint offset=ePoint(i->x, i->y);
newLine(rflags);
offset-=cursor;
- while (i != glyphs.end()) // rearrange them into the next line
+ do
{
i->x-=offset.x();
i->y-=offset.y();
i->bbox.moveBy(-offset.x(), -offset.y());
- ++i;
}
- cursor+=ePoint(linelength, 0); // put the cursor after that line
- } else
+ while (i-- != glyphs.rbegin()); // rearrange them into the next line
+ cursor+=ePoint(linelength, 0); // put the cursor after that line
+ }
+ else
{
- if (cnt)
+ if (cnt)
{
newLine(rflags);
flags|=GS_ISFIRST;
}
pGlyph ng;
-
- ng.bbox.setLeft( (flags&GS_ISFIRST|glyphs.empty()?cursor.x():cursor.x()-1) + glyph->left );
+ ng.bbox.setLeft( (flags&GS_ISFIRST|cursor.x()-1)+glyph->left );
ng.bbox.setTop( cursor.y() - glyph->top );
ng.bbox.setWidth( glyph->width );
ng.bbox.setHeight( glyph->height );
xadvance+=kern;
ng.x=cursor.x()+kern;
-
ng.y=cursor.y();
ng.w=xadvance;
ng.font=current_font;
- ng.font->lock();
ng.glyph_index=glyphIndex;
ng.flags=flags;
glyphs.push_back(ng);
boundBox.setBottom( -32000 );
// and grow the string bbox
- for ( glyphString::iterator i(glyphs.begin()); i != glyphs.end(); ++i)
+ for ( glyphString::iterator i(glyphs.begin()); i != glyphs.end(); ++i)
{
+ if ( i->flags & GS_ISSPACE )
+ continue;
if ( i->bbox.left() < boundBox.left() )
boundBox.setLeft( i->bbox.left() );
if ( i->bbox.top() < boundBox.top() )
boundBox.setBottom( i->bbox.bottom() );
}
// eDebug("boundBox left = %i, top = %i, right = %i, bottom = %i", boundBox.left(), boundBox.top(), boundBox.right(), boundBox.bottom() );
- bboxValid=1;
+ if ( glyphs.size() )
+ bboxValid=1;
}
void eTextPara::newLine(int flags)
return this;
}
-void eTextPara::setFont(const gFont &font)
+void eTextPara::setFont(const gFont *font)
{
if (refcnt)
eFatal("mod. after lock");
- Font *fnt=fontRenderClass::getInstance()->getFont(font.family.c_str(), font.pointSize);
+ ePtr<Font> fnt, replacement;
+ fontRenderClass::getInstance()->getFont(fnt, font->family.c_str(), font->pointSize);
if (!fnt)
- eWarning("FONT '%s' MISSING!", font.family.c_str());
- setFont(fnt,
- fontRenderClass::getInstance()->getFont(replacement_facename.c_str(), font.pointSize));
+ eWarning("FONT '%s' MISSING!", font->family.c_str());
+ fontRenderClass::getInstance()->getFont(replacement, replacement_facename.c_str(), font->pointSize);
+ setFont(fnt, replacement);
}
eString eTextPara::replacement_facename;
eFatal("mod. after lock");
if (!fnt)
return;
- if (current_font && !current_font->ref)
- delete current_font;
current_font=fnt;
replacement_font=replacement;
singleLock s(ftlock);
std::vector<unsigned long> uc_string, uc_visual;
uc_string.reserve(string.length());
- std::string::const_iterator p(string.begin());
+ eString::const_iterator p(string.begin());
while(p != string.end())
{
glyphs.reserve(uc_visual.size());
+ int nextflags = 0;
+
for (std::vector<unsigned long>::const_iterator i(uc_visual.begin());
i != uc_visual.end(); ++i)
{
int isprintable=1;
- int flags=0;
+ int flags = nextflags;
+ nextflags = 0;
if (!(rflags&RS_DIRECT))
{
switch (*i)
case '\n':
newline:isprintable=0;
newLine(rflags);
- flags|=GS_ISFIRST;
+ nextflags|=GS_ISFIRST;
break;
case '\r':
case 0x86: case 0xE086:
return 0;
}
-void eTextPara::blit(gPixmapDC &dc, const ePoint &offset, const gRGB &background, const gRGB &foreground)
+void eTextPara::blit(gDC &dc, const ePoint &offset, const gRGB &background, const gRGB &foreground)
{
singleLock s(ftlock);
ePtr<gPixmap> target;
dc.getPixmap(target);
+ gSurface *surface = target->surface;
register int opcode;
gColor *lookup8=0;
__u32 lookup32[16];
- if (target->bpp == 8)
+ if (surface->bpp == 8)
{
- if (target->clut.data)
+ if (surface->clut.data)
{
- lookup8=getColor(target->clut, background, foreground).lookup;
+ lookup8=getColor(surface->clut, background, foreground).lookup;
opcode=0;
} else
opcode=1;
- } else if (target->bpp == 32)
+ } else if (surface->bpp == 32)
{
opcode=3;
- if (target->clut.data)
+ if (surface->clut.data)
{
- lookup8=getColor(target->clut, background, foreground).lookup;
+ lookup8=getColor(surface->clut, background, foreground).lookup;
for (int i=0; i<16; ++i)
- lookup32[i]=((target->clut.data[lookup8[i]].a<<24)|
- (target->clut.data[lookup8[i]].r<<16)|
- (target->clut.data[lookup8[i]].g<<8)|
- (target->clut.data[lookup8[i]].b))^0xFF000000;
+ lookup32[i]=((surface->clut.data[lookup8[i]].a<<24)|
+ (surface->clut.data[lookup8[i]].r<<16)|
+ (surface->clut.data[lookup8[i]].g<<8)|
+ (surface->clut.data[lookup8[i]].b))^0xFF000000;
} else
{
for (int i=0; i<16; ++i)
}
} else
{
- eWarning("can't render to %dbpp", target->bpp);
+ eWarning("can't render to %dbpp", surface->bpp);
return;
}
- eRect clip(0, 0, target->x, target->y);
- clip&=dc.getClip();
+ gRegion area(eRect(0, 0, surface->x, surface->y));
+ gRegion clip;
+ clip.intersect(area, dc.getClip());
- int buffer_stride=target->stride;
+ int buffer_stride=surface->stride;
for (glyphString::iterator i(glyphs.begin()); i != glyphs.end(); ++i)
{
continue;
int rx=i->x+glyph_bitmap->left + offset.x();
int ry=i->y-glyph_bitmap->top + offset.y();
- __u8 *d=(__u8*)(target->data)+buffer_stride*ry+rx*target->bypp;
+ __u8 *d=(__u8*)(surface->data)+buffer_stride*ry+rx*surface->bypp;
__u8 *s=glyph_bitmap->buffer;
register int sx=glyph_bitmap->width;
int sy=glyph_bitmap->height;
- if ((sy+ry) >= clip.bottom())
- sy=clip.bottom()-ry;
- if ((sx+rx) >= clip.right())
- sx=clip.right()-rx;
- if (rx < clip.left())
+ if ((sy+ry) >= clip.extends.bottom())
+ sy=clip.extends.bottom()-ry;
+ if ((sx+rx) >= clip.extends.right())
+ sx=clip.extends.right()-rx;
+ if (rx < clip.extends.left())
{
- int diff=clip.left()-rx;
+ int diff=clip.extends.left()-rx;
s+=diff;
sx-=diff;
rx+=diff;
- d+=diff*target->bypp;
+ d+=diff*surface->bypp;
}
- if (ry < clip.top())
+ if (ry < clip.extends.top())
{
- int diff=clip.top()-ry;
+ int diff=clip.extends.top()-ry;
s+=diff*glyph_bitmap->pitch;
sy-=diff;
ry+=diff;
linelength+=c->w;
num++;
}
+
if (!num) // line mit nur einem space
continue;
{
singleLock s(ftlock);
- for (glyphString::iterator i(glyphs.begin()); i!=glyphs.end(); ++i)
- i->font->unlock();
+ current_font = 0;
+ replacement_font = 0;
glyphs.clear();
}
#ifndef __FONT_H
#define __FONT_H
-#include <freetype/freetype.h>
-#include <freetype/ftcache.h>
-#include <freetype/cache/ftcglyph.h>
-#include <freetype/cache/ftcimage.h>
-#include <freetype/cache/ftcmanag.h>
-#include <freetype/cache/ftcsbits.h>
-#include <freetype/cache/ftlru.h>
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_CACHE_H
+#include FT_CACHE_IMAGE_H
+#include FT_CACHE_SMALL_BITMAPS_H
#include <vector>
+
#include <lib/gdi/fb.h>
#include <lib/gdi/esize.h>
#include <lib/gdi/epoint.h>
#include <lib/gdi/erect.h>
#include <lib/base/estring.h>
+#include <lib/base/object.h>
class FontRenderClass;
class Font;
-class gPixmapDC;
+class gDC;
class gFont;
class gRGB;
static fontRenderClass *getInstance();
FT_Error FTC_Face_Requester(FTC_FaceID face_id,
FT_Face* aface);
- Font *getFont(const eString &face, int size, int tabwidth=-1);
+ int getFont(ePtr<Font> &font, const eString &face, int size, int tabwidth=-1);
fontRenderClass();
~fontRenderClass();
};
struct pGlyph
{
int x, y, w;
- Font *font;
+ ePtr<Font> font;
FT_ULong glyph_index;
int flags;
eRect bbox;
class Font;
class eLCD;
-class eTextPara
+class eTextPara: public iObject
{
- Font *current_font, *replacement_font;
+DECLARE_REF;
+private:
+ ePtr<Font> current_font, replacement_font;
FT_Face current_face, replacement_face;
int use_kerning;
int previous;
area(area), cursor(start), maximum(0, 0), left(start.x()), refcnt(0), bboxValid(0)
{
}
- ~eTextPara();
+ virtual ~eTextPara();
static void setReplacementFont(eString font) { replacement_facename=font; }
void destroy();
eTextPara *grab();
- void setFont(const gFont &font);
+ void setFont(const gFont *font);
int renderString(const eString &string, int flags=0);
void clear();
- void blit(gPixmapDC &dc, const ePoint &offset, const gRGB &background, const gRGB &foreground);
+ void blit(gDC &dc, const ePoint &offset, const gRGB &background, const gRGB &foreground);
enum
{
}
};
-class Font
+class Font: public iObject
{
+DECLARE_REF;
public:
FTC_Image_Desc font;
fontRenderClass *renderer;
- int ref;
FT_Error getGlyphBitmap(FT_ULong glyph_index, FTC_SBit *sbit);
FT_Face face;
FT_Size size;
int tabwidth;
int height;
Font(fontRenderClass *render, FTC_FaceID faceid, int isize, int tabwidth);
- ~Font();
-
- void lock();
- void unlock(); // deletes if ref==0
+ virtual ~Font();
};
extern fontRenderClass *font;
eFatal("no framebuffer available");
fb->SetMode(720, 576, 8);
+
for (int y=0; y<576; y++) // make whole screen transparent
memset(fb->lfb+y*fb->Stride(), 0x00, fb->Stride());
- pixmap=new gPixmap();
- pixmap->x=720;
- pixmap->y=576;
- pixmap->bpp=8;
- pixmap->bypp=1;
- pixmap->stride=fb->Stride();
- pixmap->data=fb->lfb;
+ surface.type = 0;
+ surface.x = 720;
+ surface.y = 576;
+ surface.bpp = 8;
+ surface.bypp = 1;
+ surface.stride = fb->Stride();
+ surface.data = fb->lfb;
+ surface.clut.colors=256;
+ surface.clut.data=new gRGB[surface.clut.colors];
+
+ m_pixmap = new gPixmap(&surface);
- pixmap->clut.colors=256;
- pixmap->clut.data=new gRGB[pixmap->clut.colors];
- memset(pixmap->clut.data, 0, sizeof(*pixmap->clut.data)*pixmap->clut.colors);
+ memset(surface.clut.data, 0, sizeof(*surface.clut.data)*surface.clut.colors);
reloadSettings();
}
gFBDC::~gFBDC()
{
- delete pixmap;
delete fb;
instance=0;
}
d=255;
ramp[i]=d;
-/* if ( eDVB::getInstance()->getmID == 1 )
- rampalpha[i]=i*alpha/65535;
- else*/
- rampalpha[i]=i*alpha/256;
+ rampalpha[i]=i*alpha/256;
}
rampalpha[255]=255; // transparent BLEIBT bitte so.
void gFBDC::setPalette()
{
- if (!pixmap->clut.data)
+ if (!surface.clut.data)
return;
for (int i=0; i<256; ++i)
{
- fb->CMAP()->red[i]=ramp[pixmap->clut.data[i].r]<<8;
- fb->CMAP()->green[i]=ramp[pixmap->clut.data[i].g]<<8;
- fb->CMAP()->blue[i]=ramp[pixmap->clut.data[i].b]<<8;
- fb->CMAP()->transp[i]=rampalpha[pixmap->clut.data[i].a]<<8;
+ fb->CMAP()->red[i]=ramp[surface.clut.data[i].r]<<8;
+ fb->CMAP()->green[i]=ramp[surface.clut.data[i].g]<<8;
+ fb->CMAP()->blue[i]=ramp[surface.clut.data[i].b]<<8;
+ fb->CMAP()->transp[i]=rampalpha[surface.clut.data[i].a]<<8;
if (!fb->CMAP()->red[i])
fb->CMAP()->red[i]=0x100;
}
{
case gOpcode::setPalette:
{
- gPixmapDC::exec(o);
+ gDC::exec(o);
setPalette();
break;
}
default:
- gPixmapDC::exec(o);
+ gDC::exec(o);
break;
}
}
setPalette();
}
-eAutoInitP0<gFBDC> init_gFBDC(eAutoInitNumbers::graphic+1, "GFBDC");
+eAutoInitP0<gFBDC> init_gFBDC(eAutoInitNumbers::graphic-1, "GFBDC");
#include "gpixmap.h"
#include "grc.h"
-class gFBDC: public gPixmapDC
+class gFBDC: public gDC
{
fbClass *fb;
static gFBDC *instance;
int brightness, gamma, alpha;
void calcRamp();
void setPalette();
+ gSurface surface;
public:
void reloadSettings();
void setAlpha(int alpha);
gFBDC();
~gFBDC();
static gFBDC *getInstance();
+ int islocked() { return fb->islocked(); }
};
#ifndef DISABLE_LCD
#include <lib/gdi/glcddc.h>
-#include <lib/gdi/lcd.h>
gLCDDC *gLCDDC::instance;
update=1;
- pixmap=new gPixmap();
- pixmap->x=lcd->size().width();
- pixmap->y=lcd->size().height();
- pixmap->bpp=8;
- pixmap->bypp=1;
- pixmap->stride=lcd->stride();
- pixmap->data=lcd->buffer();
-
- pixmap->clut.colors=256;
- pixmap->clut.data=0;
+ surface.x=lcd->size().width();
+ surface.y=lcd->size().height();
+ surface.bpp=8;
+ surface.bypp=1;
+ surface.stride=lcd->stride();
+ surface.data=lcd->buffer();
+
+ surface.clut.colors=256;
+ surface.clut.data=0;
+ m_pixmap = new gPixmap(&surface);
}
gLCDDC::~gLCDDC()
{
- delete pixmap;
instance=0;
}
{
switch (o->opcode)
{
- case gOpcode::flush:
+// case gOpcode::flush:
case gOpcode::end:
if (update)
lcd->update();
default:
- gPixmapDC::exec(o);
+ gDC::exec(o);
break;
}
}
#define __glcddc_h
#include "grc.h"
+#include <lib/gdi/lcd.h>
-class eLCD;
-
-class gLCDDC: public gPixmapDC
+class gLCDDC: public gDC
{
eLCD *lcd;
static gLCDDC *instance;
int update;
void exec(gOpcode *opcode);
+ gSurface surface;
public:
gLCDDC(eLCD *lcd);
~gLCDDC();
void setUpdate(int update);
static gLCDDC *getInstance();
+ int islocked() { return lcd->islocked(); }
};
#include <lib/gdi/gpixmap.h>
gLookup::gLookup()
+ :size(0), lookup(0)
{
- size=0;
- lookup=0;
}
gLookup::gLookup(int size, const gPalette &pal, const gRGB &start, const gRGB &end)
+ :size(0), lookup(0)
{
- size=0;
- lookup=0;
build(size, pal, start, end);
}
{
if (lookup)
{
- delete lookup;
+ delete [] lookup;
lookup=0;
size=0;
}
}
}
-DEFINE_REF(gPixmap);
+gSurface::~gSurface()
+{
+}
+
+gSurfaceSystem::gSurfaceSystem(eSize size, int _bpp)
+{
+ x=size.width();
+ y=size.height();
+ bpp=_bpp;
+ switch (bpp)
+ {
+ case 8:
+ bypp=1;
+ break;
+ case 15:
+ case 16:
+ bypp=2;
+ break;
+ case 24: // never use 24bit mode
+ case 32:
+ bypp=4;
+ break;
+ default:
+ bypp=(bpp+7)/8;
+ }
+ stride=x*bypp;
+ if (bpp==8)
+ {
+ clut.colors=256;
+ clut.data=new gRGB[clut.colors];
+ } else
+ {
+ clut.colors=0;
+ clut.data=0;
+ }
+ data=malloc(x*y*bypp);
+}
+
+gSurfaceSystem::~gSurfaceSystem()
+{
+ free(data);
+ delete[] clut.data;
+}
+
+gPixmap *gPixmap::lock()
+{
+ contentlock.lock(1);
+ return this;
+}
+
+void gPixmap::unlock()
+{
+ contentlock.unlock(1);
+}
void gPixmap::fill(const eRect &area, const gColor &color)
{
if ((area.height()<=0) || (area.width()<=0))
return;
- if (bpp == 8)
+ if (surface->bpp == 8)
for (int y=area.top(); y<area.bottom(); y++)
- memset(((__u8*)data)+y*stride+area.left(), color.color, area.width());
- else if (bpp == 32)
+ memset(((__u8*)surface->data)+y*surface->stride+area.left(), color.color, area.width());
+ else if (surface->bpp == 32)
for (int y=area.top(); y<area.bottom(); y++)
{
- __u32 *dst=(__u32*)(((__u8*)data)+y*stride+area.left()*bypp);
+ __u32 *dst=(__u32*)(((__u8*)surface->data)+y*surface->stride+area.left()*surface->bypp);
int x=area.width();
__u32 col;
- if (clut.data && color < clut.colors)
- col=(clut.data[color].a<<24)|(clut.data[color].r<<16)|(clut.data[color].g<<8)|(clut.data[color].b);
+ if (surface->clut.data && color < surface->clut.colors)
+ col=(surface->clut.data[color].a<<24)|(surface->clut.data[color].r<<16)|(surface->clut.data[color].g<<8)|(surface->clut.data[color].b);
else
col=0x10101*color;
col^=0xFF000000;
*dst++=col;
}
else
- eWarning("couldn't fill %d bpp", bpp);
+ eWarning("couldn't fill %d bpp", surface->bpp);
}
void gPixmap::blit(const gPixmap &src, ePoint pos, const eRect &clip, int flag)
{
-
eRect area=eRect(pos, src.getSize());
- if (!clip.isNull())
- area&=clip;
+ area&=clip;
area&=eRect(ePoint(0, 0), getSize());
if ((area.width()<0) || (area.height()<0))
return;
-
+
eRect srcarea=area;
srcarea.moveBy(-pos.x(), -pos.y());
- if ((bpp == 8) && (src.bpp==8))
+ if ((surface->bpp == 8) && (src.surface->bpp==8))
{
- __u8 *srcptr=(__u8*)src.data;
- __u8 *dstptr=(__u8*)data;
+ __u8 *srcptr=(__u8*)src.surface->data;
+ __u8 *dstptr=(__u8*)surface->data;
- srcptr+=srcarea.left()*bypp+srcarea.top()*src.stride;
- dstptr+=area.left()*bypp+area.top()*stride;
+ srcptr+=srcarea.left()*surface->bypp+srcarea.top()*src.surface->stride;
+ dstptr+=area.left()*surface->bypp+area.top()*surface->stride;
for (int y=0; y<area.height(); y++)
{
if (flag & blitAlphaTest)
*dst++=*src++;
}
} else
- memcpy(dstptr, srcptr, area.width()*bypp);
- srcptr+=src.stride;
- dstptr+=stride;
+ memcpy(dstptr, srcptr, area.width()*surface->bypp);
+ srcptr+=src.surface->stride;
+ dstptr+=surface->stride;
}
- } else if ((bpp == 32) && (src.bpp==8))
+ } else if ((surface->bpp == 32) && (src.surface->bpp==8))
{
- __u8 *srcptr=(__u8*)src.data;
- __u8 *dstptr=(__u8*)data; // !!
+ __u8 *srcptr=(__u8*)src.surface->data;
+ __u8 *dstptr=(__u8*)surface->data; // !!
__u32 pal[256];
for (int i=0; i<256; ++i)
{
- if (src.clut.data && (i<src.clut.colors))
- pal[i]=(src.clut.data[i].a<<24)|(src.clut.data[i].r<<16)|(src.clut.data[i].g<<8)|(src.clut.data[i].b);
+ if (src.surface->clut.data && (i<src.surface->clut.colors))
+ pal[i]=(src.surface->clut.data[i].a<<24)|(src.surface->clut.data[i].r<<16)|(src.surface->clut.data[i].g<<8)|(src.surface->clut.data[i].b);
else
pal[i]=0x010101*i;
pal[i]^=0xFF000000;
}
- srcptr+=srcarea.left()*bypp+srcarea.top()*src.stride;
- dstptr+=area.left()*bypp+area.top()*stride;
+ srcptr+=srcarea.left()*surface->bypp+srcarea.top()*src.surface->stride;
+ dstptr+=area.left()*surface->bypp+area.top()*surface->stride;
for (int y=0; y<area.height(); y++)
{
if (flag & blitAlphaTest)
while (width--)
*dst++=pal[*src++];
}
- srcptr+=src.stride;
- dstptr+=stride;
+ srcptr+=src.surface->stride;
+ dstptr+=surface->stride;
}
} else
- eFatal("cannot blit %dbpp from %dbpp", bpp, src.bpp);
+ eFatal("cannot blit %dbpp from %dbpp", surface->bpp, src.surface->bpp);
}
void gPixmap::mergePalette(const gPixmap &target)
{
- if ((!clut.colors) || (!target.clut.colors))
+ if ((!surface->clut.colors) || (!target.surface->clut.colors))
return;
- gColor *lookup=new gColor[clut.colors];
+ gColor *lookup=new gColor[surface->clut.colors];
- for (int i=0; i<clut.colors; i++)
- lookup[i].color=target.clut.findColor(clut.data[i]);
+ for (int i=0; i<surface->clut.colors; i++)
+ lookup[i].color=target.surface->clut.findColor(surface->clut.data[i]);
- delete clut.data;
- clut.colors=target.clut.colors;
- clut.data=new gRGB[clut.colors];
- memcpy(clut.data, target.clut.data, sizeof(gRGB)*clut.colors);
+ delete [] surface->clut.data;
+ surface->clut.colors=target.surface->clut.colors;
+ surface->clut.data=new gRGB[surface->clut.colors];
+ memcpy(surface->clut.data, target.surface->clut.data, sizeof(gRGB)*surface->clut.colors);
- __u8 *dstptr=(__u8*)data;
+ __u8 *dstptr=(__u8*)surface->data;
- for (int ay=0; ay<y; ay++)
+ for (int ay=0; ay<surface->y; ay++)
{
- for (int ax=0; ax<x; ax++)
+ for (int ax=0; ax<surface->x; ax++)
dstptr[ax]=lookup[dstptr[ax]];
- dstptr+=stride;
+ dstptr+=surface->stride;
}
- delete lookup;
+ delete [] lookup;
}
void gPixmap::line(ePoint start, ePoint dst, gColor color)
{
-int Ax=start.x(), // dieser code rult ganz ganz doll weil er ganz ganz fast ist und auch sehr gut dokumentiert is
-Ay=start.y(), Bx=dst.x(), // t. es handelt sich immerhin um den weltbekannten bresenham algorithmus der nicht nur
-By=dst.y(); int dX, dY, fbXincr, // sehr schnell ist sondern auch sehr gut dokumentiert und getestet wurde. nicht
-fbYincr, fbXYincr, dPr, dPru, P; __u8 // nur auf dem LCD der dbox, sondern auch ueberall anders. und auch auf der
-*AfbAddr = &((__u8*)data)[Ay*stride+Ax*bypp]; __u8 // dbox mit LCD soll das teil nun tun, und ich denke das tut es. ausse
-*BfbAddr = &((__u8*)data)[By*stride+Bx*bypp]; fbXincr= // rdem hat dieser algo den vorteil dass man fehler sehr leicht fi
-bypp; if ( (dX=Bx-Ax) >= 0) goto AFTERNEGX; dX=-dX; // ndet und beheben kann. das liegt nicht zuletzt an den komment
-fbXincr=-1; AFTERNEGX: fbYincr=stride; if ( (dY=By // aren. und ausserdem, je kuerzer der code, desto weniger k
--Ay) >= 0) goto AFTERNEGY; fbYincr=-stride; dY=-dY;AFTERNEGY: // ann daran falsch sein. erwaehnte ich schon, da
-fbXYincr = fbXincr+fbYincr; if (dY > dX) goto YisIndependent; dPr = dY+ // s dieser tolle code wahnsinnig schnell
-dY; P = -dX; dPru = P+P; dY = dX>>1; XLOOP: *AfbAddr=color; *BfbAddr=color; if ((P+=dPr) > 0) // ist? bye, tmbinc
+int Ax=start.x(),
+Ay=start.y(), Bx=dst.x(),
+By=dst.y(); int dX, dY, fbXincr,
+fbYincr, fbXYincr, dPr, dPru, P; __u8
+*AfbAddr = &((__u8*)surface->data)[Ay*surface->stride+Ax*surface->bypp]; __u8
+*BfbAddr = &((__u8*)surface->data)[By*surface->stride+Bx*surface->bypp]; fbXincr=
+surface->bypp; if ( (dX=Bx-Ax) >= 0) goto AFTERNEGX; dX=-dX;
+fbXincr=-1; AFTERNEGX: fbYincr=surface->stride; if ( (dY=By
+-Ay) >= 0) goto AFTERNEGY; fbYincr=-surface->stride; dY=-dY;AFTERNEGY:
+fbXYincr = fbXincr+fbYincr; if (dY > dX) goto YisIndependent; dPr = dY+
+dY; P = -dX; dPru = P+P; dY = dX>>1; XLOOP: *AfbAddr=color; *BfbAddr=color; if ((P+=dPr) > 0)
goto RightAndUp; AfbAddr+=fbXincr; BfbAddr-=fbXincr; if ((dY=dY-1) > 0) goto XLOOP; *AfbAddr=color; if ((dX & 1)
== 0) return; *BfbAddr=color; return; RightAndUp: AfbAddr+=fbXYincr; BfbAddr-=fbXYincr; P+=dPru; if ((dY=dY-1) >
0) goto XLOOP; *AfbAddr=color; if ((dX & 1) == 0) return; *BfbAddr=color; return; YisIndependent: dPr = dX+dX; P
= -dY; dPru = P+P; dX = dY>>1; YLOOP: *AfbAddr=color; *BfbAddr=color; if ((P+=dPr) > 0) goto RightAndUp2; AfbAddr
+=fbYincr; BfbAddr-=fbYincr; if ((dX=dX-1) > 0) goto YLOOP; *AfbAddr=color; if ((dY & 1) == 0) return; *BfbAddr=
color;return; RightAndUp2: AfbAddr+=fbXYincr; BfbAddr-=fbXYincr; P+=dPru; if ((dX=dX-1) > 0) goto YLOOP; *AfbAddr
-=color; if((dY & 1) == 0) return; *BfbAddr=color; return; // nun ist der tolle code leider zu ende. tut mir leid.
+=color; if((dY & 1) == 0) return; *BfbAddr=color; return;
}
gColor gPalette::findColor(const gRGB &rgb) const
return best_choice;
}
-gPixmap::gPixmap(): ref(0)
-{
-}
+DEFINE_REF(gPixmap);
gPixmap::~gPixmap()
{
}
-gImage::gImage(eSize size, int _bpp)
+gPixmap::gPixmap(gSurface *surface): surface(surface)
{
- x=size.width();
- y=size.height();
- bpp=_bpp;
- switch (bpp)
- {
- case 8:
- bypp=1;
- break;
- case 15:
- case 16:
- bypp=2;
- break;
- case 24: // never use 24bit mode
- case 32:
- bypp=4;
- break;
- default:
- bypp=(bpp+7)/8;
- }
- stride=x*bypp;
- if (bpp==8)
- {
- clut.colors=256;
- clut.data=new gRGB[clut.colors];
- } else
- {
- clut.colors=0;
- clut.data=0;
- }
- data=new char[x*y*bypp];
}
-gImage::~gImage()
+gPixmap::gPixmap(eSize size, int bpp)
{
- delete[] clut.data;
- delete[] (char*)data;
+ surface = new gSurfaceSystem(size, bpp);
}
+
#include <pthread.h>
#include <lib/base/estring.h>
+#include <lib/base/object.h>
+#include <lib/base/elock.h>
#include <lib/gdi/erect.h>
#include <lib/gdi/fb.h>
-#include <lib/base/elock.h>
-
-#include <lib/base/object.h>
struct gColor
{
gColor *lookup;
gLookup(int size, const gPalette &pal, const gRGB &start, const gRGB &end);
gLookup();
+ ~gLookup() { delete [] lookup; }
void build(int size, const gPalette &pal, const gRGB &start, const gRGB &end);
};
* The font is specified by a name and a size.
* \c gFont is part of the \ref gdi.
*/
-struct gFont
+class gFont: public virtual iObject
{
+DECLARE_REF;
+public:
+
eString family;
int pointSize;
{
}
- enum
+ virtual ~gFont()
{
- tRegular, tFixed
- };
-
- gFont(int type, int pointSize);
+ }
gFont()
:pointSize(0)
}
};
+struct gSurface
+{
+ int type;
+ int x, y, bpp, bypp, stride;
+ gPalette clut;
+
+ void *data;
+ virtual ~gSurface();
+};
+
+struct gSurfaceSystem: gSurface
+{
+ gSurfaceSystem(eSize size, int bpp);
+ ~gSurfaceSystem();
+};
+
struct gPixmap: public iObject
{
DECLARE_REF;
public:
- int x, y, bpp, bypp, stride;
- void *data;
+ gSurface *surface;
- gPalette clut;
+ eLock contentlock;
+ int final;
+
+ gPixmap *lock();
+ void unlock();
- eSize getSize() const { return eSize(x, y); }
+ eSize getSize() const { return eSize(surface->x, surface->y); }
void fill(const eRect &area, const gColor &color);
void mergePalette(const gPixmap &target);
void line(ePoint start, ePoint end, gColor color);
- gPixmap();
+ void finalLock();
+ gPixmap(gSurface *surface);
+ gPixmap(eSize, int bpp);
virtual ~gPixmap();
};
-struct gImage: gPixmap
-{
- gImage(eSize size, int bpp);
- ~gImage();
-};
-
#endif
#include <lib/gdi/grc.h>
#include <lib/gdi/font.h>
+#include <lib/gdi/lcd.h>
#include <lib/base/init.h>
#include <lib/base/init_num.h>
gRC *gRC::instance=0;
-gRC::gRC(): queuelock(MAXSIZE), queue(2048)
+gRC::gRC(): queue(2048), queuelock(MAXSIZE)
{
ASSERT(!instance);
instance=this;
gRC::~gRC()
{
+ fbClass::getInstance()->lock();
+#ifndef DISABLE_LCD
+ eDBoxLCD::getInstance()->lock();
+#endif
+ instance=0;
+
gOpcode o;
- o.dc=0;
o.opcode=gOpcode::shutdown;
submit(o);
- instance=0;
+ eDebug("waiting for gRC thread shutdown");
+ pthread_join(the_thread, 0);
+ eDebug("gRC thread has finished");
}
void *gRC::thread()
if (o.opcode==gOpcode::shutdown)
break;
o.dc->exec(&o);
+ o.dc->Release();
queue.dequeue();
}
#ifndef SYNC_PAINT
return 0;
}
-gRC &gRC::getInstance()
+gRC *gRC::getInstance()
{
- return *instance;
+ return instance;
}
static int gPainter_instances;
-gPainter::gPainter(gDC &dc, eRect rect): dc(dc), rc(gRC::getInstance()), foregroundColor(0), backgroundColor(0)
+gPainter::gPainter(gDC *dc, eRect rect): m_dc(dc), m_rc(gRC::getInstance())
{
- if (rect.isNull())
- rect=eRect(ePoint(0, 0), dc.getSize());
// ASSERT(!gPainter_instances);
gPainter_instances++;
begin(rect);
gPainter_instances--;
}
-void gPainter::begin(const eRect &rect)
-{
- gOpcode o;
- dc.lock();
- o.dc=&dc;
- o.opcode=gOpcode::begin;
- o.parm.begin=new gOpcode::para::pbegin(rect);
-// cliparea=std::stack<eRect, std::list<eRect> >();
- cliparea=std::stack<eRect>();
- cliparea.push(rect);
- setLogicalZero(cliparea.top().topLeft());
- rc.submit(o);
-}
-
void gPainter::setBackgroundColor(const gColor &color)
{
- backgroundColor=color;
+ gOpcode o;
+ o.opcode = gOpcode::setBackgroundColor;
+ o.dc = m_dc.grabRef();
+ o.parm.setColor = new gOpcode::para::psetColor;
+ o.parm.setColor->color = color;
+
+ m_rc->submit(o);
}
void gPainter::setForegroundColor(const gColor &color)
{
- foregroundColor=color;
+ gOpcode o;
+ o.opcode = gOpcode::setForegroundColor;
+ o.dc = m_dc.grabRef();
+ o.parm.setColor = new gOpcode::para::psetColor;
+ o.parm.setColor->color = color;
+
+ m_rc->submit(o);
}
-void gPainter::setFont(const gFont &mfont)
+void gPainter::setFont(gFont *font)
{
- font=mfont;
+ gOpcode o;
+ o.opcode = gOpcode::setFont;
+ o.dc = m_dc.grabRef();
+ font->AddRef();
+ o.parm.setFont = new gOpcode::para::psetFont;
+ o.parm.setFont->font = font;
+
+ m_rc->submit(o);
}
void gPainter::renderText(const eRect &pos, const std::string &string, int flags)
{
- eRect area=pos;
- area.moveBy(logicalZero.x(), logicalZero.y());
-
gOpcode o;
- o.dc=&dc;
o.opcode=gOpcode::renderText;
- o.parm.renderText=new gOpcode::para::prenderText(font, area, string, dc.getRGB(foregroundColor), dc.getRGB(backgroundColor));
- o.flags=flags;
- rc.submit(o);
+ o.dc = m_dc.grabRef();
+ o.parm.renderText = new gOpcode::para::prenderText;
+ o.parm.renderText->area = pos;
+ o.parm.renderText->text = string;
+ o.parm.renderText->flags = flags;
+ m_rc->submit(o);
}
-void gPainter::renderPara(eTextPara ¶, ePoint offset)
+void gPainter::renderPara(eTextPara *para, ePoint offset)
{
gOpcode o;
- o.dc=&dc;
o.opcode=gOpcode::renderPara;
- o.parm.renderPara=new gOpcode::para::prenderPara(logicalZero+offset, para.grab(), dc.getRGB(foregroundColor), dc.getRGB(backgroundColor));
- rc.submit(o);
+ o.dc = m_dc.grabRef();
+ o.parm.renderPara = new gOpcode::para::prenderPara;
+ o.parm.renderPara->offset = offset;
+
+ para->AddRef();
+ o.parm.renderPara->textpara = para;
+ m_rc->submit(o);
}
void gPainter::fill(const eRect &area)
{
gOpcode o;
- o.dc=&dc;
o.opcode=gOpcode::fill;
- eRect a=area;
- a.moveBy(logicalZero.x(), logicalZero.y());
- a&=cliparea.top();
-
- o.parm.fill=new gOpcode::para::pfill(a, foregroundColor);
- rc.submit(o);
+
+ o.dc = m_dc.grabRef();
+ o.parm.fill = new gOpcode::para::pfillRect;
+ o.parm.fill->area = area;
+ m_rc->submit(o);
}
void gPainter::clear()
{
gOpcode o;
- o.dc=&dc;
- o.opcode=gOpcode::fill;
- o.parm.fill=new gOpcode::para::pfill(cliparea.top(), backgroundColor);
- rc.submit(o);
+ o.opcode=gOpcode::clear;
+ o.dc = m_dc.grabRef();
+ o.parm.fill = new gOpcode::para::pfillRect;
+ o.parm.fill->area = eRect();
+ m_rc->submit(o);
+}
+
+void gPainter::blit(gPixmap *pixmap, ePoint pos, gRegion *clip, int flags)
+{
+ gOpcode o;
+
+ o.opcode=gOpcode::blit;
+ o.dc = m_dc.grabRef();
+ pixmap->AddRef();
+ o.parm.blit = new gOpcode::para::pblit;
+ o.parm.blit->pixmap = pixmap;
+ o.parm.blit->position = pos;
+ clip->AddRef();
+ o.parm.blit->clip = clip;
+ o.flags=flags;
+ m_rc->submit(o);
}
+
void gPainter::setPalette(gRGB *colors, int start, int len)
{
gOpcode o;
- o.dc=&dc;
o.opcode=gOpcode::setPalette;
+ o.dc = m_dc.grabRef();
gPalette *p=new gPalette;
p->data=new gRGB[len];
memcpy(p->data, colors, len*sizeof(gRGB));
p->start=start;
p->colors=len;
- o.parm.setPalette=new gOpcode::para::psetPalette(p);
- rc.submit(o);
+ o.parm.setPalette->palette = p;
+ m_rc->submit(o);
}
void gPainter::mergePalette(gPixmap *target)
{
gOpcode o;
- o.dc=&dc;
o.opcode=gOpcode::mergePalette;
- o.parm.mergePalette=new gOpcode::para::pmergePalette(target);
- rc.submit(o);
+ o.dc = m_dc.grabRef();
+ target->AddRef();
+ o.parm.mergePalette->target = target;
+ m_rc->submit(o);
}
void gPainter::line(ePoint start, ePoint end)
{
gOpcode o;
- o.dc=&dc;
o.opcode=gOpcode::line;
- o.parm.line=new gOpcode::para::pline(start+logicalZero, end+logicalZero, foregroundColor);
- rc.submit(o);
+ o.dc = m_dc.grabRef();
+ o.parm.line = new gOpcode::para::pline;
+ o.parm.line->start = start;
+ o.parm.line->end = end;
+ m_rc->submit(o);
}
-void gPainter::setLogicalZero(ePoint rel)
+void gPainter::setLogicalZero(ePoint val)
{
- logicalZero=rel;
+ gOpcode o;
+ o.opcode=gOpcode::setOffset;
+ o.dc = m_dc.grabRef();
+ o.parm.setOffset = new gOpcode::para::psetOffset;
+ o.parm.setOffset->rel = 0;
+ o.parm.setOffset->value = val;
+ m_rc->submit(o);
}
void gPainter::moveLogicalZero(ePoint rel)
{
- logicalZero+=rel;
+ gOpcode o;
+ o.opcode=gOpcode::moveOffset;
+ o.dc = m_dc.grabRef();
+ o.parm.setOffset = new gOpcode::para::psetOffset;
+ o.parm.setOffset->rel = 1;
+ o.parm.setOffset->value = rel;
+ m_rc->submit(o);
}
void gPainter::resetLogicalZero()
{
- logicalZero.setX(0);
- logicalZero.setY(0);
+ gOpcode o;
+ o.opcode=gOpcode::moveOffset;
+ o.dc = m_dc.grabRef();
+ o.parm.setOffset = new gOpcode::para::psetOffset;
+ o.parm.setOffset->value = ePoint(0, 0);
+ m_rc->submit(o);
}
-void gPainter::clip(eRect clip)
+void gPainter::clip(const gRegion ®ion)
{
gOpcode o;
- o.dc=&dc;
- o.opcode=gOpcode::clip;
- clip.moveBy(logicalZero.x(), logicalZero.y());
- cliparea.push(cliparea.top()&clip);
- o.parm.clip=new gOpcode::para::pclip(cliparea.top());
-
- rc.submit(o);
+ o.opcode = gOpcode::addClip;
+ o.dc = m_dc.grabRef();
+ o.parm.clip = new gOpcode::para::psetClip;
+ o.parm.clip->region = new gRegion(region);
+ o.parm.clip->region->AddRef();
+ m_rc->submit(o);
}
void gPainter::clippop()
{
- ASSERT (cliparea.size()>1);
gOpcode o;
- o.dc=&dc;
- o.opcode=gOpcode::clip;
- cliparea.pop();
- o.parm.clip=new gOpcode::para::pclip(cliparea.top());
- rc.submit(o);
+ o.opcode = gOpcode::popClip;
+ o.dc = m_dc.grabRef();
+ m_rc->submit(o);
}
void gPainter::flush()
{
- gOpcode o;
- o.dc=&dc;
- o.opcode=gOpcode::flush;
- rc.submit(o);
}
void gPainter::end()
{
- gOpcode o;
- o.dc=&dc;
- o.opcode=gOpcode::end;
- rc.submit(o);
-}
-
-gDC::~gDC()
-{
}
-gPixmapDC::gPixmapDC(): pixmap(0)
+gDC::gDC()
{
}
-gPixmapDC::gPixmapDC(gPixmap *pixmap): pixmap(pixmap)
+gDC::gDC(gPixmap *pixmap): m_pixmap(pixmap)
{
}
-gPixmapDC::~gPixmapDC()
+gDC::~gDC()
{
- dclock.lock();
}
-void gPixmapDC::exec(gOpcode *o)
+void gDC::exec(gOpcode *o)
{
+#if 0
switch(o->opcode)
{
- case gOpcode::begin:
- clip=o->parm.begin->area;
- delete o->parm.begin;
- break;
case gOpcode::renderText:
{
- eTextPara *para=new eTextPara(o->parm.renderText->area);
- para->setFont(o->parm.renderText->font);
- para->renderString(o->parm.renderText->text, o->flags);
- para->blit(*this, ePoint(0, 0), o->parm.renderText->backgroundColor, o->parm.renderText->foregroundColor);
- para->destroy();
- delete o->parm.renderText;
+ ePtr<eTextPara> para = new eTextPara(o->parm.renderText.area);
+ para->setFont(m_current_font);
+ para->renderString(*o->parm.renderText.text, o->parm.renderText.flags);
+ para->blit(*this, ePoint(0, 0), m_foregroundColor, m_backgroundColor);
+ delete o->parm.renderText->text;
break;
}
case gOpcode::renderPara:
{
- o->parm.renderPara->textpara->blit(*this, o->parm.renderPara->offset, o->parm.renderPara->backgroundColor, o->parm.renderPara->foregroundColor);
- o->parm.renderPara->textpara->destroy();
- delete o->parm.renderPara;
+ o->parm.renderPara.textpara->blit(*this, o->parm.renderPara.offset, m_foregroundColor, m_backgroundColor);
+ o->parm.renderPara.textpara.Release();
break;
}
case gOpcode::fill:
- pixmap->fill(o->parm.fill->area, o->parm.fill->color);
+ m_pixmap->fill(o->parm.fill.area, m_foregroundColor);
delete o->parm.fill;
break;
case gOpcode::blit:
{
- if (o->parm.blit->clip.isNull())
- o->parm.blit->clip=clip;
- else
- o->parm.blit->clip&=clip;
- pixmap->blit(*o->parm.blit->pixmap, o->parm.blit->position, o->parm.blit->clip, o->flags);
- delete o->parm.blit;
+ gRegion clip;
+ if (o->parm.blit.clip)
+ {
+ clip.intersect(o->parm.blit.clip, clip);
+ o->parm.blit.clip->Release();
+ } else
+ clip = m_current_clip;
+ pixmap->blit(*o->parm.blit.pixmap, o->parm.blit.pos, clip, o->parm.blit.flags);
+ o->parm.blit.pixmap->Release();
break;
}
case gOpcode::setPalette:
- if (o->parm.setPalette->palette->start>pixmap->clut.colors)
- o->parm.setPalette->palette->start=pixmap->clut.colors;
- if (o->parm.setPalette->palette->colors>(pixmap->clut.colors-o->parm.setPalette->palette->start))
- o->parm.setPalette->palette->colors=pixmap->clut.colors-o->parm.setPalette->palette->start;
+#if 0
+ if (o->parm.setPalette->palette->start>pixmap->surface->clut.colors)
+ o->parm.setPalette->palette->start=pixmap->surface->clut.colors;
+ if (o->parm.setPalette->palette->colors>(pixmap->surface->clut.colors-o->parm.setPalette->palette->start))
+ o->parm.setPalette->palette->colors=pixmap->surface->clut.colors-o->parm.setPalette->palette->start;
if (o->parm.setPalette->palette->colors)
- memcpy(pixmap->clut.data+o->parm.setPalette->palette->start, o->parm.setPalette->palette->data, o->parm.setPalette->palette->colors*sizeof(gRGB));
+ memcpy(pixmap->surface->clut.data+o->parm.setPalette->palette->start, o->parm.setPalette->palette->data, o->parm.setPalette->palette->colors*sizeof(gRGB));
delete[] o->parm.setPalette->palette->data;
delete o->parm.setPalette->palette;
delete o->parm.setPalette;
+#endif
break;
case gOpcode::mergePalette:
+#if 0
pixmap->mergePalette(*o->parm.blit->pixmap);
+ o->parm.blit->pixmap->unlock();
delete o->parm.blit;
+#endif
break;
case gOpcode::line:
+#if 0
pixmap->line(o->parm.line->start, o->parm.line->end, o->parm.line->color);
delete o->parm.line;
+#endif
break;
- case gOpcode::clip:
- clip=o->parm.clip->clip;
- delete o->parm.clip;
+ case gOpcode::setBackgroundColor:
+ m_backgroundColor = o->parm.setColor.color;
+ break;
+ case gOpcode::setForegroundColor:
+ m_foregroundColor = o->parm.setColor.color;
break;
- case gOpcode::end:
- unlock();
- case gOpcode::flush:
+ case gOpcode::clip:
break;
default:
eFatal("illegal opcode %d. expect memory leak!", o->opcode);
}
+#endif
}
-gRGB gPixmapDC::getRGB(gColor col)
+gRGB gDC::getRGB(gColor col)
{
- if ((!pixmap) || (!pixmap->clut.data))
+ if ((!m_pixmap) || (!m_pixmap->surface->clut.data))
return gRGB(col, col, col);
if (col<0)
{
eFatal("bla transp");
return gRGB(0, 0, 0, 0xFF);
}
- return pixmap->clut.data[col];
+ return m_pixmap->surface->clut.data[col];
}
+DEFINE_REF(gDC);
+
eAutoInitP0<gRC> init_grc(eAutoInitNumbers::graphic, "gRC");
#include <lib/base/estring.h>
#include <lib/base/ringbuffer.h>
-#include <lib/gdi/erect.h>
#include <lib/base/elock.h>
+#include <lib/gdi/erect.h>
#include <lib/gdi/gpixmap.h>
-
+#include <lib/gdi/region.h>
class eTextPara;
{
enum Opcode
{
- begin,
-
renderText,
renderPara,
+ setFont,
- fill,
+ fill, clear,
blit,
setPalette,
line,
- clip,
+ setBackgroundColor,
+ setForegroundColor,
+
+ setOffset, moveOffset,
- flush,
- end,
+ addClip, popClip,
- shutdown
+ end,shutdown
} opcode;
+ gDC *dc;
union para
{
- struct pbegin
+ struct pfillRect
{
eRect area;
- pbegin(const eRect &area): area(area) { }
- } *begin;
-
- struct pfill
- {
- eRect area;
- gColor color;
- pfill(const eRect &area, gColor color): area(area), color(color) { }
} *fill;
struct prenderText
{
- gFont font;
eRect area;
eString text;
- gRGB foregroundColor, backgroundColor;
- prenderText(const gFont &font, const eRect &area, const eString &text, const gRGB &foregroundColor, const gRGB &backgroundColor):
- font(font), area(area), text(text), foregroundColor(foregroundColor), backgroundColor(backgroundColor) { }
+ int flags;
} *renderText;
struct prenderPara
{
ePoint offset;
eTextPara *textpara;
- gRGB foregroundColor, backgroundColor;
- prenderPara(const ePoint &offset, eTextPara *textpara, const gRGB &foregroundColor, const gRGB &backgroundColor)
- : offset(offset), textpara(textpara), foregroundColor(foregroundColor), backgroundColor(backgroundColor) { }
} *renderPara;
+
+ struct psetFont
+ {
+ gFont *font;
+ } *setFont;
struct psetPalette
{
gPalette *palette;
- psetPalette(gPalette *palette): palette(palette) { }
} *setPalette;
struct pblit
{
- ePtr<gPixmap> pixmap;
+ gPixmap *pixmap;
ePoint position;
- eRect clip;
- pblit(gPixmap *pixmap, const ePoint &position, const eRect &clip)
- : pixmap(pixmap), position(position), clip(clip) { }
+ int flags;
+ gRegion *clip;
} *blit;
struct pmergePalette
{
- ePtr<gPixmap> target;
- pmergePalette(gPixmap *target): target(target) { }
+ gPixmap *target;
} *mergePalette;
struct pline
{
ePoint start, end;
- gColor color;
- pline(const ePoint &start, const ePoint &end, gColor color): start(start), end(end), color(color) { }
} *line;
- struct pclip
+ struct psetClip
{
- eRect clip;
- pclip(const eRect &clip): clip(clip) { }
+ gRegion *region;
} *clip;
+
+ struct psetColor
+ {
+ gColor color;
+ } *setColor;
+
+ struct psetOffset
+ {
+ ePoint value;
+ int rel;
+ } *setOffset;
} parm;
int flags;
-
- gDC *dc;
};
-class gRC
+ /* gRC is the singleton which controls the fifo and dispatches commands */
+class gRC: public virtual iObject
{
+DECLARE_REF;
+private:
static gRC *instance;
static void *thread_wrapper(void *ptr);
pthread_t the_thread;
void *thread();
-
- eLock queuelock;
-
+
queueRingBuffer<gOpcode> queue;
public:
+ eLock queuelock;
gRC();
virtual ~gRC();
static int collected=0;
queue.enqueue(o);
collected++;
- if (o.opcode==gOpcode::end)
+ if (o.opcode==gOpcode::end||o.opcode==gOpcode::shutdown)
{
queuelock.unlock(collected);
#ifdef SYNC_PAINT
}
}
- static gRC &getInstance();
+ static gRC *getInstance();
};
+ /* gPainter is the user frontend, which in turn sends commands through gRC */
class gPainter
{
- gDC &dc;
- gRC &rc;
+ ePtr<gDC> m_dc;
+ ePtr<gRC> m_rc;
friend class gRC;
gOpcode *beginptr;
- /* paint states */
-// std::stack<eRect, std::list<eRect> > cliparea;
- std::stack<eRect> cliparea;
- gFont font;
- gColor foregroundColor, backgroundColor;
- ePoint logicalZero;
void begin(const eRect &rect);
void end();
public:
- gPainter(gDC &dc, eRect rect=eRect());
+ gPainter(gDC *dc, eRect rect=eRect());
virtual ~gPainter();
void setBackgroundColor(const gColor &color);
void setForegroundColor(const gColor &color);
- void setFont(const gFont &font);
+ void setFont(gFont *font);
void renderText(const eRect &position, const std::string &string, int flags=0);
- void renderPara(eTextPara ¶, ePoint offset=ePoint(0, 0));
+ void renderPara(eTextPara *para, ePoint offset=ePoint(0, 0));
void fill(const eRect &area);
void clear();
- void gPainter::blit(gPixmap *pixmap, ePoint pos, eRect clip=eRect(), int flags=0)
- {
- gOpcode o;
- o.dc=&dc;
- o.opcode=gOpcode::blit;
- pos+=logicalZero;
- clip.moveBy(logicalZero.x(), logicalZero.y());
- o.parm.blit=new gOpcode::para::pblit(pixmap, pos, clip);
- o.flags=flags;
- rc.submit(o);
- }
+ void blit(gPixmap *pixmap, ePoint pos, gRegion *clip = 0, int flags=0);
void setPalette(gRGB *colors, int start=0, int len=256);
void mergePalette(gPixmap *target);
void moveLogicalZero(ePoint rel);
void resetLogicalZero();
- void clip(eRect clip);
+ void clip(const gRegion &clip);
void clippop();
void flush();
};
-class gDC
-{
-protected:
- eLock dclock;
-public:
- virtual void exec(gOpcode *opcode)=0;
- virtual RESULT getPixmap(ePtr<gPixmap> &)=0;
- virtual eSize getSize()=0;
- virtual const eRect &getClip()=0;
- virtual gRGB getRGB(gColor col)=0;
- virtual ~gDC();
- void lock() { dclock.lock(1); }
- void unlock() { dclock.unlock(1); }
-};
-
-class gPixmapDC: public gDC
+class gDC: public iObject
{
+DECLARE_REF;
protected:
- ePtr<gPixmap> pixmap;
- eRect clip;
+ ePtr<gPixmap> m_pixmap;
- void exec(gOpcode *opcode);
- gPixmapDC();
+ ePtr<gRegion> m_clip_region;
+ gColor m_foregroundColor, m_backgroundColor;
+ ePtr<gFont> m_current_font;
+ ePoint m_current_offset;
+ gRegion m_current_clip;
+
public:
- gPixmapDC(gPixmap *pixmap);
- virtual ~gPixmapDC();
- RESULT getPixmap(ePtr<gPixmap> &ptr) { ptr = pixmap; return 0; }
+ void exec(gOpcode *opcode);
+ gDC(gPixmap *pixmap);
+ gDC();
+ virtual ~gDC();
+ gRegion &getClip() { return *m_clip_region; }
+ int getPixmap(ePtr<gPixmap> &pm) { pm = m_pixmap; return 0; }
gRGB getRGB(gColor col);
- const eRect &getClip() { return clip; }
- virtual eSize getSize() { return eSize(pixmap->x, pixmap->y); }
+ virtual eSize getSize() { return m_pixmap->getSize(); }
};
#endif
#include <dbox/fp.h>
#include <dbox/lcd-ks0713.h>
-#include <lib/gdi/esize.h>
-#include <lib/base/init.h>
-#include <lib/base/init_num.h>
+#include <lib/base/esize.h>
+#include <lib/system/init.h>
+#include <lib/system/init_num.h>
#include <lib/gdi/glcddc.h>
-#include <lib/base/econfig.h>
+#include <lib/system/econfig.h>
eDBoxLCD *eDBoxLCD::instance;
void eLCD::unlock()
{
- read( lcdfd, NULL, 0);
- if ( errno == 9 )
- {
- eDebug("reopen lcd");
- lcdfd=open("/dev/dbox/lcd0", O_RDWR); // reopen device
- }
- else
- eDebug("do not reopen lcd.. errno = %d", errno);
+ read( lcdfd, NULL, 0);
+ if ( errno == 9 )
+ {
+ eDebug("reopen lcd");
+ lcdfd=open("/dev/dbox/lcd0", O_RDWR); // reopen device
+ }
+ else
+ eDebug("do not reopen lcd.. errno = %d", errno);
- locked=0;
+ locked=0;
}
/* void eLCD::line(ePoint start, ePoint dst, int color)
eDBoxLCD::~eDBoxLCD()
{
if (lcdfd>0)
+ {
close(lcdfd);
+ lcdfd=0;
+ }
}
eDBoxLCD *eDBoxLCD::getInstance()
void eDBoxLCD::update()
{
- if (!locked)
+ unsigned char raw[120*8];
+ int x, y, yy;
+ for (y=0; y<8; y++)
{
- unsigned char raw[120*8];
- int x, y, yy;
- for (y=0; y<8; y++)
+ for (x=0; x<120; x++)
{
- for (x=0; x<120; x++)
+ int pix=0;
+ for (yy=0; yy<8; yy++)
{
- int pix=0;
- for (yy=0; yy<8; yy++)
- {
- pix|=(_buffer[(y*8+yy)*128+x]>=108)<<yy;
- }
- raw[y*120+x]=(pix^inverted);
+ pix|=(_buffer[(y*8+yy)*128+x]>=108)<<yy;
}
+ raw[y*120+x]=(pix^inverted);
}
- if (lcdfd>0)
- write(lcdfd, raw, 120*8);
}
+ if (lcdfd>0)
+ write(lcdfd, raw, 120*8);
}
class eDBoxLCDHardware
eAutoInitP0<eDBoxLCDHardware> init_eDBoxLCDHardware(eAutoInitNumbers::lowlevel, "d-Box LCD Hardware");
#endif //DISABLE_LCD
+
#endif
public:
int lock();
void unlock();
+ int islocked() { return locked; }
eLCD(eSize size);
virtual ~eLCD();
--- /dev/null
+#include <lib/gdi/erect.h>
+#include <lib/gdi/epoint.h>
+#include <lib/gdi/region.h>
+
+#undef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#undef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+
+/*
+
+ Region code.
+
+ A region is basically a list of rectangles. In this implementation,
+ rectangles are ordered by their upper-left position, organized in bands.
+
+ this code stolen from miregion.c out of the X-Window system.
+ for implementation details, look into their source.
+ This code does all the ugly stuff.
+
+ Thanks go out to ryg, for explaining me this stuff.
+
+*/
+
+gRegion::gRegion(const eRect &rect) : extends(rect)
+{
+ rects.push_back(rect);
+}
+
+gRegion::gRegion()
+{
+}
+
+gRegion::~gRegion()
+{
+}
+
+int gRegion::do_coalesce(int prevStart, unsigned int curStart)
+{
+ // Figure out how many rectangles are in the band.
+ unsigned int numRects = curStart - prevStart;
+ assert(numRects == rects.size() - curStart);
+ if (!numRects)
+ return curStart;
+ std::vector<eRect>::iterator prevBox = rects.begin() + prevStart;
+ std::vector<eRect>::const_iterator curBox = rects.begin() + curStart;
+
+ // The bands may only be coalesced if the bottom of the previous
+ // matches the top scanline of the current.
+ if (prevBox->y2 != curBox->y1)
+ return curStart;
+
+ // Make sure the bands have boxes in the same places. This
+ // assumes that boxes have been added in such a way that they
+ // cover the most area possible. I.e. two boxes in a band must
+ // have some horizontal space between them.
+
+ int y2 = curBox->y2;
+
+ do {
+ if ((prevBox->x1 != curBox->x1) || (prevBox->x2 != curBox->x2))
+ return curStart;
+ prevBox++;
+ curBox++;
+ numRects--;
+ } while ( numRects );
+
+ // The bands may be merged, so set the bottom y of each box
+ // in the previous band to the bottom y of the current band.
+ numRects = curStart - prevStart;
+ rects.resize(rects.size() - numRects);
+ do {
+ prevBox--;
+ prevBox->y2 = y2;
+ numRects--;
+ } while (numRects);
+ return prevStart;
+}
+
+void gRegion::appendNonO(std::vector<eRect>::const_iterator r,
+ std::vector<eRect>::const_iterator rEnd, int y1, int y2)
+{
+ int newRects = rEnd - r;
+ assert(y1 < y2);
+ assert(newRects != 0);
+ rects.reserve(rects.size() + newRects);
+ do {
+ assert(r->x1 < r->x2);
+ rects.push_back(eRect(r->x1, y1, r->x2, y2));
+ r++;
+ } while (r != rEnd);
+}
+
+void gRegion::intersectO(
+ std::vector<eRect>::const_iterator r1,
+ std::vector<eRect>::const_iterator r1End,
+ std::vector<eRect>::const_iterator r2,
+ std::vector<eRect>::const_iterator r2End,
+ int y1, int y2,
+ int &overlap)
+{
+ int x1, x2;
+
+ assert(y1 < y2);
+ assert(r1 != r1End && r2 != r2End);
+
+ do {
+ x1 = max(r1->x1, r2->x1);
+ x2 = min(r1->x2, r2->x2);
+
+ if (x1 < x2)
+ rects.push_back(eRect(x1, y1, x2, y2));
+ if (r1->x2 == x2)
+ r1++;
+ if (r2->x2 == x2)
+ r2++;
+ } while ( (r1 != r1End) && (r2 != r2End));
+}
+
+void gRegion::subtractO(
+ std::vector<eRect>::const_iterator r1,
+ std::vector<eRect>::const_iterator r1End,
+ std::vector<eRect>::const_iterator r2,
+ std::vector<eRect>::const_iterator r2End,
+ int y1, int y2,
+ int &overlap)
+{
+ int x1;
+ x1 = r1->x1;
+
+ assert(y1<y2);
+ assert(r1 != r1End && r2 != r2End);
+
+ do {
+ if (r2->x2 <= x1)
+ ++r2;
+ else if (r2->x1 <= x1) {
+ x1 = r2->x2;
+ if (x1 >= r1->x2) {
+ ++r1;
+ if (r1 != r1End)
+ x1 = r1->x1;
+ } else
+ ++r2;
+ } else if (r2->x1 < r1->x2) {
+ assert(x1<r2->x1);
+ rects.push_back(eRect(x1, y1, r2->x1, y2));
+ x1 = r2->x2;
+ if (x1 >= r1->x2) {
+ ++r1;
+ if (r1 != r1End)
+ x1 = r1->x1;
+ } else
+ ++r2;
+ } else
+ {
+ if (r1->x2 > x1)
+ rects.push_back(eRect(x1, y1, r1->x2, y2));
+ ++r1;
+ if (r1 != r1End)
+ x1 = r1->x1;
+ }
+ } while ((r1 != r1End) && (r2 != r2End));
+ while (r1 != r1End)
+ {
+ assert(x1<r1->x2);
+ rects.push_back(eRect(x1, y1, r1->x2, y2));
+ ++r1;
+ if (r1 != r1End)
+ x1 = r1->x1;
+ }
+}
+
+#define MERGERECT(r) \
+{ \
+ if (r->x1 <= x2) { \
+ /* Merge with current rectangle */ \
+ if (r->x1 < x2) overlap = 1; \
+ if (x2 < r->x2) x2 = r->x2; \
+ } else { \
+ /* Add current rectangle, start new one */ \
+ rects.push_back(eRect(x1, y1, x2, y2)); \
+ x1 = r->x1; \
+ x2 = r->x2; \
+ } \
+ r++; \
+}
+
+void gRegion::mergeO(
+ std::vector<eRect>::const_iterator r1,
+ std::vector<eRect>::const_iterator r1End,
+ std::vector<eRect>::const_iterator r2,
+ std::vector<eRect>::const_iterator r2End,
+ int y1, int y2,
+ int &overlap)
+{
+ int x1, x2;
+
+ assert(y1 < y2);
+ assert(r1 != r1End && r2 != r2End);
+
+ if (r1->x1 < r2->x1)
+ {
+ x1 = r1->x1;
+ x2 = r1->x2;
+ ++r1;
+ } else {
+ x1 = r2->x1;
+ x2 = r2->x2;
+ ++r2;
+ }
+
+ while (r1 != r1End && r2 != r2End)
+ if (r1->x1 < r2->x1) MERGERECT(r1) else MERGERECT(r2);
+
+ if (r1 != r1End)
+ {
+ do {
+ MERGERECT(r1);
+ } while (r1 != r1End);
+ } else if (r2 != r2End)
+ {
+ do {
+ MERGERECT(r2);
+ } while (r2 != r2End);
+ }
+ rects.push_back(eRect(x1, y1, x2, y2));
+}
+
+void gRegion::regionOp(const gRegion ®1, const gRegion ®2, int opcode, int &overlap)
+{
+ std::vector<eRect>::const_iterator r1, r1End, r2, r2End, r1BandEnd, r2BandEnd;
+ int prevBand;
+ int r1y1, r2y1;
+ int curBand, ytop, top, bot;
+
+ r1 = reg1.rects.begin();
+ r1End = reg1.rects.end();
+ r2 = reg2.rects.begin();
+ r2End = reg2.rects.end();
+
+ int newSize = reg1.rects.size();
+ int numRects = reg2.rects.size();
+ assert(r1 != r1End);
+ assert(r2 != r2End);
+
+ if (numRects > newSize)
+ newSize = numRects;
+ newSize <<= 1;
+
+ rects.reserve(newSize);
+
+ int ybot = min(r1->y1, r2->y1);
+ prevBand = 0;
+ do {
+ assert(r1 != r1End);
+ assert(r2 != r2End);
+ FindBand(r1, r1BandEnd, r1End, r1y1);
+ FindBand(r2, r2BandEnd, r2End, r2y1);
+ if (r1y1 < r2y1) {
+ if (opcode & 1) {
+ top = max(r1y1, ybot);
+ bot = min(r1->y2, r2y1);
+ if (top != bot) {
+ curBand = rects.size();
+ appendNonO(r1, r1BandEnd, top, bot);
+ coalesce(prevBand, curBand);
+ }
+ }
+ ytop = r2y1;
+ } else if (r2y1 < r1y1) {
+ if (opcode & 2) {
+ top = max(r2y1, ybot);
+ bot = min(r2->y2, r1y1);
+ if (top != bot) {
+ curBand = rects.size();
+ appendNonO(r2, r2BandEnd, top, bot);
+ coalesce(prevBand, curBand);
+ }
+ }
+ ytop = r1y1;
+ } else
+ ytop = r1y1;
+ ybot = min(r1->y2, r2->y2);
+ if (ybot > ytop) {
+ curBand = rects.size();
+ switch (opcode)
+ {
+ case OP_INTERSECT:
+ intersectO(r1, r1BandEnd, r2, r2BandEnd, ytop, ybot, overlap);
+ break;
+ case OP_SUBTRACT:
+ subtractO(r1, r1BandEnd, r2, r2BandEnd, ytop, ybot, overlap);
+ break;
+ case OP_UNION:
+ mergeO(r1, r1BandEnd, r2, r2BandEnd, ytop, ybot, overlap);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ coalesce(prevBand, curBand);
+ }
+ if (r1->y2 == ybot) r1 = r1BandEnd;
+ if (r2->y2 == ybot) r2 = r2BandEnd;
+ } while (r1 != r1End && r2 != r2End);
+ if ((r1 != r1End) && (opcode & 1)) {
+ FindBand(r1, r1BandEnd, r1End, r1y1);
+ curBand = rects.size();
+ appendNonO(r1, r1BandEnd, max(r1y1, ybot), r1->y2);
+ coalesce(prevBand, curBand);
+ AppendRegions(r1BandEnd, r1End);
+ } else if ((r2 != r2End) && (opcode & 2)) {
+ FindBand(r2, r2BandEnd, r2End, r2y1);
+ curBand = rects.size();
+ appendNonO(r2, r2BandEnd, max(r2y1, ybot), r2->y2);
+ coalesce(prevBand, curBand);
+ AppendRegions(r2BandEnd, r2End);
+ }
+}
+
+void gRegion::intersect(const gRegion &r1, const gRegion &r2)
+{
+ int overlap;
+ // TODO: handle trivial reject
+ regionOp(r1, r2, OP_INTERSECT, overlap);
+}
+
+void gRegion::subtract(const gRegion &r1, const gRegion &r2)
+{
+ int overlap;
+ // TODO: handle trivial reject
+ regionOp(r1, r2, OP_SUBTRACT, overlap);
+}
+
+void gRegion::merge(const gRegion &r1, const gRegion &r2)
+{
+ int overlap;
+ // TODO: handle trivial reject
+ regionOp(r1, r2, OP_UNION, overlap);
+}
+
--- /dev/null
+#ifndef __lib_gdi_region_h
+#define __lib_gdi_region_h
+
+#include <lib/base/object.h>
+#include <vector>
+
+class gRegion: public virtual iObject
+{
+DECLARE_REF;
+private:
+ inline void FindBand(
+ std::vector<eRect>::const_iterator r,
+ std::vector<eRect>::const_iterator &rBandEnd,
+ std::vector<eRect>::const_iterator rEnd,
+ int &ry1)
+ {
+ ry1 = r->y1;
+ rBandEnd = r+1;
+ while ((rBandEnd != rEnd) && (rBandEnd->y1 == ry1))
+ rBandEnd++;
+ }
+
+ inline void AppendRegions(
+ std::vector<eRect>::const_iterator r,
+ std::vector<eRect>::const_iterator rEnd)
+ {
+ rects.insert(rects.end(), r, rEnd);
+ }
+
+ int do_coalesce(int prevStart, unsigned int curStart);
+ inline void coalesce(int &prevBand, unsigned int curBand)
+ {
+ if (curBand - prevBand == rects.size() - curBand) {
+ prevBand = do_coalesce(prevBand, curBand);
+ } else {
+ prevBand = curBand;
+ }
+ };
+ void appendNonO(std::vector<eRect>::const_iterator r,
+ std::vector<eRect>::const_iterator rEnd, int y1, int y2);
+
+ void intersectO(
+ std::vector<eRect>::const_iterator r1,
+ std::vector<eRect>::const_iterator r1End,
+ std::vector<eRect>::const_iterator r2,
+ std::vector<eRect>::const_iterator r2End,
+ int y1, int y2,
+ int &overlap);
+ void subtractO(
+ std::vector<eRect>::const_iterator r1,
+ std::vector<eRect>::const_iterator r1End,
+ std::vector<eRect>::const_iterator r2,
+ std::vector<eRect>::const_iterator r2End,
+ int y1, int y2,
+ int &overlap);
+ void mergeO(
+ std::vector<eRect>::const_iterator r1,
+ std::vector<eRect>::const_iterator r1End,
+ std::vector<eRect>::const_iterator r2,
+ std::vector<eRect>::const_iterator r2End,
+ int y1, int y2,
+ int &overlap);
+ void regionOp(const gRegion ®1, const gRegion ®2, int opcode, int &overlap);
+public:
+ std::vector<eRect> rects;
+ eRect extends;
+
+ enum
+ {
+ // note: bit 0 and bit 1 have special meanings
+ OP_INTERSECT = 0,
+ OP_SUBTRACT = 1,
+ OP_UNION = 3
+ };
+
+ gRegion(const eRect &rect);
+ gRegion();
+ virtual ~gRegion();
+
+ void intersect(const gRegion &r1, const gRegion &r2);
+ void subtract(const gRegion &r1, const gRegion &r2);
+ void merge(const gRegion &r1, const gRegion &r2);
+};
+
+#endif
-#include <lib/gui/echeckbox.h>
-
-#include <lib/gdi/font.h>
-#include <lib/base/init.h>
-#include <lib/base/init_num.h>
-#include <lib/gui/eskin.h>
-
-eCheckbox::eCheckbox(eWidget *parent, int checked, int takefocus, bool swapTxtPixmap, const char *deco)
- :eButton(parent, 0, takefocus, deco), swapTxtPixmap(swapTxtPixmap)
-{
- align=eTextPara::dirLeft;
- ischecked = -1;
- setCheck(checked);
- CONNECT(selected, eCheckbox::sel);
-}
-
-eCheckbox::~eCheckbox()
-{
-}
-
-void eCheckbox::sel()
-{
- setCheck(ischecked?0:1);
- /*emit*/ checked(ischecked);
-}
-
-void eCheckbox::gotFocus()
-{
-#ifndef DISABLE_LCD
- if (parent && parent->LCDElement)
- {
- LCDTmp = new eLabel(parent->LCDElement);
- LCDTmp->hide();
- eSize s = parent->LCDElement->getSize();
- LCDTmp->move(ePoint(0,0));
- LCDTmp->resize(eSize(s.width(), s.height()));
- ((eLabel*)LCDTmp)->setFlags(RS_WRAP);
- ePtr<gPixmap> pm;
- eSkin::getActive()->queryImage(pm, ischecked?"eCheckboxLCD.checked":"eCheckboxLCD.unchecked");
- LCDTmp->setPixmap(pm);
- ((eLabel*)LCDTmp)->pixmap_position=ePoint(0, (size.height()-15)/2);
- ((eLabel*)LCDTmp)->text_position=ePoint(21, 0);
- LCDTmp->setText(text);
- LCDTmp->show();
- }
-#endif
- setForegroundColor(focusF, false);
- setBackgroundColor(focusB);
-// invalidate();
-}
-
-void eCheckbox::lostFocus()
-{
-#ifndef DISABLE_LCD
- if (LCDTmp)
- {
- delete LCDTmp;
- LCDTmp = 0;
- }
-#endif
- eButton::lostFocus();
-}
-
-
-void eCheckbox::setCheck(int c)
-{
- if (ischecked != -1 && ischecked == c)
- return;
-
- ischecked=c;
-
- ePtr<gPixmap> pixmap;
- eSkin::getActive()->queryImage(pixmap, ischecked?"eCheckbox.checked":"eCheckbox.unchecked");
- setPixmap(pixmap);
-#ifndef DISABLE_LCD
- eSkin::getActive()->queryImage(pixmap, ischecked?"eCheckboxLCD.checked":"eCheckboxLCD.unchecked");
- if (LCDTmp)
- LCDTmp->setPixmap(pixmap);
-#endif
-}
-
-int eCheckbox::setProperty(const eString &prop, const eString &value)
-{
- if (prop=="swaptxtpixmap")
- {
- swapTxtPixmap = (value != "off");
- event( eWidgetEvent::changedSize );
- }
- else
- return eButton::setProperty(prop, value);
- return 0;
-}
-
-int eCheckbox::eventHandler(const eWidgetEvent &event)
-{
- switch (event.type)
- {
- case eWidgetEvent::changedSize:
- if (swapTxtPixmap)
- {
- text_position=ePoint(0,0);
- eLabel::invalidate();
- validate();
- pixmap_position=ePoint( para->getBoundBox().right()+5, (size.height()-pixmap->y) / 2 );
- }
- else
- {
- pixmap_position=ePoint(0, (size.height()-pixmap->y)/2);
- text_position=ePoint((int)(pixmap->x*1.25), 0);
- }
- //return eButton::eventHandler(event); // changed Size must seen by eLabel...
- break;
-
- default:
- return eButton::eventHandler(event);
- }
- return 1;
-}
-
-static eWidget *create_eCheckbox(eWidget *parent)
-{
- return new eCheckbox(parent);
-}
-
-class eCheckboxSkinInit
-{
-public:
- eCheckboxSkinInit()
- {
- eSkin::addWidgetCreator("eCheckbox", create_eCheckbox);
- }
- ~eCheckboxSkinInit()
- {
- eSkin::removeWidgetCreator("eCheckbox", create_eCheckbox);
- }
-};
-
-eAutoInitP0<eCheckboxSkinInit> init_eCheckboxSkinInit(eAutoInitNumbers::guiobject, "eCheckbox");
/* eDebug("decoStr = %s, text=%s, name=%s, %p left = %d, top = %d, width=%d, height = %d", strDeco?strDeco.c_str():"no", text?text.c_str():"no" , name?name.c_str():"no", this, this->getPosition().x(), this->getPosition().y(), this->getSize().width(), this->getSize().height() );
eDebug("renderContext left = %d, top = %d, width = %d, height = %d", rc.left(), rc.top(), rc.width(), rc.height() );*/
- target->clip( rc );
+ target->clip( gRegion(rc) );
eRect area=eRect(ePoint(0, 0), ePoint(width(), height()));
/* eDebug("area left = %d, top = %d, width = %d, height = %d",
area.left(), area.top(),
target->setBackgroundColor(w->getBackgroundColor());
}
target->setFont(font);
- target->renderPara(*para, ePoint( area.left(), area.top()+yOffs) );
+ target->renderPara(para, ePoint( area.left(), area.top()+yOffs) );
}
if (pixmap)
{
}
if (shortcutPixmap)
target->blit(shortcutPixmap,
- ePoint((area.height()-shortcutPixmap->x)/2, area.top()+(area.height()-shortcutPixmap->y)/2),
+ ePoint((area.height()-shortcutPixmap->getSize().width())/2, area.top()+(area.height()-shortcutPixmap->getSize().height())/2),
eRect(),
gPixmap::blitAlphaTest);
target->clippop();
gRGB *palette;
int maxcolors;
- ePtr<gImage> paldummy;
+ ePtr<gPixmap> paldummy;
int *colorused;
static std::map< eString, tWidgetCreator > widget_creator;
void parseSkins();
int build(eWidget *widget, const char *name);
- void setPalette(gPixmapDC *pal);
+ void setPalette(gPixmap *pal);
gColor queryColor(const eString &name);
gColor queryScheme(const eString &name) const;
-#ifndef __ewidget_h
-#define __ewidget_h
-
-#include <lib/base/ebase.h>
-#include <lib/base/estring.h>
-#include <lib/gdi/epoint.h>
-#include <lib/gdi/esize.h>
-#include <lib/gdi/erect.h>
-#include <lib/base/eptrlist.h>
-#include <libsig_comp.h>
-#include <lib/gdi/grc.h>
-#include <lib/driver/rc.h>
-#include <lib/gui/actions.h>
-
-class eWidgetEvent
-{
-public:
- enum eventType
- {
- evtKey,
- willShow, willHide,
- execBegin, execDone,
- gotFocus, lostFocus,
-
- changedText, changedFont, changedForegroundColor, changedBackgroundColor,
- changedSize, changedPosition, changedPixmap, childChangedHelpText,
-
- evtAction, evtShortcut
- } type;
- union
- {
- int parameter;
- const eAction *action;
- const eRCKey *key;
- };
- eWidgetEvent(eventType type, int parameter=0): type(type), parameter(parameter) { }
- eWidgetEvent(eventType type, const eAction *action): type(type), action(action) { }
- eWidgetEvent(eventType type, const eRCKey &key): type(type), key(&key) { }
-
- /**
- * \brief Event should be delivered to the focused widget.
- *
- * \return true if the event should be delivered to the focused widget instead of the widget itself.
- */
- int toFocus() const
- {
- switch (type)
- {
- case evtKey:
- return 1;
- default:
- return 0;
- }
- }
-};
-
-/** \brief The main widget class. All widgets inherit this class.
- * eWidget handles focus management.
- */
-class eWidget: public Object
-{
- enum
- {
- /// Widget was shown with show() or implicit show()
- stateShow=1,
- /// Widget is visible on screen. Implies stateShow.
- stateVisible=2
- };
-
-public:
- /**
- * \brief Exits a (model) widget.
- *
- * Quit the local event loop, thus returning the control to the function which called \a exec.
- * \sa eWidget::accept
- * \sa eWidget::reject
- */
- void close(int result);
-
- /**
- * \brief Closes with a returncode of 0 (success).
- *
- * Synonym to \a close(0);. Useful to use as a slot.
- * \sa eWidget::close
- */
- void accept();
-
- /**
- * \brief Closes with a returncode of -1 (failure).
- *
- * Synonym to \a close(-1);. Useful to use as a slot.
- * \sa eWidget::close
- */
- void reject();
- /**
- * \brief Signal is send, when the focus Changed
- *
- * used from a existing statusbar.
- * \sa eWidget::focusChanged
- */
- Signal1<void, const eWidget*> focusChanged;
- static Signal2< void, ePtrList<eAction>*, int > showHelp;
-protected:
- ePtrList<eAction> actionHelpList;
- int helpID;
- ePtrList<eWidget> childlist;
- static eWidget *root;
- eWidget *parent;
- eString name;
- eString helptext;
- ePoint position;
- ePoint absPosition;
- eSize size;
- eRect clientrect;
- eRect clientclip;
-
- eAction *shortcut;
- eWidget *shortcutFocusWidget;
-
- ePtrList<eWidget> _focusList;
-
- ePtrList<eWidget> actionListener;
- eWidget *focus, *TLW;
-
- /// old top-level focus
- eWidget *oldTLfocus;
- int takefocus;
- int state;
-
- gDC *target;
-
- inline eWidget *getTLW() // pseudoTLW !!
- {
- return TLW ? TLW : (TLW = (parent && parent->parent) ? parent->getTLW() : this );
- }
- int result, in_loop, have_focus, just_showing;
- void takeFocus();
- void releaseFocus();
-
- void _willShow();
- void _willHide();
-
- virtual void willShow();
- virtual void willHide();
-
- virtual void setPalette();
-
- void willShowChildren();
- void willHideChildren();
-
- /**
- * \brief Hi priority event filter.
- *
- * This event filter is called before the event is delivered via \a event.
- * \return 1 if the event should NOT be forwarded.
- */
- virtual int eventFilter(const eWidgetEvent &event);
-
- /**
- * \brief Handles an event.
- *
- * If re-implemented in a widget-sub-class, \c eWidget::event should be called whenever the event is
- * not processed by the widget.
- * \return 1 if the event was processed, 0 if ignored. it might be forwarded to other widgets then.
- */
-
- virtual int keyDown(int rc);
- virtual int keyUp(int rc);
-
- virtual void gotFocus();
- virtual void lostFocus();
-
- virtual void recalcClientRect();
- void recalcClip();
- void checkFocus();
-
- typedef ePtrList<eActionMap> actionMapList;
-
- void findAction(eActionPrioritySet &prio, const eRCKey &key, eWidget *context);
- void addActionMap(eActionMap *map);
- void removeActionMap(eActionMap *map);
- actionMapList actionmaps;
- static actionMapList globalActions;
-
- // generic properties
- gFont font;
- eString text;
- gColor backgroundColor, foregroundColor;
-
- ePtr<gPixmap> pixmap;
-
- eString descr;
-
-public:
- virtual int eventHandler(const eWidgetEvent &event);
- static void addGlobalActionMap(eActionMap *map);
- static void removeGlobalActionMap(eActionMap *map);
- inline eWidget *getNonTransparentBackground()
- {
- if (backgroundColor >= 0)
- return this;
- return parent?parent->getNonTransparentBackground():this;
- }
-
-#ifndef DISABLE_LCD
- eWidget *LCDTitle;
- eWidget *LCDElement;
- eWidget *LCDTmp;
-#endif
-
- void recalcAbsolutePosition();
-
- inline const ePoint &getAbsolutePosition() const
- {
- return absPosition;
- }
-
- inline ePoint getRelativePosition(eWidget *e) const
- {
- ePoint pos=position;
- if (this != e)
- for (eWidget *a=parent; a && (a != e); a=a->parent)
- pos+=a->clientrect.topLeft();
- return pos;
- }
-
- virtual void redrawWidget(gPainter *target, const eRect &area);
-
- virtual void eraseBackground(gPainter *target, const eRect &area);
-
- /**
- * \brief Constructs a new eWidget.
- * \param parent The parent widget. The widget gets automatically removed when the parent gets removed.
- * \param takefocus Specifies if the widget should be appended to the focus list of the TLW, i.e. if it can
- receive keys.
- */
- eWidget(eWidget *parent=0, int takefocus=0);
-
- /**
- * \brief Destructs an eWidget and all its childs.
- *
- * hide() is called when the widget is shown. The set ePixmap is \e not
- * freed. If the widget acquired focus, it will be removed from the focuslist.
- * \sa eWidget::setPixmap
- */
- virtual ~eWidget();
-
- /**
- * \brief Returns a pointer to the focus list.
- *
- * The focus list is the list of childs which have the \c takefocus flag set.
- * This list is only maintained for TLWs.
- */
- ePtrList<eWidget> *focusList() { return &_focusList; }
-
- /**
- * \brief Resizes the widget.
- *
- * Sets the size of the widget to the given size. The event \c changedSize event will be generated.
- * \param size The new size, relative to the position.
- */
- void resize(const eSize& size);
-
- /**
- * \brief Resizes clientrect (and the widget).
- *
- * Sets the clientrect of the widget to the given size. The real size of the widget will be set to met
- * these requirement. The event \c changedSize event will be generated.
- * \param size The new size of the clientrect, relative to the position.
- */
- void cresize(const eSize& size);
-
- /**
- * \brief Moves the widget.
- *
- * Set the new position of the widget to the given position. The \c changedPosition event will be generated.
- * \param position The new position, relative to the parent's \c clientrect.
- */
- void move(const ePoint& position);
-
- /**
- * \brief Moves the clientrect (and the widget).
- *
- * Set the new position of the clientrect to the given position. The \c changedPosition event will be generated.
- * \param position The new position, relative to the parent's \c clientrect.
- */
- void cmove(const ePoint& position);
-
- /**
- * \brief Returns the current size.
- *
- * \return Current size of the widget, relative to the position.
- */
- const eSize& getSize() const { return size; }
-
- /**
- * \brief Returns the current position.
- *
- * \return Current position, relative to the parent's \c clientrect.
- */
- const ePoint& getPosition() const { return position; }
-
- /**
- * \brief Returns the size of the clientrect.
- *
- * \return The usable size for the childwidgets.
- */
- eSize getClientSize() const { return clientrect.size(); }
-
- /**
- * \brief Returns the clientrect.
- *
- * \return The area usable for the childwidgets.
- */
- const eRect& getClientRect() const { return clientrect; }
-
- /**
- * \brief Recursive redraw of a widget.
- *
- * All client windows get repaint too, but no widgets above. Unless you have a good reason, you shouldn't
- * use this function and use \c invalidate().
- * \param area The area which should be repaint. The default is to repaint the whole widget.
- * \sa eWidget::invalidate
- */
- void redraw(eRect area=eRect());
-
- /**
- * \brief Recursive (complete) redraw of a widget.
- *
- * Redraws the widget including background. This is the function to use if you want to manually redraw something!
- * \param area The area which should be repaint. The default is to repaint the whole widget.
- * \param force Forces a parent-invalidate even on non-visible widgets. Shouldn't be used outside eWidget.
- * \sa eWidget::redraw
- */
- void invalidate(eRect area=eRect(), int force=0);
-
- /**
- * \brief Enters modal message loop.
- *
- * A new event loop will be launched. The function returns when \a close is called.
- * \return The argument of \a close.
- * \sa eWidget::close
- */
- int exec();
-
- /**
- * \brief Visually clears the widget.
- *
- * Clears the widget. This is done on \a hide().
- * \sa eWidget::hide
- */
- void clear();
-
- /**
- * \brief Delivers a widget-event.
- *
- * Internally calles \a eventFilter, then \a eventHandler() (in some cases of the focused widget)
- * \param event The event to deliver.
- */
- int event(const eWidgetEvent &event);
-
- /**
- * \brief Shows the widget.
- *
- * If necessary, the widget will be linked into the TLW's active focus list. The widget will
- * visually appear.
- * \sa eWidget::hide
- */
- void show();
-
- /**
- * \brief Hides the widget.
- *
- * The widget will be removed from the screen. All childs will be hidden too.
- * \sa eWidget::show
- */
- void hide();
-
- /**
- * \brief Returns if the widget is vissible.
- *
- * \return If the widget and all parents are visible, \c true is returned, else false.
- */
- int isVisible() { return (state&stateVisible) && ( (!parent) || parent->isVisible() ); }
-
- /**
- * \brief Possible focus directions.
- */
- enum focusDirection
- {
- focusDirNext, focusDirPrev, focusDirN, focusDirE, focusDirS, focusDirW
- };
-
- /**
- * \brief changes the focused widget.
- *
- * Focuses the next or previous widget of the \c focuslist. An \c gotFocus and \c lostFocus event will be
- * generated.
- * \param dir The direction, \c focusDirection.
- */
- void focusNext(int dir=0);
-
- /**
- * \brief Gives focus to a widget.
- *
- * Set the focus to the specified widget. The \c focuslist is updated, too.
- * An \c gotFocus and \c lostFocus event will be generated.
- * \param newfocus The new widget to focus.
- */
- void setFocus(eWidget *newfocus);
-
- /**
- * \brief Sets the widget font.
- *
- * The font is used for example by the \c eLabel.
- * \sa eLabel
- * \param font The new font used by widget-specific drawing code.
- */
- void setFont(const gFont &font);
-
- /**
- * \brief Sets the widget caption or text.
- *
- * \param label The text to assign to the widget.
- */
- void setText(const eString &label);
-
- const eString& getText() const { return text; }
- void setBackgroundColor(const gColor& color, bool inv=true);
- void setForegroundColor(const gColor& color, bool inv=true);
- void setPixmap(gPixmap *pmap);
- void setTarget(gDC *target);
- gDC *getTarget() { return target; }
-
-#ifndef DISABLE_LCD
- void setLCD(eWidget *lcdtitle, eWidget *lcdelement);
-#endif
-
- void setName(const char *name);
- const eString& getName() const { return name; }
- eWidget*& getParent() { return parent; }
- const gFont& getFont() const { return font; }
-
- const gColor& getBackgroundColor() const { return backgroundColor; }
- const gColor& getForegroundColor() const { return foregroundColor; }
-
- int width() { return getSize().width(); }
- int height() { return getSize().height(); }
-
- gPainter *getPainter(eRect area);
-
- const eString& getHelpText() const { return helptext; }
-
- void setHelpText( const eString&);
- /**
- * \brief Sets a property.
- *
- * A property is a value/data pair which is used for serializing widgets (like in skinfiles).
- * These properties are available to all \c "eWidget"-based classes.
- * \arg \c position, the position of the widget, relative to the parent's childarea. Consider using csize for TLWs.
- * Positions are specified in a "x:y" manner.
- * \arg \c cposition, the position of the widget's clientrect (upper left).
- * This is useful for specifing a position independant of a decoration which might be
- * different sized. The real position will be calculated to match the requested position.
- * \arg \c size, the size of the widget. Consider using csize for TLWs. Sizes are specified in a "width:height" manner.
- * \arg \c csize, the size of the clientrect. The real size will be calculated to match the requested size.
- * \arg \c text, the text/caption of the widget.
- * \arg \c font, the primary font used in the widget.
- * \arg \c name, the name of the widget for referring them.
- * \arg \c pixmap, an already loaded, named pixmap to be used as the widget's pixmap.
- * \arg \c foregroundColor, a named color, which will be used for the widget's foreground color.
- * \arg \c backgroundColor
- * \param prop The property to be set.
- * \param value The value to be set.
- */
- virtual int setProperty(const eString &prop, const eString &value);
-
- eWidget *search(const eString &name);
-
- eWidget* getFocus() { return focus; }
-
- void makeRoot();
-
- void zOrderLower();
- void zOrderRaise();
-
- /**
- * \brief sets the shortcut (generate evtShortcut)
- */
- void setShortcut(const eString &shortcut);
- void setShortcutFocus(eWidget *focus);
-
- void addActionToHelpList(eAction *action);
- void clearHelpList();
- void setHelpID(int fHelpID);
-};
-
-#endif