trunk 20080912
[gitenigma.git] / include / lib / gdi / grc.h
blob7322263b229e73eff980ddfb3a407cc4b15b1978
1 #ifndef __grc_h
2 #define __grc_h
4 /*
5 gPainter ist die high-level version. die highlevel daten werden zu low level opcodes ueber
6 die gRC-queue geschickt und landen beim gDC der hardwarespezifisch ist, meist aber auf einen
7 gPixmap aufsetzt (und damit unbeschleunigt ist).
8 */
10 #include <pthread.h>
11 #include <unistd.h>
12 #include <stack>
13 #include <list>
15 #include <lib/base/estring.h>
16 #include <lib/base/erect.h>
17 #include <lib/system/elock.h>
18 #include <lib/gdi/gpixmap.h>
21 class eTextPara;
23 class gDC;
24 struct gOpcode
26 enum Opcode
28 begin,
30 renderText,
31 renderPara,
33 fill,
34 blit,
36 setPalette,
37 mergePalette,
39 line,
41 clip,
43 flush,
44 end,
46 shutdown
47 } opcode;
49 union para
51 struct pbegin
53 eRect area;
54 pbegin(const eRect &area): area(area) { }
55 } *begin;
57 struct pfill
59 eRect area;
60 gColor color;
61 pfill(const eRect &area, gColor color): area(area), color(color) { }
62 } *fill;
64 struct prenderText
66 gFont font;
67 eRect area;
68 char *text;
69 gRGB foregroundColor, backgroundColor;
70 prenderText(const gFont &font, const eRect &area, const eString &text, const gRGB &foregroundColor, const gRGB &backgroundColor):
71 font(font), area(area), text(text.length()?strdup(text.c_str()):0), foregroundColor(foregroundColor), backgroundColor(backgroundColor) { }
72 } *renderText;
74 struct prenderPara
76 ePoint offset;
77 eTextPara *textpara;
78 gRGB foregroundColor, backgroundColor;
79 prenderPara(const ePoint &offset, eTextPara *textpara, const gRGB &foregroundColor, const gRGB &backgroundColor)
80 : offset(offset), textpara(textpara), foregroundColor(foregroundColor), backgroundColor(backgroundColor) { }
81 } *renderPara;
83 struct psetPalette
85 gPalette *palette;
86 psetPalette(gPalette *palette): palette(palette) { }
87 } *setPalette;
89 struct pblit
91 gPixmap *pixmap;
92 ePoint position;
93 eRect clip;
94 pblit(gPixmap *pixmap, const ePoint &position, const eRect &clip)
95 : pixmap(pixmap), position(position), clip(clip) { }
96 } *blit;
98 struct pmergePalette
100 gPixmap *target;
101 pmergePalette(gPixmap *target): target(target) { }
102 } *mergePalette;
104 struct pline
106 ePoint start, end;
107 gColor color;
108 pline(const ePoint &start, const ePoint &end, gColor color): start(start), end(end), color(color) { }
109 } *line;
111 struct pclip
113 eRect clip;
114 pclip(const eRect &clip): clip(clip) { }
115 } *clip;
116 } parm;
118 int flags;
120 gDC *dc;
123 #define MAXSIZE 1024
125 class gRC
127 static void *thread_wrapper(void *ptr);
128 void *thread();
130 static gRC *instance;
131 gOpcode queue[MAXSIZE];
132 pthread_t the_thread;
133 pthread_mutex_t mutex;
134 pthread_cond_t cond;
135 int rp, wp;
136 public:
137 bool mustDraw() { return rp != wp; }
138 gRC();
139 virtual ~gRC();
141 void submit(const gOpcode &o)
143 while(1)
145 pthread_mutex_lock(&mutex);
146 int tmp=wp+1;
147 if ( tmp == MAXSIZE )
148 tmp=0;
149 if ( tmp == rp )
151 pthread_mutex_unlock(&mutex);
152 //printf("render buffer full...\n");
153 //fflush(stdout);
154 usleep(1000); // wait 1 msec
155 continue;
157 int free=rp-wp;
158 if ( free <= 0 )
159 free+=MAXSIZE;
160 queue[wp++]=o;
161 if ( wp == MAXSIZE )
162 wp = 0;
163 if (o.opcode==gOpcode::end||o.opcode==gOpcode::shutdown)
164 pthread_cond_signal(&cond);
165 pthread_mutex_unlock(&mutex);
166 break;
170 static gRC &getInstance();
173 class gDC
175 protected:
176 eLock dclock;
177 public:
178 virtual void exec(gOpcode *opcode)=0;
179 virtual gPixmap &getPixmap()=0;
180 virtual eSize getSize()=0;
181 virtual const eRect &getClip()=0;
182 virtual gRGB getRGB(gColor col)=0;
183 virtual ~gDC();
184 virtual int islocked() { return 0; }
185 void lock() { dclock.lock(1); }
186 void unlock() { dclock.unlock(1); }
189 class gPainter
191 gDC &dc;
192 gRC &rc;
193 friend class gRC;
195 gOpcode *beginptr;
196 /* paint states */
197 // std::stack<eRect, std::list<eRect> > cliparea;
198 std::stack<eRect> cliparea;
199 gFont font;
200 gColor foregroundColor, backgroundColor;
201 ePoint logicalZero;
202 void begin(const eRect &rect);
203 void end();
204 public:
205 gPainter(gDC &dc, eRect rect=eRect());
206 virtual ~gPainter();
208 void setBackgroundColor(const gColor &color);
209 void setForegroundColor(const gColor &color);
211 void setFont(const gFont &font);
212 void renderText(const eRect &position, const std::string &string, int flags=0);
213 void renderPara(eTextPara &para, ePoint offset=ePoint(0, 0));
215 void fill(const eRect &area);
217 void clear();
219 void gPainter::blit(gPixmap &pixmap, ePoint pos, eRect clip=eRect(), int flags=0)
221 if ( dc.islocked() )
222 return;
223 gOpcode o;
224 o.dc=&dc;
225 o.opcode=gOpcode::blit;
226 pos+=logicalZero;
227 clip.moveBy(logicalZero.x(), logicalZero.y());
228 o.parm.blit=new gOpcode::para::pblit(pixmap.lock(), pos, clip);
229 o.flags=flags;
230 rc.submit(o);
233 void setPalette(gRGB *colors, int start=0, int len=256);
234 void mergePalette(gPixmap &target);
236 void line(ePoint start, ePoint end);
238 void setLogicalZero(ePoint abs);
239 void moveLogicalZero(ePoint rel);
240 void resetLogicalZero();
242 void clip(eRect clip);
243 void clippop();
245 void flush();
248 class gPixmapDC: public gDC
250 protected:
251 gPixmap *pixmap;
252 eRect clip;
254 void exec(gOpcode *opcode);
255 gPixmapDC();
256 public:
257 gPixmapDC(gPixmap *pixmap);
258 virtual ~gPixmapDC();
259 gPixmap &getPixmap() { return *pixmap; }
260 gRGB getRGB(gColor col);
261 const eRect &getClip() { return clip; }
262 virtual eSize getSize() { return eSize(pixmap->x, pixmap->y); }
265 #endif