1 /* -*- mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: t -*- */
2 /* AbiWord
3 * Copyright (C) 2004-2006 Tomas Frydrych <dr.tomas@yahoo.co.uk>
4 * Copyright (C) 2009-2016 Hubert Figuiere
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA.
20 */
21
22 #include "ut_bytebuf.h"
23
24 #include "gr_UnixCairoGraphics.h"
25 #include "gr_CairoImage.h"
26 #include "gr_Painter.h"
27 #include "gr_UnixImage.h"
28
29 #include "xap_App.h"
30 #include "xap_EncodingManager.h"
31 #if GTK_CHECK_VERSION(3,0,0)
32 #include "xap_GtkStyle.h"
33 #endif
34
~GR_UnixCairoGraphicsBase()35 GR_UnixCairoGraphicsBase::~GR_UnixCairoGraphicsBase()
36 {
37 }
38
39 /*!
40 * Create a new image from the Raster rgba byte buffer defined by pBB.
41 * The dimensions of iWidth and iHeight are in logical units but the image
42 * doesn't scale if the resolution or zoom changes. Instead you must create
43 * a new image.
44 */
createNewImage(const char * pszName,const UT_ByteBuf * pBB,const std::string & mimetype,UT_sint32 iWidth,UT_sint32 iHeight,GR_Image::GRType iType)45 GR_Image* GR_UnixCairoGraphicsBase::createNewImage (const char* pszName,
46 const UT_ByteBuf* pBB,
47 const std::string& mimetype,
48 UT_sint32 iWidth,
49 UT_sint32 iHeight,
50 GR_Image::GRType iType)
51 {
52 GR_Image* pImg = NULL;
53
54 if (iType == GR_Image::GRT_Raster) {
55 pImg = new GR_UnixImage(pszName);
56 pImg->convertFromBuffer(pBB, mimetype, tdu(iWidth), tdu(iHeight));
57 } else if (iType == GR_Image::GRT_Vector) {
58 pImg = new GR_RSVGVectorImage(pszName);
59 pImg->convertFromBuffer(pBB, mimetype, tdu(iWidth), tdu(iHeight));
60 } else {
61 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
62 }
63
64 return pImg;
65 }
66
GR_UnixCairoGraphicsBase()67 GR_UnixCairoGraphicsBase::GR_UnixCairoGraphicsBase()
68 : GR_CairoGraphics()
69 {
70 }
71
GR_UnixCairoGraphicsBase(cairo_t * cr,UT_uint32 iDeviceResolution)72 GR_UnixCairoGraphicsBase::GR_UnixCairoGraphicsBase(cairo_t *cr, UT_uint32 iDeviceResolution)
73 : GR_CairoGraphics(cr, iDeviceResolution)
74 {
75 }
76
GR_UnixCairoGraphics(GdkWindow * win,bool double_buffered)77 GR_UnixCairoGraphics::GR_UnixCairoGraphics(GdkWindow * win, bool double_buffered)
78 : GR_UnixCairoGraphicsBase(),
79 m_pWin(win),
80 m_double_buffered(double_buffered),
81 m_CairoCreated(false),
82 m_Painting(false),
83 m_Signal(0),
84 m_DestroySignal(0),
85 #if GTK_CHECK_VERSION(3,0,0)
86 m_Widget(NULL),
87 m_styleBg(NULL),
88 m_styleHighlight(NULL)
89 #else
90 m_Widget(NULL)
91 #endif
92 {
93 m_cr = NULL;
94 if (_getWindow())
95 {
96 // Set GraphicsExposes so that XCopyArea() causes an expose on
97 // obscured regions rather than just tiling in the default background.
98 // TODO: is this still needed with cairo, and if yes can it be emulated
99 // without having m_pGC any more?
100 // gdk_gc_set_exposures(m_pGC, 1);
101 setCursor(GR_CURSOR_DEFAULT);
102 }
103 }
104
~GR_UnixCairoGraphics()105 GR_UnixCairoGraphics::~GR_UnixCairoGraphics()
106 {
107 if (m_Widget) {
108 g_signal_handler_disconnect (m_Widget, m_Signal);
109 g_signal_handler_disconnect (m_Widget, m_DestroySignal);
110 }
111 #if GTK_CHECK_VERSION(3,0,0)
112 if (m_styleBg) {
113 g_object_unref(m_styleBg);
114 }
115 if (m_styleHighlight) {
116 g_object_unref(m_styleHighlight);
117 }
118 #endif
119 }
120
121
graphicsAllocator(GR_AllocInfo & info)122 GR_Graphics * GR_UnixCairoGraphics::graphicsAllocator(GR_AllocInfo& info)
123 {
124 UT_return_val_if_fail(info.getType() == GRID_UNIX, NULL);
125 xxx_UT_DEBUGMSG(("GR_CairoGraphics::graphicsAllocator\n"));
126
127 // UT_return_val_if_fail(!info.isPrinterGraphics(), NULL);
128 GR_UnixCairoAllocInfo &AI = (GR_UnixCairoAllocInfo&)info;
129 #if GTK_CHECK_VERSION(3,0,0)
130 // We disable double buffering on Gtk3 because it doesn't work.
131 return new GR_UnixCairoGraphics(AI.m_win, false);
132 #else
133 return new GR_UnixCairoGraphics(AI.m_win, AI.m_double_buffered);
134 #endif
135 }
136
_convertGdkColor(const GdkColor & c)137 inline UT_RGBColor _convertGdkColor(const GdkColor &c)
138 {
139 UT_RGBColor color;
140 color.m_red = c.red >> 8;
141 color.m_grn = c.green >> 8;
142 color.m_blu = c.blue >> 8;
143 return color;
144 }
145
146 #if GTK_CHECK_VERSION(3,0,0)
_convertGdkRGBA(const GdkRGBA & c)147 inline UT_RGBColor _convertGdkRGBA(const GdkRGBA &c)
148 {
149 UT_RGBColor color;
150 color.m_red = c.red * 255;
151 color.m_grn = c.green * 255;
152 color.m_blu = c.blue * 255;
153 return color;
154 }
155 #endif
156
widget_size_allocate(GtkWidget *,GtkAllocation *,GR_UnixCairoGraphics * me)157 void GR_UnixCairoGraphics::widget_size_allocate(GtkWidget* /*widget*/, GtkAllocation* /*allocation*/, GR_UnixCairoGraphics* me)
158 {
159 UT_return_if_fail(me);
160 me->m_clipRectDirty = TRUE;
161 }
162
widget_destroy(GtkWidget * widget,GR_UnixCairoGraphics * me)163 void GR_UnixCairoGraphics::widget_destroy(GtkWidget* widget, GR_UnixCairoGraphics* me)
164 {
165 UT_return_if_fail(me && me->m_Widget == widget);
166 me->m_Widget = NULL;
167 me->m_Signal = 0;
168 me->m_DestroySignal = 0;
169 }
170
initWidget(GtkWidget * widget)171 void GR_UnixCairoGraphics::initWidget(GtkWidget* widget)
172 {
173 UT_return_if_fail(widget && m_Widget == NULL);
174 m_Widget = widget;
175 m_Signal = g_signal_connect_after(G_OBJECT(widget), "size_allocate", G_CALLBACK(widget_size_allocate), this);
176 m_DestroySignal = g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(widget_destroy), this);
177 }
178
179 #if GTK_CHECK_VERSION(3,0,0)
180 #define COLOR_MIX 0.67 //COLOR_MIX should be between 0 and 1
181 #define SQUARE(A) (A)*(A)
init3dColors(GtkWidget *)182 void GR_UnixCairoGraphics::init3dColors(GtkWidget* /*w*/)
183 {
184 if (m_styleBg) {
185 g_object_unref(m_styleBg);
186 }
187 m_styleBg = XAP_GtkStyle_get_style(NULL, "GtkButton"); // "button"
188 // guess colours
189 // WHITE
190 GdkRGBA rgba2;
191 rgba2.red = 1.;
192 rgba2.green = 1.;
193 rgba2.blue = 1.;
194 rgba2.alpha = 1;
195 // this is the colour used notably for the the ruler.
196 // Gray-ish in adwaita, black in Dark theme
197 m_3dColors[CLR3D_Background] = _convertGdkRGBA(rgba2);
198
199 // this is white in Adwaita, and black in a dark theme.
200 GdkRGBA rgba1;
201 if (m_styleHighlight) {
202 g_object_unref(m_styleHighlight);
203 }
204 m_styleHighlight = XAP_GtkStyle_get_style(NULL, "GtkTreeView.view"); // "textview.view"
205 gtk_style_context_get_color (m_styleHighlight, GTK_STATE_FLAG_NORMAL, &rgba1);
206 m_3dColors[CLR3D_Highlight] = _convertGdkRGBA(rgba1);
207
208 // guess colours.
209 // BLACK
210 rgba1.red = 0.;
211 rgba1.green = 0.;
212 rgba1.blue = 0.;
213 rgba1.alpha = 1;
214
215 GdkRGBA rgba_;
216 rgba_.alpha = 1.; // we don't really care, abiword does not use transparency
217 rgba_.red = rgba1.red*COLOR_MIX + rgba2.red*(1.-COLOR_MIX);
218 rgba_.green = rgba1.green*COLOR_MIX + rgba2.green*(1.-COLOR_MIX);
219 rgba_.blue = rgba1.blue*COLOR_MIX + rgba2.blue*(1.-COLOR_MIX);
220 m_3dColors[CLR3D_BevelUp] = _convertGdkRGBA(rgba_);
221
222 rgba_.red = rgba1.red*(1.-COLOR_MIX) + rgba2.red*COLOR_MIX;
223 rgba_.green = rgba1.green*(1.-COLOR_MIX) + rgba2.green*COLOR_MIX;
224 rgba_.blue = rgba1.blue*(1.-COLOR_MIX) + rgba2.blue*COLOR_MIX;
225 m_3dColors[CLR3D_BevelDown] = _convertGdkRGBA(rgba_);
226
227
228 GtkStyleContext *text_style = XAP_GtkStyle_get_style(NULL, "GtkLabel.view"); // "label.view"
229 gtk_style_context_get_color (text_style, GTK_STATE_FLAG_NORMAL, &rgba2);
230 m_3dColors[CLR3D_Foreground] = _convertGdkRGBA(rgba2);
231 g_object_unref(text_style);
232
233 m_bHave3DColors = true;
234 }
235 #undef COLOR_MIX
236 #undef SQUARE
237 #else
init3dColors(GtkWidget * w)238 void GR_UnixCairoGraphics::init3dColors(GtkWidget* w)
239 {
240 init3dColors(w->style);
241 }
init3dColors(GtkStyle * pStyle)242 void GR_UnixCairoGraphics::init3dColors(GtkStyle* pStyle)
243 {
244 m_3dColors[CLR3D_Foreground] = _convertGdkColor(pStyle->text[GTK_STATE_NORMAL]);
245 m_3dColors[CLR3D_Background] = _convertGdkColor(pStyle->bg[GTK_STATE_NORMAL]);
246 m_3dColors[CLR3D_BevelUp] = _convertGdkColor(pStyle->light[GTK_STATE_NORMAL]);
247 m_3dColors[CLR3D_BevelDown] = _convertGdkColor(pStyle->dark[GTK_STATE_NORMAL]);
248 m_3dColors[CLR3D_Highlight] = _convertGdkColor(pStyle->bg[GTK_STATE_PRELIGHT]);
249
250 m_bHave3DColors = true;
251 }
252 #endif
253
getGUIFont(void)254 GR_Font * GR_UnixCairoGraphics::getGUIFont(void)
255 {
256 if (!m_pPFontGUI)
257 {
258 // get the font resource
259 #if GTK_CHECK_VERSION(3,0,0)
260 GtkStyleContext *tempCtxt = gtk_style_context_new();
261 GtkWidgetPath *path = gtk_widget_path_new();
262 gtk_widget_path_append_type (path, GTK_TYPE_WINDOW);
263 gtk_style_context_set_path(tempCtxt, path);
264 gtk_widget_path_free(path);
265 PangoFontDescription* fontDesc;
266 gtk_style_context_get(tempCtxt, GTK_STATE_FLAG_NORMAL, "font", &fontDesc, NULL);
267 const char *guiFontName = pango_font_description_get_family(fontDesc);
268 #else
269 GtkStyle *tempStyle = gtk_style_new();
270 const char *guiFontName = pango_font_description_get_family(tempStyle->font_desc);
271 #endif
272 if (!guiFontName)
273 guiFontName = "'Times New Roman'";
274
275 UT_UTF8String s = XAP_EncodingManager::get_instance()->getLanguageISOName();
276
277 const char * pCountry
278 = XAP_EncodingManager::get_instance()->getLanguageISOTerritory();
279
280 if(pCountry)
281 {
282 s += "-";
283 s += pCountry;
284 }
285
286 m_pPFontGUI = new GR_PangoFont(guiFontName, 11.0, this, s.utf8_str(), true);
287
288 #if GTK_CHECK_VERSION(3,0,0)
289 pango_font_description_free(fontDesc);
290 g_object_unref(G_OBJECT(tempCtxt));
291 #else
292 g_object_unref(G_OBJECT(tempStyle));
293 #endif
294
295 UT_ASSERT(m_pPFontGUI);
296 }
297
298 return m_pPFontGUI;
299 }
300
301
setCursor(GR_Graphics::Cursor c)302 void GR_UnixCairoGraphics::setCursor(GR_Graphics::Cursor c)
303 {
304 if (m_cursor == c)
305 return;
306
307 m_cursor = c;
308
309 GdkCursorType cursor_number;
310
311 switch (c)
312 {
313 default:
314 UT_ASSERT(UT_NOT_IMPLEMENTED);
315 /*FALLTHRU*/
316 case GR_CURSOR_DEFAULT:
317 cursor_number = GDK_LEFT_PTR;
318 break;
319
320 case GR_CURSOR_IBEAM:
321 cursor_number = GDK_XTERM;
322 break;
323
324 //I have changed the shape of the arrow so get a consistent
325 //behaviour in the bidi build; I think the new arrow is better
326 //for the purpose anyway
327
328 case GR_CURSOR_RIGHTARROW:
329 cursor_number = GDK_SB_RIGHT_ARROW; //GDK_ARROW;
330 break;
331
332 case GR_CURSOR_LEFTARROW:
333 cursor_number = GDK_SB_LEFT_ARROW; //GDK_LEFT_PTR;
334 break;
335
336 case GR_CURSOR_IMAGE:
337 cursor_number = GDK_FLEUR;
338 break;
339
340 case GR_CURSOR_IMAGESIZE_NW:
341 cursor_number = GDK_TOP_LEFT_CORNER;
342 break;
343
344 case GR_CURSOR_IMAGESIZE_N:
345 cursor_number = GDK_TOP_SIDE;
346 break;
347
348 case GR_CURSOR_IMAGESIZE_NE:
349 cursor_number = GDK_TOP_RIGHT_CORNER;
350 break;
351
352 case GR_CURSOR_IMAGESIZE_E:
353 cursor_number = GDK_RIGHT_SIDE;
354 break;
355
356 case GR_CURSOR_IMAGESIZE_SE:
357 cursor_number = GDK_BOTTOM_RIGHT_CORNER;
358 break;
359
360 case GR_CURSOR_IMAGESIZE_S:
361 cursor_number = GDK_BOTTOM_SIDE;
362 break;
363
364 case GR_CURSOR_IMAGESIZE_SW:
365 cursor_number = GDK_BOTTOM_LEFT_CORNER;
366 break;
367
368 case GR_CURSOR_IMAGESIZE_W:
369 cursor_number = GDK_LEFT_SIDE;
370 break;
371
372 case GR_CURSOR_LEFTRIGHT:
373 cursor_number = GDK_SB_H_DOUBLE_ARROW;
374 break;
375
376 case GR_CURSOR_UPDOWN:
377 cursor_number = GDK_SB_V_DOUBLE_ARROW;
378 break;
379
380 case GR_CURSOR_EXCHANGE:
381 cursor_number = GDK_EXCHANGE;
382 break;
383
384 case GR_CURSOR_GRAB:
385 cursor_number = GDK_HAND1;
386 break;
387
388 case GR_CURSOR_LINK:
389 cursor_number = GDK_HAND2;
390 break;
391
392 case GR_CURSOR_WAIT:
393 cursor_number = GDK_WATCH;
394 break;
395
396 case GR_CURSOR_HLINE_DRAG:
397 cursor_number = GDK_SB_V_DOUBLE_ARROW;
398 break;
399
400 case GR_CURSOR_VLINE_DRAG:
401 cursor_number = GDK_SB_H_DOUBLE_ARROW;
402 break;
403
404 case GR_CURSOR_CROSSHAIR:
405 cursor_number = GDK_CROSSHAIR;
406 break;
407
408 case GR_CURSOR_DOWNARROW:
409 cursor_number = GDK_SB_DOWN_ARROW;
410 break;
411
412 case GR_CURSOR_DRAGTEXT:
413 cursor_number = GDK_TARGET;
414 break;
415
416 case GR_CURSOR_COPYTEXT:
417 cursor_number = GDK_DRAPED_BOX;
418 break;
419 }
420 xxx_UT_DEBUGMSG(("cursor set to %d gdk %d \n",c,cursor_number));
421 GdkCursor * cursor = gdk_cursor_new(cursor_number);
422 gdk_window_set_cursor(m_pWin, cursor);
423 #if GTK_CHECK_VERSION(3,0,0)
424 g_object_unref(cursor);
425 #else
426 gdk_cursor_unref(cursor);
427 #endif
428 }
429
430
scroll(UT_sint32 dx,UT_sint32 dy)431 void GR_UnixCairoGraphics::scroll(UT_sint32 dx, UT_sint32 dy)
432 {
433 UT_sint32 oldDY = tdu(getPrevYOffset());
434 UT_sint32 oldDX = tdu(getPrevXOffset());
435 UT_sint32 newY = getPrevYOffset() + dy;
436 UT_sint32 newX = getPrevXOffset() + dx;
437 UT_sint32 ddx = -(tdu(newX) - oldDX);
438 UT_sint32 ddy = -(tdu(newY) - oldDY);
439 setPrevYOffset(newY);
440 setPrevXOffset(newX);
441 if(ddx == 0 && ddy == 0)
442 {
443 return;
444 }
445
446 disableAllCarets();
447
448 UT_sint32 iddy = labs(ddy);
449 bool bEnableSmooth = XAP_App::getApp()->isSmoothScrollingEnabled();
450 bEnableSmooth = bEnableSmooth && (iddy < 30) && (ddx == 0);
451 if(bEnableSmooth)
452 {
453 if(ddy < 0)
454 {
455 UT_sint32 i = 0;
456 for(i = 0; i< iddy; i++)
457 {
458 gdk_window_scroll(m_pWin,0,-1);
459 }
460 }
461 else
462 {
463 UT_sint32 i = 0;
464 for(i = 0; i< iddy; i++)
465 {
466 gdk_window_scroll(m_pWin,0,1);
467 }
468 }
469 }
470 else
471 {
472 gdk_window_scroll(m_pWin,ddx,ddy);
473 }
474 enableAllCarets();
475 }
476
scroll(UT_sint32 x_dest,UT_sint32 y_dest,UT_sint32 x_src,UT_sint32 y_src,G_GNUC_UNUSED UT_sint32 width,G_GNUC_UNUSED UT_sint32 height)477 void GR_UnixCairoGraphics::scroll(UT_sint32 x_dest, UT_sint32 y_dest,
478 UT_sint32 x_src, UT_sint32 y_src,
479 G_GNUC_UNUSED UT_sint32 width, G_GNUC_UNUSED UT_sint32 height)
480 {
481 #if !GTK_CHECK_VERSION(3,0,0)
482 GdkGC *gc;
483
484 disableAllCarets();
485 gc = gdk_gc_new(_getWindow());
486 gdk_draw_drawable(_getWindow(), gc, _getWindow(), tdu(x_src), tdu(y_src),
487 tdu(x_dest), tdu(y_dest), tdu(width), tdu(height));
488 g_object_unref(G_OBJECT(gc)), gc = NULL;
489 enableAllCarets();
490 #else
491 scroll(x_src - x_dest, y_src - y_dest);
492 #endif
493 }
494
_resetClip(void)495 void GR_UnixCairoGraphics::_resetClip(void)
496 {
497
498 cairo_reset_clip (m_cr);
499 xxx_UT_DEBUGMSG(("Reset clip in gtk cairo \n"));
500 }
501
502 /*!
503 * Take a screenshot of the graphics and convert it to an image.
504 */
genImageFromRectangle(const UT_Rect & rec)505 GR_Image * GR_UnixCairoGraphics::genImageFromRectangle(const UT_Rect &rec)
506 {
507 UT_sint32 idx = _tduX(rec.left);
508 UT_sint32 idy = _tduY(rec.top);
509 UT_sint32 idw = _tduR(rec.width);
510 UT_sint32 idh = _tduR(rec.height);
511 UT_return_val_if_fail (idw > 0 && idh > 0 && idx >= 0, NULL);
512 cairo_surface_flush ( cairo_get_target(m_cr));
513 #if !GTK_CHECK_VERSION(3,0,0)
514 GdkColormap* cmp = gdk_colormap_get_system();
515 GdkPixbuf * pix = gdk_pixbuf_get_from_drawable(NULL,
516 _getWindow(),
517 cmp,
518 idx, idy, 0, 0,
519 idw, idh);
520 #else
521 GdkPixbuf * pix = gdk_pixbuf_get_from_window(getWindow(),
522 idx, idy,
523 idw, idh);
524 #endif
525 UT_return_val_if_fail(pix, NULL);
526
527 GR_UnixImage * pImg = new GR_UnixImage("ScreenShot");
528 pImg->setData(pix);
529 pImg->setDisplaySize(idw,idh);
530 return pImg;
531 }
532
_beginPaint()533 void GR_UnixCairoGraphics::_beginPaint()
534 {
535 UT_ASSERT(m_Painting == false);
536 GR_CairoGraphics::_beginPaint();
537
538 if (m_cr == NULL)
539 {
540 UT_ASSERT(m_pWin);
541 m_cr = gdk_cairo_create (m_pWin);
542 m_CairoCreated = true;
543 }
544
545 #ifndef NDEBUG
546 /* should only be called inside an expose event, messes up
547 * double-buffering and all sorts of other GTK assumptions otherwise
548 * we make this extra effort here to track down old wrong code
549 */
550 /* for the time being, ignore it for non-double-buffered widgets that
551 * might be very hard to migrate */
552 if (m_double_buffered)
553 {
554 GdkEvent *ev = gtk_get_current_event();
555 UT_ASSERT(ev);
556 if (ev)
557 {
558 UT_ASSERT(ev->type == GDK_EXPOSE || ev->type == GDK_DAMAGE);
559 if (ev->type == GDK_EXPOSE || ev->type == GDK_DAMAGE)
560 UT_ASSERT(ev->expose.window == m_pWin || ev->expose.window == gdk_window_get_effective_parent (m_pWin));
561 }
562 }
563 #endif
564
565 UT_ASSERT(m_cr);
566 m_Painting = true;
567 _initCairo();
568 }
569
_endPaint()570 void GR_UnixCairoGraphics::_endPaint()
571 {
572 if (m_CairoCreated)
573 {
574 cairo_surface_flush(cairo_get_target(m_cr));
575 cairo_destroy (m_cr);
576 }
577 m_cr = NULL;
578
579 m_Painting = false;
580 m_CairoCreated = false;
581
582 GR_CairoGraphics::_endPaint();
583 }
584
flush(void)585 void GR_UnixCairoGraphics::flush(void)
586 {
587
588 if (m_Widget) {
589 gtk_widget_queue_draw(m_Widget);
590 }
591
592 /*
593 if(m_cr)
594 {
595 cairo_surface_flush(cairo_get_target(m_cr));
596 }
597 */
598 }
599
queryProperties(GR_Graphics::Properties gp) const600 bool GR_UnixCairoGraphics::queryProperties(GR_Graphics::Properties gp) const
601 {
602 switch (gp)
603 {
604 case DGP_SCREEN:
605 case DGP_OPAQUEOVERLAY:
606 return m_pWin != NULL;
607 case DGP_PAPER:
608 return false;
609 default:
610 UT_ASSERT(0);
611 return false;
612 }
613 }
614
615 #if GTK_CHECK_VERSION(3,0,0)
getColor3D(GR_Color3D name,UT_RGBColor & color)616 bool GR_UnixCairoGraphics::getColor3D(GR_Color3D name, UT_RGBColor &color)
617 {
618 switch(name) {
619 case GR_Graphics::CLR3D_Background:
620 case GR_Graphics::CLR3D_Highlight:
621 return false;
622
623 default:
624 return GR_CairoGraphics::getColor3D(name, color);
625 }
626 }
627
628 /**
629 * This is an override that will use the GtkStyle code to actually render
630 * directly.
631 */
fillRect(GR_Color3D c,UT_sint32 x,UT_sint32 y,UT_sint32 w,UT_sint32 h)632 void GR_UnixCairoGraphics::fillRect(GR_Color3D c, UT_sint32 x, UT_sint32 y,
633 UT_sint32 w, UT_sint32 h)
634 {
635 switch(c) {
636 case GR_Graphics::CLR3D_Background:
637 case GR_Graphics::CLR3D_Highlight:
638 {
639 if (m_cr == NULL) {
640 return;
641 }
642 _setProps();
643 cairo_save (m_cr);
644
645 GtkStyleContext *context = NULL;
646 switch(c) {
647 case GR_Graphics::CLR3D_Background:
648 context = m_styleBg;
649 break;
650 case GR_Graphics::CLR3D_Highlight:
651 context = m_styleHighlight;
652 break;
653 default:
654 UT_ASSERT(0);
655 return;
656 }
657 gtk_render_background (context, m_cr, tdu(x), tdu(y), tdu(w), tdu(h));
658 gtk_render_frame (context, m_cr, tdu(x), tdu(y), tdu(w), tdu(h));
659 cairo_restore (m_cr);
660 break;
661 }
662 default:
663 GR_CairoGraphics::fillRect(c, x, y, w, h);
664 return;
665 }
666 }
667 #endif
668