From: Felix Domke Date: Thu, 27 May 2004 22:30:21 +0000 (+0000) Subject: yes! ich habs kaputt gemacht! (doesn't compile anymore, doesn't work anymore, X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=commitdiff_plain;h=d6f6602d7cea3a7899990fe79216af7d98d05917 yes! ich habs kaputt gemacht! (doesn't compile anymore, doesn't work anymore, lots of work required). --- diff --git a/lib/base/smartptr.h b/lib/base/smartptr.h index c89763e..85ad5a9 100644 --- a/lib/base/smartptr.h +++ b/lib/base/smartptr.h @@ -66,6 +66,8 @@ public: if (ptr) ptr->Release(); } + + T* grabRef() { if (!ptr) return 0; ptr->AddRef(); return ptr; } T* &ptrref() { assert(!ptr); return ptr; } ePtrHelper operator->() { assert(ptr); return ePtrHelper(ptr); } diff --git a/lib/gdi/Makefile.am b/lib/gdi/Makefile.am index eff43b0..49459b6 100644 --- a/lib/gdi/Makefile.am +++ b/lib/gdi/Makefile.am @@ -4,5 +4,5 @@ INCLUDES = \ 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 diff --git a/lib/gdi/epng.cpp b/lib/gdi/epng.cpp index d476ec3..0d1072f 100644 --- a/lib/gdi/epng.cpp +++ b/lib/gdi/epng.cpp @@ -3,13 +3,11 @@ #include #include -gImage *loadPNG(const char *filename) +int loadPNG(ePtr &result, const char *filename) { __u8 header[8]; FILE *fp=fopen(filename, "rb"); - gImage *res=0; - if (!fp) { // eDebug("couldn't open %s", filename ); @@ -54,8 +52,7 @@ gImage *loadPNG(const char *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); @@ -73,15 +70,16 @@ gImage *loadPNG(const char *filename) 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; idata))+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)) { @@ -89,37 +87,37 @@ gImage *loadPNG(const char *filename) 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; iclut.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; iclut.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) @@ -127,6 +125,11 @@ 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) { @@ -156,28 +159,28 @@ int savePNG(const char *filename, gPixmap *pixmap) 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; iclut.colors; ++i) + png_color palette[surface->clut.colors]; + png_byte trans[surface->clut.colors]; + for (int i=0; iclut.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; iy; ++i) - row_pointers[i]=((png_byte*)pixmap->data)+i*pixmap->stride; + png_byte *row_pointers[surface->y]; + for (int i=0; iy; ++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); diff --git a/lib/gdi/epng.h b/lib/gdi/epng.h index 650c251..244019f 100644 --- a/lib/gdi/epng.h +++ b/lib/gdi/epng.h @@ -3,7 +3,7 @@ #include "grc.h" -gImage *loadPNG(const char *filename); +int loadPNG(ePtr &pixmap, const char *filename); int savePNG(const char *filename, gPixmap *pixmap); #endif diff --git a/lib/gdi/erect.h b/lib/gdi/erect.h index c41d831..30db41f 100644 --- a/lib/gdi/erect.h +++ b/lib/gdi/erect.h @@ -9,6 +9,7 @@ class eRect // rectangle class { + friend class gRegion; public: eRect() { x1 = y1 = x2 = y2 = 0; } eRect( const ePoint &topleft, const ePoint &bottomright ); diff --git a/lib/gdi/fb.cpp b/lib/gdi/fb.cpp index 96ca431..52d950a 100644 --- a/lib/gdi/fb.cpp +++ b/lib/gdi/fb.cpp @@ -88,6 +88,8 @@ int fbClass::SetMode(unsigned int nxRes, unsigned int nyRes, unsigned int nbpp) { 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) @@ -131,7 +133,7 @@ int fbClass::PutCMAP() 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); @@ -149,6 +151,8 @@ void fbClass::Box(int x, int y, int width, int height, int color, int backcolor) 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++) @@ -160,6 +164,8 @@ void fbClass::NBox(int x, int y, int width, int height, int color) void fbClass::VLine(int x, int y, int sy, int color) { + if (locked) + return; int offset=y*stride+x/2; while (sy--) { diff --git a/lib/gdi/fb.h b/lib/gdi/fb.h index d0ad6fe..ab80166 100644 --- a/lib/gdi/fb.h +++ b/lib/gdi/fb.h @@ -13,7 +13,6 @@ class fbClass fb_cmap cmap; __u16 red[256], green[256], blue[256], trans[256]; static fbClass *instance; - int locked; public: unsigned char *lfb; @@ -38,6 +37,7 @@ public: int lock(); void unlock(); + int islocked() { return locked; } }; #endif diff --git a/lib/gdi/font.cpp b/lib/gdi/font.cpp index e7a0074..a0b6d2e 100644 --- a/lib/gdi/font.cpp +++ b/lib/gdi/font.cpp @@ -192,13 +192,15 @@ float fontRenderClass::getLineHeight(const gFont& font) { if (!instance) return 0; - Font *fnt = getFont( font.family.c_str(), font.pointSize); + ePtr 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; } @@ -212,20 +214,32 @@ float fontRenderClass::getLineHeight(const gFont& font) 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, 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; @@ -248,18 +262,6 @@ Font::~Font() { } -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; @@ -276,33 +278,36 @@ int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt gly ) { 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; @@ -320,8 +325,7 @@ int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt gly } 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 ); @@ -329,11 +333,9 @@ int eTextPara::appendGlyph(Font *current_font, FT_Face current_face, FT_UInt gly 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); @@ -351,8 +353,10 @@ void eTextPara::calc_bbox() 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() ) @@ -363,7 +367,8 @@ void eTextPara::calc_bbox() 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) @@ -402,15 +407,16 @@ eTextPara *eTextPara::grab() 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 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; @@ -421,8 +427,6 @@ void eTextPara::setFont(Font *fnt, Font *replacement) 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); @@ -483,7 +487,7 @@ int eTextPara::renderString(const eString &string, int rflags) std::vector 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()) { @@ -546,11 +550,14 @@ int eTextPara::renderString(const eString &string, int rflags) glyphs.reserve(uc_visual.size()); + int nextflags = 0; + for (std::vector::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) @@ -584,7 +591,7 @@ tab: isprintable=0; case '\n': newline:isprintable=0; newLine(rflags); - flags|=GS_ISFIRST; + nextflags|=GS_ISFIRST; break; case '\r': case 0x86: case 0xE086: @@ -625,7 +632,7 @@ nprint: isprintable=0; 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); @@ -644,30 +651,31 @@ void eTextPara::blit(gPixmapDC &dc, const ePoint &offset, const gRGB &background ePtr 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) @@ -675,14 +683,15 @@ void eTextPara::blit(gPixmapDC &dc, const ePoint &offset, const gRGB &background } } 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) { @@ -691,25 +700,25 @@ void eTextPara::blit(gPixmapDC &dc, const ePoint &offset, const gRGB &background 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; @@ -789,6 +798,7 @@ void eTextPara::realign(int dir) // der code hier ist ein wenig merkwuerdig. linelength+=c->w; num++; } + if (!num) // line mit nur einem space continue; @@ -846,8 +856,8 @@ void eTextPara::clear() { singleLock s(ftlock); - for (glyphString::iterator i(glyphs.begin()); i!=glyphs.end(); ++i) - i->font->unlock(); + current_font = 0; + replacement_font = 0; glyphs.clear(); } diff --git a/lib/gdi/font.h b/lib/gdi/font.h index ac55c88..9977eb3 100644 --- a/lib/gdi/font.h +++ b/lib/gdi/font.h @@ -1,24 +1,24 @@ #ifndef __FONT_H #define __FONT_H -#include -#include -#include -#include -#include -#include -#include +#include +#include FT_FREETYPE_H +#include FT_CACHE_H +#include FT_CACHE_IMAGE_H +#include FT_CACHE_SMALL_BITMAPS_H #include + #include #include #include #include #include +#include class FontRenderClass; class Font; -class gPixmapDC; +class gDC; class gFont; class gRGB; @@ -49,7 +49,7 @@ public: 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, const eString &face, int size, int tabwidth=-1); fontRenderClass(); ~fontRenderClass(); }; @@ -66,7 +66,7 @@ public: struct pGlyph { int x, y, w; - Font *font; + ePtr font; FT_ULong glyph_index; int flags; eRect bbox; @@ -77,9 +77,11 @@ typedef std::vector glyphString; class Font; class eLCD; -class eTextPara +class eTextPara: public iObject { - Font *current_font, *replacement_font; +DECLARE_REF; +private: + ePtr current_font, replacement_font; FT_Face current_face, replacement_face; int use_kerning; int previous; @@ -104,19 +106,19 @@ public: 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 { @@ -139,12 +141,12 @@ public: } }; -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; @@ -152,10 +154,7 @@ public: 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; diff --git a/lib/gdi/gfbdc.cpp b/lib/gdi/gfbdc.cpp index 83f681d..3247aa6 100644 --- a/lib/gdi/gfbdc.cpp +++ b/lib/gdi/gfbdc.cpp @@ -15,26 +15,28 @@ gFBDC::gFBDC() 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; } @@ -72,10 +74,7 @@ void gFBDC::calcRamp() 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. @@ -83,15 +82,15 @@ void gFBDC::calcRamp() 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; } @@ -104,12 +103,12 @@ void gFBDC::exec(gOpcode *o) { case gOpcode::setPalette: { - gPixmapDC::exec(o); + gDC::exec(o); setPalette(); break; } default: - gPixmapDC::exec(o); + gDC::exec(o); break; } } @@ -163,4 +162,4 @@ void gFBDC::reloadSettings() setPalette(); } -eAutoInitP0 init_gFBDC(eAutoInitNumbers::graphic+1, "GFBDC"); +eAutoInitP0 init_gFBDC(eAutoInitNumbers::graphic-1, "GFBDC"); diff --git a/lib/gdi/gfbdc.h b/lib/gdi/gfbdc.h index f975fb5..0b0372d 100644 --- a/lib/gdi/gfbdc.h +++ b/lib/gdi/gfbdc.h @@ -5,7 +5,7 @@ #include "gpixmap.h" #include "grc.h" -class gFBDC: public gPixmapDC +class gFBDC: public gDC { fbClass *fb; static gFBDC *instance; @@ -14,6 +14,7 @@ class gFBDC: public gPixmapDC int brightness, gamma, alpha; void calcRamp(); void setPalette(); + gSurface surface; public: void reloadSettings(); void setAlpha(int alpha); @@ -29,6 +30,7 @@ public: gFBDC(); ~gFBDC(); static gFBDC *getInstance(); + int islocked() { return fb->islocked(); } }; diff --git a/lib/gdi/glcddc.cpp b/lib/gdi/glcddc.cpp index 3895df9..1a5e03f 100644 --- a/lib/gdi/glcddc.cpp +++ b/lib/gdi/glcddc.cpp @@ -1,7 +1,6 @@ #ifndef DISABLE_LCD #include -#include gLCDDC *gLCDDC::instance; @@ -11,21 +10,20 @@ gLCDDC::gLCDDC(eLCD *lcd): lcd(lcd) 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; } @@ -33,12 +31,12 @@ void gLCDDC::exec(gOpcode *o) { switch (o->opcode) { - case gOpcode::flush: +// case gOpcode::flush: case gOpcode::end: if (update) lcd->update(); default: - gPixmapDC::exec(o); + gDC::exec(o); break; } } diff --git a/lib/gdi/glcddc.h b/lib/gdi/glcddc.h index 9342e5e..d4cfab8 100644 --- a/lib/gdi/glcddc.h +++ b/lib/gdi/glcddc.h @@ -4,20 +4,21 @@ #define __glcddc_h #include "grc.h" +#include -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(); } }; diff --git a/lib/gdi/gpixmap.cpp b/lib/gdi/gpixmap.cpp index e8ddcf7..b6711fc 100644 --- a/lib/gdi/gpixmap.cpp +++ b/lib/gdi/gpixmap.cpp @@ -1,15 +1,13 @@ #include 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); } @@ -17,7 +15,7 @@ void gLookup::build(int _size, const gPalette &pal, const gRGB &start, const gRG { if (lookup) { - delete lookup; + delete [] lookup; lookup=0; size=0; } @@ -49,24 +47,77 @@ void gLookup::build(int _size, const gPalette &pal, const gRGB &start, const gRG } } -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(); ydata)+y*surface->stride+area.left(), color.color, area.width()); + else if (surface->bpp == 32) for (int y=area.top(); ydata)+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; @@ -74,29 +125,27 @@ void gPixmap::fill(const eRect &area, const gColor &color) *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; ybypp); + 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 && (iclut.data && (iclut.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; ystride; + 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; iclut.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; ayy; ay++) { - for (int ax=0; axx; 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 @@ -246,50 +295,18 @@ 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); } + diff --git a/lib/gdi/gpixmap.h b/lib/gdi/gpixmap.h index f68a574..048b73a 100644 --- a/lib/gdi/gpixmap.h +++ b/lib/gdi/gpixmap.h @@ -3,11 +3,10 @@ #include #include +#include +#include #include #include -#include - -#include struct gColor { @@ -71,6 +70,7 @@ struct gLookup 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); }; @@ -80,8 +80,11 @@ struct gLookup * 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; @@ -95,12 +98,9 @@ struct gFont { } - enum + virtual ~gFont() { - tRegular, tFixed - }; - - gFont(int type, int pointSize); + } gFont() :pointSize(0) @@ -108,16 +108,35 @@ struct gFont } }; +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); @@ -129,14 +148,10 @@ public: 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 diff --git a/lib/gdi/grc.cpp b/lib/gdi/grc.cpp index 3bd0078..55c86a0 100644 --- a/lib/gdi/grc.cpp +++ b/lib/gdi/grc.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -22,7 +23,7 @@ void *gRC::thread_wrapper(void *ptr) gRC *gRC::instance=0; -gRC::gRC(): queuelock(MAXSIZE), queue(2048) +gRC::gRC(): queue(2048), queuelock(MAXSIZE) { ASSERT(!instance); instance=this; @@ -34,11 +35,18 @@ gRC::gRC(): queuelock(MAXSIZE), queue(2048) 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() @@ -54,6 +62,7 @@ void *gRC::thread() if (o.opcode==gOpcode::shutdown) break; o.dc->exec(&o); + o.dc->Release(); queue.dequeue(); } #ifndef SYNC_PAINT @@ -62,17 +71,15 @@ void *gRC::thread() 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); @@ -84,265 +91,299 @@ gPainter::~gPainter() 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 >(); - cliparea=std::stack(); - 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 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 init_grc(eAutoInitNumbers::graphic, "gRC"); diff --git a/lib/gdi/grc.h b/lib/gdi/grc.h index 53cd4a8..225fd9d 100644 --- a/lib/gdi/grc.h +++ b/lib/gdi/grc.h @@ -13,10 +13,10 @@ #include #include -#include #include +#include #include - +#include class eTextPara; @@ -25,12 +25,11 @@ struct gOpcode { enum Opcode { - begin, - renderText, renderPara, + setFont, - fill, + fill, clear, blit, setPalette, @@ -38,100 +37,99 @@ struct gOpcode 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 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 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 queue; public: + eLock queuelock; gRC(); virtual ~gRC(); @@ -140,7 +138,7 @@ public: 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 @@ -150,50 +148,35 @@ public: } } - 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 m_dc; + ePtr m_rc; friend class gRC; gOpcode *beginptr; - /* paint states */ -// std::stack > cliparea; - std::stack 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); @@ -204,42 +187,33 @@ public: 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 &)=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 pixmap; - eRect clip; + ePtr m_pixmap; - void exec(gOpcode *opcode); - gPixmapDC(); + ePtr m_clip_region; + gColor m_foregroundColor, m_backgroundColor; + ePtr m_current_font; + ePoint m_current_offset; + gRegion m_current_clip; + public: - gPixmapDC(gPixmap *pixmap); - virtual ~gPixmapDC(); - RESULT getPixmap(ePtr &ptr) { ptr = pixmap; return 0; } + void exec(gOpcode *opcode); + gDC(gPixmap *pixmap); + gDC(); + virtual ~gDC(); + gRegion &getClip() { return *m_clip_region; } + int getPixmap(ePtr &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 diff --git a/lib/gdi/lcd.cpp b/lib/gdi/lcd.cpp index 33eb619..4de4df0 100644 --- a/lib/gdi/lcd.cpp +++ b/lib/gdi/lcd.cpp @@ -10,11 +10,11 @@ #include #include -#include -#include -#include +#include +#include +#include #include -#include +#include eDBoxLCD *eDBoxLCD::instance; @@ -41,16 +41,16 @@ int eLCD::lock() 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) @@ -165,7 +165,10 @@ int eDBoxLCD::switchLCD(int state) eDBoxLCD::~eDBoxLCD() { if (lcdfd>0) + { close(lcdfd); + lcdfd=0; + } } eDBoxLCD *eDBoxLCD::getInstance() @@ -175,25 +178,22 @@ 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)<=108)<0) - write(lcdfd, raw, 120*8); } + if (lcdfd>0) + write(lcdfd, raw, 120*8); } class eDBoxLCDHardware @@ -209,4 +209,5 @@ public: eAutoInitP0 init_eDBoxLCDHardware(eAutoInitNumbers::lowlevel, "d-Box LCD Hardware"); #endif //DISABLE_LCD + #endif diff --git a/lib/gdi/lcd.h b/lib/gdi/lcd.h index 567d064..88e543f 100644 --- a/lib/gdi/lcd.h +++ b/lib/gdi/lcd.h @@ -23,6 +23,7 @@ protected: public: int lock(); void unlock(); + int islocked() { return locked; } eLCD(eSize size); virtual ~eLCD(); diff --git a/lib/gdi/region.cpp b/lib/gdi/region.cpp new file mode 100644 index 0000000..f341e79 --- /dev/null +++ b/lib/gdi/region.cpp @@ -0,0 +1,343 @@ +#include +#include +#include + +#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::iterator prevBox = rects.begin() + prevStart; + std::vector::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::const_iterator r, + std::vector::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::const_iterator r1, + std::vector::const_iterator r1End, + std::vector::const_iterator r2, + std::vector::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::const_iterator r1, + std::vector::const_iterator r1End, + std::vector::const_iterator r2, + std::vector::const_iterator r2End, + int y1, int y2, + int &overlap) +{ + int x1; + x1 = r1->x1; + + assert(y1x2 <= 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(x1x1); + 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(x1x2); + 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::const_iterator r1, + std::vector::const_iterator r1End, + std::vector::const_iterator r2, + std::vector::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::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); +} + diff --git a/lib/gdi/region.h b/lib/gdi/region.h new file mode 100644 index 0000000..a1dbe91 --- /dev/null +++ b/lib/gdi/region.h @@ -0,0 +1,85 @@ +#ifndef __lib_gdi_region_h +#define __lib_gdi_region_h + +#include +#include + +class gRegion: public virtual iObject +{ +DECLARE_REF; +private: + inline void FindBand( + std::vector::const_iterator r, + std::vector::const_iterator &rBandEnd, + std::vector::const_iterator rEnd, + int &ry1) + { + ry1 = r->y1; + rBandEnd = r+1; + while ((rBandEnd != rEnd) && (rBandEnd->y1 == ry1)) + rBandEnd++; + } + + inline void AppendRegions( + std::vector::const_iterator r, + std::vector::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::const_iterator r, + std::vector::const_iterator rEnd, int y1, int y2); + + void intersectO( + std::vector::const_iterator r1, + std::vector::const_iterator r1End, + std::vector::const_iterator r2, + std::vector::const_iterator r2End, + int y1, int y2, + int &overlap); + void subtractO( + std::vector::const_iterator r1, + std::vector::const_iterator r1End, + std::vector::const_iterator r2, + std::vector::const_iterator r2End, + int y1, int y2, + int &overlap); + void mergeO( + std::vector::const_iterator r1, + std::vector::const_iterator r1End, + std::vector::const_iterator r2, + std::vector::const_iterator r2End, + int y1, int y2, + int &overlap); + void regionOp(const gRegion ®1, const gRegion ®2, int opcode, int &overlap); +public: + std::vector 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 diff --git a/lib/gui/echeckbox.cpp b/lib/gui/echeckbox.cpp index c41721c..e69de29 100644 --- a/lib/gui/echeckbox.cpp +++ b/lib/gui/echeckbox.cpp @@ -1,138 +0,0 @@ -#include - -#include -#include -#include -#include - -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 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 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 init_eCheckboxSkinInit(eAutoInitNumbers::guiobject, "eCheckbox"); diff --git a/lib/gui/elabel.cpp b/lib/gui/elabel.cpp index ae04eb4..ce4efaf 100644 --- a/lib/gui/elabel.cpp +++ b/lib/gui/elabel.cpp @@ -84,7 +84,7 @@ void eLabel::redrawWidget(gPainter *target, const eRect &rc) /* 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(), @@ -136,7 +136,7 @@ void eLabel::redrawWidget(gPainter *target, const eRect &rc) 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) { @@ -146,7 +146,7 @@ void eLabel::redrawWidget(gPainter *target, const eRect &rc) } 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(); diff --git a/lib/gui/eskin.h b/lib/gui/eskin.h index d28655a..7d701ad 100644 --- a/lib/gui/eskin.h +++ b/lib/gui/eskin.h @@ -40,7 +40,7 @@ class eSkin gRGB *palette; int maxcolors; - ePtr paldummy; + ePtr paldummy; int *colorused; static std::map< eString, tWidgetCreator > widget_creator; @@ -68,7 +68,7 @@ public: 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; diff --git a/lib/gui/ewidget.h b/lib/gui/ewidget.h index 3a1199a..e69de29 100644 --- a/lib/gui/ewidget.h +++ b/lib/gui/ewidget.h @@ -1,498 +0,0 @@ -#ifndef __ewidget_h -#define __ewidget_h - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -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 focusChanged; - static Signal2< void, ePtrList*, int > showHelp; -protected: - ePtrList actionHelpList; - int helpID; - ePtrList 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 _focusList; - - ePtrList 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 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 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 *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