mreging Ignas' update code
[dasher.git] / Src / Gtk2 / Canvas.cpp
blobf8b3d465767b0676b61514381e1b6541eed4843b
1 #include "../Common/Common.h"
3 #include <math.h>
4 #include "Canvas.h"
5 #include "DasherControl.h"
7 #include "../DasherCore/DasherTypes.h"
9 //#undef WITH_CAIRO
11 //#define IGNAS_NODRAW
12 //#define IGNAS_RECTANGLE_PRINT
13 #define IGNAS_DRAW_MAIN_RECTANGLES true
14 // #define IGNAS_NORECTANGLE_DRAW
15 // #define IGNAS_NOFONT_DRAW
16 //#define IGNAS_FRAME_PRINT
17 //#define IGNAS_NO_BLANK
19 #ifdef IGNAS_NODRAW
20 #define IGNAS_STOP_VOID return;
21 #endif
22 #ifndef IGNAS_NODRAW
23 #define IGNAS_STOP_VOID ;
24 #endif
26 #ifdef IGNAS_NO_BLANK
27 #define IGNAS_STOP_BLANK return;
28 #endif
29 #ifndef IGNAS_NO_BLANK
30 #define IGNAS_STOP_BLANK ;
31 #endif
34 #ifdef IGNAS_NORECTANGLE_DRAW
35 #define IGNAS_RECTANGLE_STOP_VOID return;
36 #endif
37 #ifndef IGNAS_NORECTANGLE_DRAW
38 #define IGNAS_RECTANGLE_STOP_VOID ;
39 #endif
40 #ifdef IGNAS_NOFONT_DRAW
41 #define IGNAS_FONT_STOP_VOID return;
42 #endif
43 #ifndef IGNAS_NOFONT_DRAW
44 #define IGNAS_FONT_STOP_VOID ;
45 #endif
46 using namespace Dasher;
48 CCanvas::CCanvas(GtkWidget *pCanvas, CPangoCache *pPangoCache)
49 : CDasherScreen(pCanvas->allocation.width, pCanvas->allocation.height) {
51 m_pCanvas = pCanvas;
52 m_bLoadBackground = true;
53 m_bCaptureBackground = true;
54 ///IGNAS
56 #ifdef FRAMERATE_DIAGNOSTICS
57 count_frames=0;
58 lasttime=-1;
59 count_time=0;
60 total_frames=0;
61 count_rectangles=0;
62 #endif
64 display_depth=3;
65 display_fontdepth=4;
66 display_fontwidth=m_pCanvas->allocation.width;
67 display_fontheight=m_pCanvas->allocation.height;
68 ///IGNAS
71 #if WITH_CAIRO
72 cairo_colours = 0;
73 #else
74 colours = 0;
75 #endif
78 m_pPangoCache = pPangoCache;
80 m_iWidth = m_pCanvas->allocation.width;
81 m_iHeight = m_pCanvas->allocation.height;
83 display_data= (guchar *) g_malloc(m_pCanvas->allocation.width*m_pCanvas->allocation.height*display_depth * sizeof(guchar));
84 display_backgrounddata= (guchar *) g_malloc(m_pCanvas->allocation.width*m_pCanvas->allocation.height*display_depth * sizeof(guchar));
86 display_fontdata= (guchar *) g_malloc(display_fontwidth*display_fontheight*display_fontdepth * sizeof(guchar));
89 point_id= (gint *) g_malloc(m_pCanvas->allocation.width * sizeof(gint));
90 point_amount= (gint *) g_malloc(m_pCanvas->allocation.width * sizeof(gint));
91 point_data= (gint *) g_malloc(m_pCanvas->allocation.width * sizeof(gint));
92 GdkColor bg;
93 GdkColor fg;
94 bg.red=0;bg.green=0;bg.blue=0;
95 fg=bg;
96 display_pixbuf =gdk_pixbuf_new_from_data (display_data,
97 GDK_COLORSPACE_RGB,
98 false, //no alpha
100 m_pCanvas->allocation.width,
101 m_pCanvas->allocation.height,
102 m_pCanvas->allocation.width*display_depth,
103 NULL,
104 NULL);
106 #if WITH_CAIRO
107 display_fontcairosurface=cairo_image_surface_create_for_data (display_fontdata,
108 CAIRO_FORMAT_RGB24,
109 display_fontwidth,display_fontheight,
110 display_fontwidth*display_fontdepth);
111 display_fontcairo= cairo_create(display_fontcairosurface);
112 #else
113 //FONT FOR GDK
114 display_fontgdk= gdk_pixmap_create_from_data (m_pCanvas->window,
115 (gchar*)display_fontdata,
116 m_iWidth,
117 m_iHeight,
119 &m_pCanvas->style->fg[GTK_STATE_NORMAL],
120 &m_pCanvas->style->bg[GTK_STATE_NORMAL]);
122 gdk_drawable_set_colormap(display_fontgdk, gdk_colormap_get_system());
124 if (display_fontgdk==NULL)
125 printf("No PIXMAP!!!\n");
127 #endif
129 m_pPangoInk = new PangoRectangle;
130 gtk_widget_add_events(m_pCanvas, GDK_ALL_EVENTS_MASK);
133 CCanvas::~CCanvas() {
134 // Free the buffer pixmaps
137 #if WITH_CAIRO
138 cairo_destroy(display_fontcairo);
140 #else
141 g_object_unref(display_fontgdk);
142 #endif
143 free(display_fontdata);
144 free(display_backgrounddata);
145 g_object_unref(display_pixbuf);
146 free(display_data);
148 delete m_pPangoInk;
151 void CCanvas::Blank() {
152 //IGNAS_STOP_VOID
154 GdkColor _c;
156 #if WITH_CAIRO
157 _c.red=(int)(cairo_colours[0].r*255);
158 _c.green=(int)(cairo_colours[0].g*255);
159 _c.blue=(int)(cairo_colours[0].b*255);
160 #else
161 _c.red=colours[0].red;
162 _c.green=colours[0].green;
163 _c.blue=colours[0].blue;
164 #endif
167 for(int i=0;i<m_iWidth*m_iHeight*display_depth;i+=display_depth)
169 display_data[i]=_c.red;
170 display_data[i+1]=_c.green;
171 display_data[i+2]=_c.blue;
176 void CCanvas::Display() {
178 //IGNAS_STOP_VOID
180 GdkGC *graphics_context;
182 graphics_context = m_pCanvas->style->fg_gc[GTK_WIDGET_STATE(m_pCanvas)];
185 gdk_pixbuf_render_to_drawable(display_pixbuf,m_pCanvas->window, graphics_context,0, 0,0,0, m_iWidth,m_iHeight, GDK_RGB_DITHER_NORMAL,0,0);
188 void CCanvas::DrawRectangle(int x1, int y1, int x2, int y2, int Color, int iOutlineColour, Opts::ColorSchemes ColorScheme, bool bDrawOutline, bool bFill, int iThickness) {
189 bFill&=IGNAS_DRAW_MAIN_RECTANGLES;
190 IGNAS_RECTANGLE_STOP_VOID
191 IGNAS_STOP_VOID
193 #ifdef FRAMERATE_DIAGNOSTICS
194 ///IGNAS
195 count_rectangles++;
196 ///IGNAS
197 #endif
199 GdkColor _c;
200 int iLeft;
201 int iTop;
202 int iRight;
203 int iBottom;
204 int iWidth;
205 int iHeight;
207 if( x2 > x1 ) {
208 iLeft = x1;
209 iWidth = x2 - x1;
211 else {
212 iLeft = x2;
213 iWidth = x1 - x2;
216 if( y2 > y1 ) {
217 iTop = y1;
218 iHeight = y2 - y1;
220 else {
221 iTop = y2;
222 iHeight = y1 - y2;
224 iBottom=iTop+iHeight;
225 if (iBottom> m_iHeight) iBottom=m_iHeight;
226 iRight=iLeft+iWidth;
227 if (iRight> m_iWidth) iRight=m_iWidth;
228 if (iLeft<0) iLeft=0;
229 if (iTop<0) iTop=0;
230 if(bFill) {
231 #if WITH_CAIRO
232 _c.red=(int)(cairo_colours[Color].r*255);
233 _c.green=(int)(cairo_colours[Color].g*255);
234 _c.blue=(int)(cairo_colours[Color].b*255);
235 #else
236 _c.red=colours[Color].red;
237 _c.green=colours[Color].green;
238 _c.blue=colours[Color].blue;
239 #endif
241 for (int i=iTop;i<iBottom;i++)
242 for(int j=iLeft;j<iRight;j++)
244 display_data[i*m_iWidth*display_depth+j*display_depth]=_c.red;
245 display_data[i*m_iWidth*display_depth+j*display_depth+1]=_c.green;
246 display_data[i*m_iWidth*display_depth+j*display_depth+2]=_c.blue;
250 if(bDrawOutline) {
251 if( iOutlineColour == -1 )
255 #if WITH_CAIRO
256 _c.red=(int)(cairo_colours[3].r*255);
257 _c.green=(int)(cairo_colours[3].g*255);
258 _c.blue=(int)(cairo_colours[3].b*255);
259 #else
260 _c.red=colours[3].red;
261 _c.green=colours[3].green;
262 _c.blue=colours[3].blue;
263 #endif
266 else
270 #if WITH_CAIRO
271 _c.red=(int)(cairo_colours[iOutlineColour].r*255);
272 _c.green=(int)(cairo_colours[iOutlineColour].g*255);
273 _c.blue=(int)(cairo_colours[iOutlineColour].b*255);
274 #else
275 _c.red=colours[iOutlineColour].red;
276 _c.green=colours[iOutlineColour].green;
277 _c.blue=colours[iOutlineColour].blue;
278 #endif
282 int i=0,j=0;
283 for(int thickness=0;thickness<iThickness;thickness++)
285 if (iLeft+thickness<m_iWidth)
286 for (i=iTop;i<iBottom;i++)
290 display_data[i*m_iWidth*display_depth+(iLeft+thickness)*display_depth]=_c.red;
291 display_data[i*m_iWidth*display_depth+(iLeft+thickness)*display_depth+1]=_c.green;
292 display_data[i*m_iWidth*display_depth+(iLeft+thickness)*display_depth+2]=_c.blue;
295 if ((iRight-thickness>=0)&&(iRight-thickness<m_iWidth))
296 for (i=iTop;i<iBottom;i++)
298 display_data[i*m_iWidth*display_depth+(iLeft+iWidth-thickness)*display_depth]=_c.red;
299 display_data[i*m_iWidth*display_depth+(iLeft+iWidth-thickness)*display_depth+1]=_c.green;
300 display_data[i*m_iWidth*display_depth+(iLeft+iWidth-thickness)*display_depth+2]=_c.blue;
303 if (iTop+thickness<m_iHeight)
304 for(j=iLeft;j<iRight;j++)
307 display_data[(iTop+thickness)*m_iWidth*display_depth+j*display_depth]=_c.red;
308 display_data[(iTop+thickness)*m_iWidth*display_depth+j*display_depth+1]=_c.green;
309 display_data[(iTop+thickness)*m_iWidth*display_depth+j*display_depth+2]=_c.blue;
311 if ((iBottom-thickness<m_iHeight)&&(iBottom-thickness>=0))
312 for(j=iLeft;j<iRight;j++)
314 display_data[(iTop+iHeight-thickness)*m_iWidth*display_depth+j*display_depth]=_c.red;
315 display_data[(iTop+iHeight-thickness)*m_iWidth*display_depth+j*display_depth+1]=_c.green;
316 display_data[(iTop+iHeight-thickness)*m_iWidth*display_depth+j*display_depth+2]=_c.blue;
323 void CCanvas::CirclePoints(int cx, int cy, int x, int y, int Colour,int iWidth)
325 //A circle drawing algorithm taken from
326 //http://www.cs.unc.edu/~mcmillan/comp136/
328 GdkColor _c;
329 #if WITH_CAIRO
330 _c.red=(int)(cairo_colours[Colour].r*255);
331 _c.green=(int)(cairo_colours[Colour].g*255);
332 _c.blue=(int)(cairo_colours[Colour].b*255);
333 #else
334 _c.red=colours[Colour].red;
335 _c.green=colours[Colour].green;
336 _c.blue=colours[Colour].blue;
337 #endif
339 if (x == 0) {
340 SetPixel(&_c, cx, cy + y,iWidth); //act
341 SetPixel(&_c, cx, cy - y,iWidth);
342 SetPixel(&_c, cx + y, cy,iWidth);
343 SetPixel(&_c, cx - y, cy,iWidth);
345 } else
346 if (x == y) {
347 SetPixel(&_c, cx + x, cy + y,iWidth);//act
348 SetPixel(&_c, cx - x, cy + y,iWidth);
349 SetPixel(&_c, cx + x, cy - y,iWidth);
350 SetPixel(&_c, cx - x, cy - y,iWidth);
351 } else
352 if (x < y) {
353 SetPixel(&_c, cx + x, cy + y,iWidth);//act
354 SetPixel(&_c, cx - x, cy + y,iWidth);
355 SetPixel(&_c, cx + x, cy - y,iWidth);
356 SetPixel(&_c, cx - x, cy - y,iWidth);
357 SetPixel(&_c, cx + y, cy + x,iWidth);
358 SetPixel(&_c, cx - y, cy + x,iWidth);
359 SetPixel(&_c, cx + y, cy - x,iWidth);
360 SetPixel(&_c, cx - y, cy - x,iWidth);
363 void CCanvas::HVThinLine(int x0,int y0,int x1,int y1,int Colour)
365 GdkColor _c;
366 #if WITH_CAIRO
367 _c.red=(int)(cairo_colours[Colour].r*255);
368 _c.green=(int)(cairo_colours[Colour].g*255);
369 _c.blue=(int)(cairo_colours[Colour].b*255);
370 #else
371 _c.red=colours[Colour].red;
372 _c.green=colours[Colour].green;
373 _c.blue=colours[Colour].blue;
374 #endif
375 int start,end,x,y;
376 if (x0!=x1)
378 if (x0<x1)
380 start=x0;
381 end=x1;
383 else
385 start = x1;
386 end=x0;
388 if (start<0) start =0;
389 if (start>=m_iWidth) start =m_iWidth-1;
391 if ((y0>=0)&&(y0<m_iHeight))
392 for(x=start;x<end;x++)
394 display_data[y0*m_iWidth*display_depth+x*display_depth]=_c.red;
395 display_data[y0*m_iWidth*display_depth+x*display_depth+1]=_c.green;
396 display_data[y0*m_iWidth*display_depth+x*display_depth+2]=_c.blue;
401 else
403 if (y0<y1)
405 start=y0;
406 end=y1;
408 else
410 start = y1;
411 end=y0;
413 if (start<0) start =0;
414 if (start>=m_iHeight) start =m_iHeight-1;
416 if ((x0>=0)&&(x0<m_iWidth))
417 for(y=start;y<end;y++)
419 display_data[y*m_iWidth*display_depth+x0*display_depth]=_c.red;
420 display_data[y*m_iWidth*display_depth+x0*display_depth+1]=_c.green;
421 display_data[y*m_iWidth*display_depth+x0*display_depth+2]=_c.blue;
427 void CCanvas::CircleMidpoint(int xCenter, int yCenter, int radius, int Colour,int iWidth)
429 int x,y,p;
430 x = 0;
431 y = radius;
432 p = (5 - radius*4)/4;
433 CirclePoints(xCenter, yCenter, x,y, Colour,iWidth);
434 while (x < y) {
435 x++;
436 if (p < 0) {
437 p += 2*x+1;
438 } else {
439 y--;
440 p += 2*(x-y)+1;
442 CirclePoints(xCenter, yCenter, x, y, Colour,iWidth);
446 void CCanvas::CircleFill(int xCenter,int yCenter,int radius,int Colour)
448 GdkColor _c;
449 #if WITH_CAIRO
450 _c.red=(int)(cairo_colours[Colour].r*255);
451 _c.green=(int)(cairo_colours[Colour].g*255);
452 _c.blue=(int)(cairo_colours[Colour].b*255);
453 #else
454 _c.red=colours[Colour].red;
455 _c.green=colours[Colour].green;
456 _c.blue=colours[Colour].blue;
457 #endif
458 int x = 0;
459 int y = radius;
460 int p = (5 - radius*4)/4;
462 while (x < y) {
463 x++;
464 if (p < 0) {
465 p += 2*x+1;
466 } else {
467 y--;
468 p += 2*(x-y)+1;
471 HVThinLine(xCenter-x,yCenter-y,xCenter-x,yCenter+y,Colour);
472 HVThinLine(xCenter+x,yCenter-y,xCenter+x,yCenter+y,Colour);
473 HVThinLine(xCenter-y,yCenter-x,xCenter-y,yCenter+x,Colour);
474 HVThinLine(xCenter+y,yCenter-x,xCenter+y,yCenter+x,Colour);
477 void CCanvas::DrawCircle(screenint iCX, screenint iCY, screenint iR, int iColour, int iFillColour, int iThickness, bool bFill) {
480 if (bFill)
481 CircleFill(iCX,iCY,iR,iFillColour);
482 CircleMidpoint(iCX,iCY,iR,iColour,iThickness);
484 bool CCanvas::HorizontalIntersectionPoint(int h,int a,int b,int x0,int y0,int x1,int y1, int *p)
486 if (x0==x1) return false;
487 if (((h>y0)&&(h>y1))||((h<y0)&&(h<y1))) return false;
488 int t;
489 if (x0>x1)
491 t=x0;
492 x0=x1;
493 x1=t;
494 t=y0;
495 y0=y1;
496 y1=t;
498 int x;
499 double l;
500 int h1 = y0-h;
501 int h2 = y1-h;
502 if (h1<0) h1=-h1;
503 if (h2<0) h2=-h2;
504 int X = x1-x0;
505 if (X<0) X = -X;
506 if (X==0)
509 if ((x0>=a)&&(x0<=b)) *p=x0;
510 else
512 if (x0<a) *p=a; else *p=b;
514 return true;
516 if (h1 == 0)
518 if ((x0>=a)&&(x0<=b)) *p=x0;
519 else
521 if (x0<a) *p=a; else *p=b;
523 return true;
525 else
527 if (h2==0)
529 if ((x1>=a)&&(x1<=b)) *p=x1;
530 else
532 if (x1<a) *p=a; else *p=b;
534 return true;
536 else
538 l = (double)(h2 * X)/(double)(h1+h2);
539 x = int (x1-l);
540 if ((x>=a)&&(x<=b)) *p=x;
541 else
543 if (x<a) *p=a; else *p=b;
545 return true;
550 void CCanvas::PolygonFill(Dasher::CDasherScreen::point *Points, int Number, int Colour)
552 GdkColor _c;
553 #if WITH_CAIRO
554 _c.red=(int)(cairo_colours[Colour].r*255);
555 _c.green=(int)(cairo_colours[Colour].g*255);
556 _c.blue=(int)(cairo_colours[Colour].b*255);
557 #else
558 _c.red=colours[Colour].red;
559 _c.green=colours[Colour].green;
560 _c.blue=colours[Colour].blue;
561 #endif
562 if (Number>m_iWidth) return; //The size of point_data
563 int minx=m_iWidth-1,maxx=0,miny=m_iHeight-1,maxy=0;
564 int i;
565 for (i=0;i<Number;i++)
567 if (Points[i].x<minx) minx = Points[i].x;
568 if (Points[i].x>maxx) maxx = Points[i].x;
569 if (Points[i].y<miny) miny = Points[i].y;
570 if (Points[i].y>maxy) maxy = Points[i].y;
572 if (minx<0) minx=0;
573 if (miny<0) miny=0;
574 if (maxx>=m_iWidth) maxx=m_iWidth-1;
575 if (maxy>=m_iHeight) maxy=m_iHeight-1;
576 int p;
577 int depth;
578 for (i=0;i<m_iWidth;i++)
579 point_id[i]=-1;
580 for(int scanline=miny;scanline<=maxy;scanline++)
582 int found=-1;
583 for(i=1;i<Number;i++)
585 if (HorizontalIntersectionPoint(scanline,0,m_iWidth-1,Points[i-1].x,Points[i-1].y,Points[i].x,Points[i].y,&p))
587 found++;
588 point_data[found]=p;
591 if (HorizontalIntersectionPoint(scanline,0,m_iWidth-1,Points[Number-1].x,Points[Number-1].y,Points[0].x,Points[0].y,&p))
593 found++;
594 point_data[found]=p;
596 for (i=0;i<found;i++)
598 if (point_id[point_data[i]]!=scanline)
600 point_amount[point_data[i]]=1;
601 point_id[point_data[i]]=scanline;
603 else point_amount[point_data[i]]++;
605 depth=0;
606 for (i=0;i<m_iWidth;i++)
608 if (point_id[i]!=scanline)
610 if (depth%2==1)
612 display_data[scanline*m_iWidth*display_depth+i*display_depth]=_c.red;
613 display_data[scanline*m_iWidth*display_depth+i*display_depth+1]=_c.green;
614 display_data[scanline*m_iWidth*display_depth+i*display_depth]=_c.blue;
617 else
619 depth+=point_amount[i];
624 void CCanvas::Polygon(Dasher::CDasherScreen::point *Points, int Number, int Colour, int iWidth) {
625 IGNAS_STOP_VOID
627 for(int i = 1; i < Number; i++)
629 Line(Points[i].x,Points[i].y,Points[i-1].x,Points[i-1].y, iWidth,Colour);
631 Line(Points[Number-1].x,Points[Number-1].y,Points[0].x,Points[0].y,iWidth,Colour);
633 void CCanvas::SetPixel(GdkColor *c,int x,int y,int iWidth)
636 int x0=x,y0=y;
637 for (int i=0;i<iWidth;i++)
638 for (int j=0;j<iWidth;j++)
641 x=x0+i-iWidth/2;
642 y=y0+j-iWidth/2;
643 if (((y>=0)&&(y<m_iHeight))&&((x>=0)&&(x<m_iWidth)))
646 display_data[y*m_iWidth*display_depth+x*display_depth]=c->red;
647 display_data[y*m_iWidth*display_depth+x*display_depth+1]=c->green;
648 display_data[y*m_iWidth*display_depth+x*display_depth+2]=c->blue;
657 void CCanvas::Line(int x0,int y0,int x1,int y1,int iWidth, int Colour)
659 //A Bresenham line drawing algorithm taken from
660 //http://www.cs.unc.edu/~mcmillan/comp136/Lecture6/Lines.html
662 GdkColor _c;
663 #if WITH_CAIRO
664 _c.red=(int)(cairo_colours[Colour].r*255);
665 _c.green=(int)(cairo_colours[Colour].g*255);
666 _c.blue=(int)(cairo_colours[Colour].b*255);
667 #else
668 _c.red=colours[Colour].red;
669 _c.green=colours[Colour].green;
670 _c.blue=colours[Colour].blue;
671 #endif
672 int dy = y1 - y0;
673 int dx = x1 - x0;
674 int stepx, stepy;
676 if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
677 if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
678 dy <<= 1; // dy is now 2*dy
679 dx <<= 1; // dx is now 2*dx
681 SetPixel(&_c, x0, y0,iWidth);
682 if (dx > dy) {
683 int fraction = dy - (dx >> 1); // same as 2*dy - dx
684 while (x0 != x1) {
685 if (fraction >= 0) {
686 y0 += stepy;
687 fraction -= dx; // same as fraction -= 2*dx
689 x0 += stepx;
690 fraction += dy; // same as fraction -= 2*dy
691 SetPixel(&_c, x0, y0,iWidth);
693 } else {
694 int fraction = dx - (dy >> 1);
695 while (y0 != y1) {
696 if (fraction >= 0) {
697 x0 += stepx;
698 fraction -= dy;
700 y0 += stepy;
701 fraction += dx;
702 SetPixel(&_c, x0, y0,iWidth);
708 void CCanvas::Polyline(Dasher::CDasherScreen::point *Points, int Number, int iWidth, int Colour) {
710 IGNAS_STOP_VOID
714 for(int i = 1; i < Number; i++)
716 Line(Points[i].x,Points[i].y,Points[i-1].x,Points[i-1].y, iWidth,Colour);
720 void CCanvas::DrawString(const std::string &String, int x1, int y1, int size) {
721 IGNAS_FONT_STOP_VOID
722 IGNAS_STOP_VOID
725 #if WITH_CAIRO //set color black
726 my_cairo_colour_t _c = cairo_colours[4];
727 cairo_set_source_rgb(display_fontcairo, _c.r, _c.g, _c.b);
729 #else
730 GdkGC *graphics_context;
731 graphics_context = m_pCanvas->style->fg_gc[GTK_WIDGET_STATE(m_pCanvas)];
732 #endif //WITH_CAIRO
734 #if WITH_CAIRO
735 PangoLayout *pLayout(m_pPangoCache->GetLayout(display_fontcairo, String, size));
736 #else
738 PangoLayout *pLayout(m_pPangoCache->GetLayout(GTK_WIDGET(m_pCanvas), String, size));
740 #endif
744 pango_layout_get_pixel_extents(pLayout, m_pPangoInk, NULL);
746 int height=m_pPangoInk->height/2;
747 guchar back=255;
748 int value,black;
749 double alpha;
750 for (int i=m_pPangoInk->y;i<m_pPangoInk->y+m_pPangoInk->height;i++)
751 if ((i+y1-height<m_iHeight) &&(i+y1-height>=0))
752 for(int j=m_pPangoInk->x;j<+m_pPangoInk->x+m_pPangoInk->width;j++)
753 if ((j+x1>=0)&&(j+x1<m_iWidth))
755 display_fontdata[i*display_fontwidth*display_fontdepth+j*display_fontdepth]=back;
756 display_fontdata[i*display_fontwidth*display_fontdepth+j*display_fontdepth+1]=back;
757 display_fontdata[i*display_fontwidth*display_fontdepth+j*display_fontdepth+2]=back;
760 #if WITH_CAIRO
761 pango_cairo_show_layout(display_fontcairo, pLayout);
762 #else
764 GdkColormap* colormap=gdk_colormap_get_system();
765 GdkColor _c = colours[4];
766 gdk_colormap_alloc_color(colormap, &_c, FALSE, TRUE);
767 gdk_gc_set_foreground (graphics_context, &_c);
768 gdk_draw_layout(display_fontgdk, graphics_context, 0,0, pLayout);
770 #endif
773 for (int i=m_pPangoInk->y;i<m_pPangoInk->y+m_pPangoInk->height;i++)
774 if ((i+y1-height<m_iHeight) &&(i+y1-height>=0))
776 for(int j=m_pPangoInk->x;j<+m_pPangoInk->x+m_pPangoInk->width;j++)
777 if ((j+x1>=0)&&(j+x1<m_iWidth))
779 if (display_fontdata[i*display_fontwidth*display_fontdepth+j*display_fontdepth+0]!=back)
781 value = display_fontdata[i*display_fontwidth*display_fontdepth+j*display_fontdepth+0];
782 alpha =(double)value/256.0;
783 black = (int )(value * (1-alpha));
785 display_data[(i+y1-height)*m_iWidth*display_depth+(j+x1)*display_depth]=int (display_data[(i+y1-height)*m_iWidth*display_depth+(j+x1)*display_depth]*alpha)+black;
787 display_data[(i+y1-height)*m_iWidth*display_depth+(j+x1)*display_depth+1]=int (display_data[(i+y1-height)*m_iWidth*display_depth+(j+x1)*display_depth+1]*alpha)+black;
789 display_data[(i+y1-height)*m_iWidth*display_depth+(j+x1)*display_depth+2]=int (display_data[(i+y1-height)*m_iWidth*display_depth+(j+x1)*display_depth+2]*alpha)+black;
797 void CCanvas::TextSize(const std::string &String, int *Width, int *Height, int size) {
799 #if WITH_CAIRO
800 PangoLayout *pLayout(m_pPangoCache->GetLayout(display_fontcairo, String, size));
801 #else
802 PangoLayout *pLayout(m_pPangoCache->GetLayout(GTK_WIDGET(m_pCanvas), String, size));
803 #endif
804 pango_layout_get_pixel_extents(pLayout, m_pPangoInk, NULL);
806 *Width = m_pPangoInk->width;
807 *Height = m_pPangoInk->height;
811 void CCanvas::SendMarker(int iMarker) {
813 switch(iMarker) {
814 case 0: // Switch to display buffer
817 break;
818 case 1: // Switch to decorations buffer
819 StoreBackground();
820 LoadBackground();
821 #ifdef FRAMERATE_DIAGNOSTICS
822 NewFrame();
823 #endif
824 break;
828 void CCanvas::SetColourScheme(const CColourIO::ColourInfo *pColourScheme) {
829 int iNumColours(pColourScheme->Reds.size());
831 #if WITH_CAIRO
832 if (cairo_colours)
833 delete[] cairo_colours;
834 cairo_colours = new my_cairo_colour_t[iNumColours];
835 #else
836 if (colours)
837 delete[] colours;
838 colours = new GdkColor[iNumColours];
839 #endif
841 for(int i = 0; i < iNumColours; i++) {
842 #if WITH_CAIRO
843 cairo_colours[i].r = pColourScheme->Reds[i] / 255.0;
844 cairo_colours[i].g = pColourScheme->Greens[i] / 255.0;
845 cairo_colours[i].b = pColourScheme->Blues[i] / 255.0;
846 #else
847 colours[i].pixel=0;
848 colours[i].red=pColourScheme->Reds[i]*257;
849 colours[i].green=pColourScheme->Greens[i]*257;
850 colours[i].blue=pColourScheme->Blues[i]*257;
851 #endif
854 void CCanvas::SetLoadBackground(bool value)
857 m_bLoadBackground=value;
859 void CCanvas::SetCaptureBackground(bool value)
861 m_bCaptureBackground=value;
863 void CCanvas::StoreBackground()
865 if (m_bCaptureBackground)
867 for (int i=0;i<m_iWidth*m_iHeight*display_depth;i++)
868 display_backgrounddata[i]=display_data[i];
869 m_bCaptureBackground=false;
874 void CCanvas::LoadBackground()
876 if (m_bLoadBackground)
878 for (int i=0;i<m_iWidth*m_iHeight*display_depth;i++)
879 display_data[i]=display_backgrounddata[i];
884 bool CCanvas::GetCanvasSize(GdkRectangle *pRectangle)
886 if ((pRectangle == NULL) || (m_pCanvas == NULL))
887 return false;
889 // Using gtk_window_get_frame_extents() only seems to return the position
890 // and size of the parent Dasher window. So we'll get the widgets position
891 // and use its size to determine the bounding rectangle.
892 int iX = 0;
893 int iY = 0;
895 gdk_window_get_position(m_pCanvas->window, &iX, &iY);
897 pRectangle->x = iX;
898 pRectangle->y = iY;
899 pRectangle->width = m_iWidth;
900 pRectangle->height = m_iHeight;
902 return true;
904 void CCanvas::ChangeState(int value)
909 #ifdef FRAMERATE_DIAGNOSTICS
910 void CCanvas::NewFrame()
912 count_frames++;
913 time_t seconds=time(NULL);
914 float average=0;
915 if (lasttime==-1) lasttime=seconds;
916 time_t temp=seconds-lasttime;
918 if (temp>=1)
920 count_time += temp;
921 if (count_time!=1)
923 total_frames+=count_frames;
924 average=(float)total_frames/(float)(count_time-1);
926 printf("New second %ld had %d frames, the averages is %f, total frames=%ld\n ",count_time,count_frames,average,total_frames);
927 count_frames=0;
929 #ifdef IGNAS_FRAME_PRINT
930 printf("OLD FRAME%d\n",count_rectangles);
931 #endif
932 count_rectangles=0;
933 lasttime=seconds;
937 #endif