Browse Source

gtk-stats: Use cairo instead of GDK for drawing

Drawing via GDK is deprecated and no longer supported in GTK 3
rdb 3 năm trước cách đây
mục cha
commit
4c3bc5a42e

+ 42 - 59
pandatool/src/gtk-stats/gtkStatsGraph.cxx

@@ -15,20 +15,14 @@
 #include "gtkStatsMonitor.h"
 #include "gtkStatsLabelStack.h"
 
-const GdkColor GtkStatsGraph::rgb_white = {
-  0, 0xffff, 0xffff, 0xffff
+const double GtkStatsGraph::rgb_light_gray[3] = {
+  0x9a / (double)0xff, 0x9a / (double)0xff, 0x9a / (double)0xff,
 };
-const GdkColor GtkStatsGraph::rgb_light_gray = {
-  0, 0x9a9a, 0x9a9a, 0x9a9a,
+const double GtkStatsGraph::rgb_dark_gray[3] = {
+  0x33 / (double)0xff, 0x33 / (double)0xff, 0x33 / (double)0xff,
 };
-const GdkColor GtkStatsGraph::rgb_dark_gray = {
-  0, 0x3333, 0x3333, 0x3333,
-};
-const GdkColor GtkStatsGraph::rgb_black = {
-  0, 0x0000, 0x0000, 0x0000
-};
-const GdkColor GtkStatsGraph::rgb_user_guide_bar = {
-  0, 0x8282, 0x9696, 0xffff
+const double GtkStatsGraph::rgb_user_guide_bar[3] = {
+  0x82 / (double)0xff, 0x96 / (double)0xff, 0xff / (double)0xff,
 };
 
 /**
@@ -48,11 +42,11 @@ GtkStatsGraph(GtkStatsMonitor *monitor) :
   GdkDisplay *display = gdk_window_get_display(gtk_widget_get_window(parent_window));
   _hand_cursor = gdk_cursor_new_for_display(display, GDK_HAND2);
 
-  _pixmap = nullptr;
-  _pixmap_gc = nullptr;
+  _cr_surface = nullptr;
+  _cr = nullptr;
 
-  _pixmap_xsize = 0;
-  _pixmap_ysize = 0;
+  _surface_xsize = 0;
+  _surface_ysize = 0;
 
   _window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
@@ -128,12 +122,11 @@ GtkStatsGraph(GtkStatsMonitor *monitor) :
 GtkStatsGraph::
 ~GtkStatsGraph() {
   _monitor = nullptr;
-  release_pixmap();
+  release_surface();
 
   Brushes::iterator bi;
   for (bi = _brushes.begin(); bi != _brushes.end(); ++bi) {
-    GdkGC *gc = (*bi).second;
-    g_object_unref(gc);
+    cairo_pattern_destroy((*bi).second);
   }
 
   _label_stack.clear_labels();
@@ -236,10 +229,10 @@ close() {
 }
 
 /**
- * Returns a GC suitable for drawing in the indicated collector's color.
+ * Returns a pattern suitable for drawing in the indicated collector's color.
  */
-GdkGC *GtkStatsGraph::
-get_collector_gc(int collector_index) {
+cairo_pattern_t *GtkStatsGraph::
+get_collector_pattern(int collector_index) {
   Brushes::iterator bi;
   bi = _brushes.find(collector_index);
   if (bi != _brushes.end()) {
@@ -248,17 +241,10 @@ get_collector_gc(int collector_index) {
 
   // Ask the monitor what color this guy should be.
   LRGBColor rgb = _monitor->get_collector_color(collector_index);
+  cairo_pattern_t *pattern = cairo_pattern_create_rgb(rgb[0], rgb[1], rgb[2]);
 
-  GdkColor c;
-  c.red = (int)(rgb[0] * 65535.0f);
-  c.green = (int)(rgb[1] * 65535.0f);
-  c.blue = (int)(rgb[2] * 65535.0f);
-  GdkGC *gc = gdk_gc_new(_pixmap);
-  // g_object_ref(gc);   Should this be ref_sink?
-  gdk_gc_set_rgb_fg_color(gc, &c);
-
-  _brushes[collector_index] = gc;
-  return gc;
+  _brushes[collector_index] = pattern;
+  return pattern;
 }
 
 /**
@@ -266,7 +252,7 @@ get_collector_gc(int collector_index) {
  * class opportunity to do some further painting into the graph window.
  */
 void GtkStatsGraph::
-additional_graph_window_paint() {
+additional_graph_window_paint(cairo_t *cr) {
 }
 
 /**
@@ -340,31 +326,27 @@ handle_motion(GtkWidget *widget, int graph_x, int graph_y) {
  * Sets up a backing-store bitmap of the indicated size.
  */
 void GtkStatsGraph::
-setup_pixmap(int xsize, int ysize) {
-  release_pixmap();
+setup_surface(int xsize, int ysize) {
+  release_surface();
 
-  _pixmap_xsize = std::max(xsize, 0);
-  _pixmap_ysize = std::max(ysize, 0);
+  _surface_xsize = std::max(xsize, 0);
+  _surface_ysize = std::max(ysize, 0);
 
-  GdkWindow *window = gtk_widget_get_window(_graph_window);
-  _pixmap = gdk_pixmap_new(window, _pixmap_xsize, _pixmap_ysize, -1);
-  // g_object_ref(_pixmap);   Should this be ref_sink?
-  _pixmap_gc = gdk_gc_new(_pixmap);
-  // g_object_ref(_pixmap_gc);    Should this be ref_sink?
+  _cr_surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, _surface_xsize, _surface_ysize);
+  _cr = cairo_create(_cr_surface);
 
-  gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
-  gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, 0, 0,
-         _pixmap_xsize, _pixmap_ysize);
+  cairo_set_source_rgb(_cr, 1.0, 1.0, 1.0);
+  cairo_paint(_cr);
 }
 
 /**
- * Frees the backing-store bitmap created by setup_pixmap().
+ * Frees the backing-store bitmap created by setup_surface().
  */
 void GtkStatsGraph::
-release_pixmap() {
-  if (_pixmap != nullptr) {
-    g_object_unref(_pixmap);
-    g_object_unref(_pixmap_gc);
+release_surface() {
+  if (_cr_surface != nullptr) {
+    cairo_surface_destroy(_cr_surface);
+    cairo_destroy(_cr);
   }
 }
 
@@ -394,16 +376,17 @@ gboolean GtkStatsGraph::
 graph_expose_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
   GtkStatsGraph *self = (GtkStatsGraph *)data;
 
-  if (self->_pixmap != nullptr) {
-    GdkWindow *window = gtk_widget_get_window(self->_graph_window);
-    GtkStyle *style = gtk_widget_get_style(self->_graph_window);
-    gdk_draw_drawable(window,
-          style->fg_gc[0],
-          self->_pixmap, 0, 0, 0, 0,
-          self->_pixmap_xsize, self->_pixmap_ysize);
+  GdkWindow *window = gtk_widget_get_window(self->_graph_window);
+  cairo_t *cr = gdk_cairo_create(window);
+
+  if (self->_cr_surface != nullptr) {
+    cairo_set_source_surface(cr, self->_cr_surface, 0, 0);
+    cairo_paint(cr);
   }
 
-  self->additional_graph_window_paint();
+  self->additional_graph_window_paint(cr);
+
+  cairo_destroy(cr);
 
   return TRUE;
 }
@@ -417,7 +400,7 @@ configure_graph_callback(GtkWidget *widget, GdkEventConfigure *event,
   GtkStatsGraph *self = (GtkStatsGraph *)data;
 
   self->changed_graph_size(event->width, event->height);
-  self->setup_pixmap(event->width, event->height);
+  self->setup_surface(event->width, event->height);
   self->force_redraw();
 
   return TRUE;

+ 15 - 14
pandatool/src/gtk-stats/gtkStatsGraph.h

@@ -19,6 +19,7 @@
 #include "pmap.h"
 
 #include <gtk/gtk.h>
+#include <cairo.h>
 
 class GtkStatsMonitor;
 
@@ -55,9 +56,9 @@ public:
 
 protected:
   void close();
-  GdkGC *get_collector_gc(int collector_index);
+  cairo_pattern_t *get_collector_pattern(int collector_index);
 
-  virtual void additional_graph_window_paint();
+  virtual void additional_graph_window_paint(cairo_t *cr);
   virtual DragMode consider_drag_start(int graph_x, int graph_y);
   virtual void set_drag_mode(DragMode drag_mode);
 
@@ -67,8 +68,8 @@ protected:
   virtual gboolean handle_motion(GtkWidget *widget, int graph_x, int graph_y);
 
 protected:
-  // Table of GC's for our various collectors.
-  typedef pmap<int, GdkGC *> Brushes;
+  // Table of patterns for our various collectors.
+  typedef pmap<int, cairo_pattern_t *> Brushes;
   Brushes _brushes;
 
   GtkStatsMonitor *_monitor;
@@ -83,9 +84,9 @@ protected:
 
   GdkCursor *_hand_cursor;
 
-  GdkPixmap *_pixmap;
-  GdkGC *_pixmap_gc;
-  int _pixmap_xsize, _pixmap_ysize;
+  cairo_surface_t *_cr_surface;
+  cairo_t *_cr;
+  int _surface_xsize, _surface_ysize;
 
   /*
   COLORREF _dark_color;
@@ -104,15 +105,15 @@ protected:
 
   bool _pause;
 
-  static const GdkColor rgb_white;
-  static const GdkColor rgb_light_gray;
-  static const GdkColor rgb_dark_gray;
-  static const GdkColor rgb_black;
-  static const GdkColor rgb_user_guide_bar;
+  static const double rgb_white[3];
+  static const double rgb_light_gray[3];
+  static const double rgb_dark_gray[3];
+  static const double rgb_black[3];
+  static const double rgb_user_guide_bar[3];
 
 private:
-  void setup_pixmap(int xsize, int ysize);
-  void release_pixmap();
+  void setup_surface(int xsize, int ysize);
+  void release_surface();
 
   static gboolean window_delete_event(GtkWidget *widget, GdkEvent *event,
               gpointer data);

+ 16 - 21
pandatool/src/gtk-stats/gtkStatsLabel.cxx

@@ -15,6 +15,8 @@
 #include "gtkStatsMonitor.h"
 #include "gtkStatsGraph.h"
 
+#include <cairo.h>
+
 int GtkStatsLabel::_left_margin = 2;
 int GtkStatsLabel::_right_margin = 2;
 int GtkStatsLabel::_top_margin = 2;
@@ -57,21 +59,14 @@ GtkStatsLabel(GtkStatsMonitor *monitor, GtkStatsGraph *graph,
   _layout = gtk_widget_create_pango_layout(_widget, _text.c_str());
 
   // Set the fg and bg colors on the label.
-  LRGBColor rgb = _monitor->get_collector_color(_collector_index);
-  _bg_color.red = (int)(rgb[0] * 65535.0f);
-  _bg_color.green = (int)(rgb[1] * 65535.0f);
-  _bg_color.blue = (int)(rgb[2] * 65535.0f);
+  _bg_color = _monitor->get_collector_color(_collector_index);
 
   // Should our foreground be black or white?
-  double bright =
-    rgb[0] * 0.299 +
-    rgb[1] * 0.587 +
-    rgb[2] * 0.114;
-
+  PN_stdfloat bright = _bg_color.dot(LRGBColor(0.299, 0.587, 0.114));
   if (bright >= 0.5) {
-    _fg_color.red = _fg_color.green = _fg_color.blue = 0;
+    _fg_color = LRGBColor(0);
   } else {
-    _fg_color.red = _fg_color.green = _fg_color.blue = 0xffff;
+    _fg_color = LRGBColor(1);
   }
 
   // What are the extents of the text?  This determines the minimum size of
@@ -163,30 +158,30 @@ expose_event_callback(GtkWidget *widget, GdkEventExpose *event, gpointer data) {
   GtkStatsLabel *self = (GtkStatsLabel *)data;
 
   GdkWindow *window = gtk_widget_get_window(widget);
-  GdkGC *gc = gdk_gc_new(window);
-  gdk_gc_set_rgb_fg_color(gc, &self->_bg_color);
+  cairo_t *cr = gdk_cairo_create(window);
+  cairo_set_source_rgb(cr, self->_bg_color[0], self->_bg_color[1], self->_bg_color[2]);
 
   GtkAllocation allocation;
   gtk_widget_get_allocation(widget, &allocation);
 
-  gdk_draw_rectangle(window, gc, TRUE, 0, 0, allocation.width, allocation.height);
+  cairo_rectangle(cr, 0, 0, allocation.width, allocation.height);
+  cairo_fill(cr);
 
   // Center the text within the rectangle.
   int width, height;
   pango_layout_get_pixel_size(self->_layout, &width, &height);
 
-  gdk_gc_set_rgb_fg_color(gc, &self->_fg_color);
-  gdk_draw_layout(window, gc,
-      (allocation.width - width) / 2, 0,
-      self->_layout);
+  cairo_set_source_rgb(cr, self->_fg_color[0], self->_fg_color[1], self->_fg_color[2]);
+  cairo_move_to(cr, (allocation.width - width) / 2, 0);
+  pango_cairo_show_layout(cr, self->_layout);
 
   // Now draw the highlight rectangle, if any.
   if (self->_highlight || self->_mouse_within) {
-    gdk_draw_rectangle(window, gc, FALSE, 0, 0,
-           allocation.width - 1, allocation.height - 1);
+    cairo_rectangle(cr, 0, 0, allocation.width, allocation.height);
+    cairo_stroke(cr);
   }
 
-  g_object_unref(gc);
+  cairo_destroy(cr);
   return TRUE;
 }
 

+ 2 - 2
pandatool/src/gtk-stats/gtkStatsLabel.h

@@ -61,8 +61,8 @@ private:
   int _collector_index;
   std::string _text;
   GtkWidget *_widget;
-  GdkColor _fg_color;
-  GdkColor _bg_color;
+  LRGBColor _fg_color;
+  LRGBColor _bg_color;
   PangoLayout *_layout;
 
   /*

+ 23 - 25
pandatool/src/gtk-stats/gtkStatsPianoRoll.cxx

@@ -142,9 +142,8 @@ set_horizontal_scale(double time_width) {
  */
 void GtkStatsPianoRoll::
 clear_region() {
-  gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
-  gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, 0, 0,
-         get_xsize(), get_ysize());
+  cairo_set_source_rgb(_cr, 1.0, 1.0, 1.0);
+  cairo_paint(_cr);
 }
 
 /**
@@ -157,7 +156,7 @@ begin_draw() {
   // Draw in the guide bars.
   int num_guide_bars = get_num_guide_bars();
   for (int i = 0; i < num_guide_bars; i++) {
-    draw_guide_bar(_pixmap, get_guide_bar(i));
+    draw_guide_bar(_cr, get_guide_bar(i));
   }
 }
 
@@ -171,11 +170,9 @@ draw_bar(int row, int from_x, int to_x) {
     int height = _label_stack.get_label_height(row);
 
     int collector_index = get_label_collector(row);
-    GdkGC *gc = get_collector_gc(collector_index);
-
-    gdk_draw_rectangle(_pixmap, gc, TRUE,
-           from_x, y - height + 2,
-           to_x - from_x, height - 4);
+    cairo_set_source(_cr, get_collector_pattern(collector_index));
+    cairo_rectangle(_cr, from_x, y - height + 2, to_x - from_x, height - 4);
+    cairo_fill(_cr);
   }
 }
 
@@ -203,12 +200,10 @@ idle() {
  * class opportunity to do some further painting into the graph window.
  */
 void GtkStatsPianoRoll::
-additional_graph_window_paint() {
-  GdkWindow *window = gtk_widget_get_window(_graph_window);
-
+additional_graph_window_paint(cairo_t *cr) {
   int num_user_guide_bars = get_num_user_guide_bars();
   for (int i = 0; i < num_user_guide_bars; i++) {
-    draw_guide_bar(window, get_user_guide_bar(i));
+    draw_guide_bar(cr, get_user_guide_bar(i));
   }
 }
 
@@ -382,25 +377,27 @@ update_labels() {
  * Draws the line for the indicated guide bar on the graph.
  */
 void GtkStatsPianoRoll::
-draw_guide_bar(GdkDrawable *surface, const PStatGraph::GuideBar &bar) {
+draw_guide_bar(cairo_t *cr, const PStatGraph::GuideBar &bar) {
   int x = height_to_pixel(bar._height);
 
   if (x > 0 && x < get_xsize() - 1) {
     // Only draw it if it's not too close to the top.
     switch (bar._style) {
     case GBS_target:
-      gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_light_gray);
+      cairo_set_source_rgb(cr, rgb_light_gray[0], rgb_light_gray[1], rgb_light_gray[2]);
       break;
 
     case GBS_user:
-      gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_user_guide_bar);
+      cairo_set_source_rgb(cr, rgb_user_guide_bar[0], rgb_user_guide_bar[1], rgb_user_guide_bar[2]);
       break;
 
     case GBS_normal:
-      gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_dark_gray);
+      cairo_set_source_rgb(cr, rgb_dark_gray[0], rgb_dark_gray[1], rgb_dark_gray[2]);
       break;
     }
-    gdk_draw_line(surface, _pixmap_gc, x, 0, x, get_ysize());
+    cairo_move_to(cr, x, 0);
+    cairo_line_to(cr, x, get_ysize());
+    cairo_stroke(cr);
   }
 }
 
@@ -427,19 +424,19 @@ draw_guide_labels() {
 void GtkStatsPianoRoll::
 draw_guide_label(const PStatGraph::GuideBar &bar) {
   GdkWindow *window = gtk_widget_get_window(_scale_area);
-  GdkGC *gc = gdk_gc_new(window);
+  cairo_t *cr = gdk_cairo_create(window);
 
   switch (bar._style) {
   case GBS_target:
-    gdk_gc_set_rgb_fg_color(gc, &rgb_light_gray);
+    cairo_set_source_rgb(cr, rgb_light_gray[0], rgb_light_gray[1], rgb_light_gray[2]);
     break;
 
   case GBS_user:
-    gdk_gc_set_rgb_fg_color(gc, &rgb_user_guide_bar);
+    cairo_set_source_rgb(cr, rgb_user_guide_bar[0], rgb_user_guide_bar[1], rgb_user_guide_bar[2]);
     break;
 
   case GBS_normal:
-    gdk_gc_set_rgb_fg_color(gc, &rgb_dark_gray);
+    cairo_set_source_rgb(cr, rgb_dark_gray[0], rgb_dark_gray[1], rgb_dark_gray[2]);
     break;
   }
 
@@ -456,7 +453,7 @@ draw_guide_label(const PStatGraph::GuideBar &bar) {
     if (find_user_guide_bar(from_height, to_height) >= 0) {
       // Omit the label: there's a user-defined guide bar in the same space.
       g_object_unref(layout);
-      g_object_unref(gc);
+      cairo_destroy(cr);
       return;
     }
   }
@@ -474,11 +471,12 @@ draw_guide_label(const PStatGraph::GuideBar &bar) {
     gtk_widget_get_allocation(_scale_area, &allocation);
 
     int this_x = x - width / 2;
-    gdk_draw_layout(window, gc, this_x, allocation.height - height, layout);
+    cairo_move_to(cr, this_x, allocation.height - height);
+    pango_cairo_show_layout(cr, layout);
   }
 
   g_object_unref(layout);
-  g_object_unref(gc);
+  cairo_destroy(cr);
 }
 
 /**

+ 2 - 2
pandatool/src/gtk-stats/gtkStatsPianoRoll.h

@@ -48,7 +48,7 @@ protected:
   virtual void end_draw();
   virtual void idle();
 
-  virtual void additional_graph_window_paint();
+  virtual void additional_graph_window_paint(cairo_t *cr);
   virtual DragMode consider_drag_start(int graph_x, int graph_y);
 
   virtual gboolean handle_button_press(GtkWidget *widget, int graph_x, int graph_y,
@@ -59,7 +59,7 @@ protected:
 private:
   int get_collector_under_pixel(int xpoint, int ypoint);
   void update_labels();
-  void draw_guide_bar(GdkDrawable *surface, const PStatGraph::GuideBar &bar);
+  void draw_guide_bar(cairo_t *cr, const PStatGraph::GuideBar &bar);
   void draw_guide_labels();
   void draw_guide_label(const PStatGraph::GuideBar &bar);
 

+ 51 - 40
pandatool/src/gtk-stats/gtkStatsStripChart.cxx

@@ -33,8 +33,6 @@ GtkStatsStripChart(GtkStatsMonitor *monitor, int thread_index,
                   default_strip_chart_height),
   GtkStatsGraph(monitor)
 {
-  _brush_origin = 0;
-
   if (show_level) {
     // If it's a level-type graph, show the appropriate units.
     if (_unit_name.empty()) {
@@ -236,9 +234,8 @@ update_labels() {
  */
 void GtkStatsStripChart::
 clear_region() {
-  gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
-  gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, 0, 0,
-         get_xsize(), get_ysize());
+  cairo_set_source_rgb(_cr, 1.0, 1.0, 1.0);
+  cairo_paint(_cr);
 }
 
 /**
@@ -247,13 +244,23 @@ clear_region() {
  */
 void GtkStatsStripChart::
 copy_region(int start_x, int end_x, int dest_x) {
-  gdk_draw_drawable(_pixmap, _pixmap_gc, _pixmap,
-        start_x, 0, dest_x, 0,
-        end_x - start_x, get_ysize());
+  // We are not allowed to copy a surface onto itself, so we have to create a
+  // temporary surface to copy to.
+  end_x = std::min(end_x, get_xsize());
+  cairo_surface_t *temp_surface =
+    cairo_image_surface_create(CAIRO_FORMAT_RGB24, end_x - start_x, get_ysize());
+  {
+    cairo_t *temp_cr = cairo_create(temp_surface);
+    cairo_set_source_surface(temp_cr, _cr_surface, -start_x, 0);
+    cairo_paint(temp_cr);
+    cairo_destroy(temp_cr);
+  }
+
+  cairo_set_source_surface(_cr, temp_surface, 0, 0);
+  cairo_rectangle(_cr, dest_x, 0, end_x - start_x, get_ysize());
+  cairo_fill(_cr);
 
-  // Also shift the brush origin over, so we still get proper dithering.
-  _brush_origin += (dest_x - start_x);
-  // SetBrushOrgEx(_bitmap_dc, _brush_origin, 0, NULL);
+  cairo_surface_destroy(temp_surface);
 
   GdkWindow *window = gtk_widget_get_window(_graph_window);
   GdkRectangle rect = {
@@ -269,9 +276,9 @@ copy_region(int start_x, int end_x, int dest_x) {
 void GtkStatsStripChart::
 draw_slice(int x, int w, const PStatStripChart::FrameData &fdata) {
   // Start by clearing the band first.
-  gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
-  gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, x, 0,
-         w + 1, get_ysize());
+  cairo_set_source_rgb(_cr, 1.0, 1.0, 1.0);
+  cairo_rectangle(_cr, x, 0, w, get_ysize());
+  cairo_fill(_cr);
 
   double overall_time = 0.0;
   int y = get_ysize();
@@ -280,18 +287,20 @@ draw_slice(int x, int w, const PStatStripChart::FrameData &fdata) {
   for (fi = fdata.begin(); fi != fdata.end(); ++fi) {
     const ColorData &cd = (*fi);
     overall_time += cd._net_value;
-    GdkGC *gc = get_collector_gc(cd._collector_index);
+    cairo_set_source(_cr, get_collector_pattern(cd._collector_index));
 
     if (overall_time > get_vertical_scale()) {
       // Off the top.  Go ahead and clamp it by hand, in case it's so far off
       // the top we'd overflow the 16-bit pixel value.
-      gdk_draw_rectangle(_pixmap, gc, TRUE, x, 0, w, y);
+      cairo_rectangle(_cr, x, 0, w, y);
+      cairo_fill(_cr);
       // And we can consider ourselves done now.
       return;
     }
 
     int top_y = height_to_pixel(overall_time);
-    gdk_draw_rectangle(_pixmap, gc, TRUE, x, top_y, w, y - top_y);
+    cairo_rectangle(_cr, x, top_y, w, y - top_y);
+    cairo_fill(_cr);
     y = top_y;
   }
 }
@@ -301,9 +310,8 @@ draw_slice(int x, int w, const PStatStripChart::FrameData &fdata) {
  */
 void GtkStatsStripChart::
 draw_empty(int x, int w) {
-  gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_white);
-  gdk_draw_rectangle(_pixmap, _pixmap_gc, TRUE, x, 0,
-         w + 1, get_ysize());
+  cairo_set_source_rgb(_cr, 1.0, 1.0, 1.0);
+  cairo_rectangle(_cr, x, 0, w, get_ysize());
 }
 
 /**
@@ -311,8 +319,10 @@ draw_empty(int x, int w) {
  */
 void GtkStatsStripChart::
 draw_cursor(int x) {
-  gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_black);
-  gdk_draw_line(_pixmap, _pixmap_gc, x, 0, x, get_ysize());
+  cairo_set_source_rgb(_cr, 0.0, 0.0, 0.0);
+  cairo_move_to(_cr, x, 0);
+  cairo_line_to(_cr, x, get_ysize());
+  cairo_stroke(_cr);
 }
 
 /**
@@ -325,12 +335,12 @@ end_draw(int from_x, int to_x) {
   // Draw in the guide bars.
   int num_guide_bars = get_num_guide_bars();
   for (int i = 0; i < num_guide_bars; i++) {
-    draw_guide_bar(_pixmap, from_x, to_x, get_guide_bar(i));
+    draw_guide_bar(_cr, from_x, to_x, get_guide_bar(i));
   }
 
   GdkWindow *window = gtk_widget_get_window(_graph_window);
   GdkRectangle rect = {
-    from_x, 0, to_x - from_x + 1, get_ysize()
+    from_x, 0, to_x - from_x, get_ysize()
   };
   gdk_window_invalidate_rect(window, &rect, FALSE);
 }
@@ -340,12 +350,10 @@ end_draw(int from_x, int to_x) {
  * class opportunity to do some further painting into the graph window.
  */
 void GtkStatsStripChart::
-additional_graph_window_paint() {
-  GdkWindow *window = gtk_widget_get_window(_graph_window);
-
+additional_graph_window_paint(cairo_t *cr) {
   int num_user_guide_bars = get_num_user_guide_bars();
   for (int i = 0; i < num_user_guide_bars; i++) {
-    draw_guide_bar(window, 0, get_xsize(), get_user_guide_bar(i));
+    draw_guide_bar(cr, 0, get_xsize(), get_user_guide_bar(i));
   }
 }
 
@@ -512,7 +520,7 @@ handle_motion(GtkWidget *widget, int graph_x, int graph_y) {
  * Draws the line for the indicated guide bar on the graph.
  */
 void GtkStatsStripChart::
-draw_guide_bar(GdkDrawable *surface, int from_x, int to_x,
+draw_guide_bar(cairo_t *cr, int from_x, int to_x,
                const PStatGraph::GuideBar &bar) {
   int y = height_to_pixel(bar._height);
 
@@ -520,18 +528,20 @@ draw_guide_bar(GdkDrawable *surface, int from_x, int to_x,
     // Only draw it if it's not too close to the top.
     switch (bar._style) {
     case GBS_target:
-      gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_light_gray);
+      cairo_set_source_rgb(cr, rgb_light_gray[0], rgb_light_gray[1], rgb_light_gray[2]);
       break;
 
     case GBS_user:
-      gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_user_guide_bar);
+      cairo_set_source_rgb(cr, rgb_user_guide_bar[0], rgb_user_guide_bar[1], rgb_user_guide_bar[2]);
       break;
 
     case GBS_normal:
-      gdk_gc_set_rgb_fg_color(_pixmap_gc, &rgb_dark_gray);
+      cairo_set_source_rgb(cr, rgb_dark_gray[0], rgb_dark_gray[1], rgb_dark_gray[2]);
       break;
     }
-    gdk_draw_line(surface, _pixmap_gc, from_x, y, to_x, y);
+    cairo_move_to(cr, from_x, y);
+    cairo_line_to(cr, to_x, y);
+    cairo_stroke(cr);
   }
 }
 
@@ -567,19 +577,19 @@ draw_guide_labels() {
 int GtkStatsStripChart::
 draw_guide_label(const PStatGraph::GuideBar &bar, int last_y) {
   GdkWindow *window = gtk_widget_get_window(_scale_area);
-  GdkGC *gc = gdk_gc_new(window);
+  cairo_t *cr = gdk_cairo_create(window);
 
   switch (bar._style) {
   case GBS_target:
-    gdk_gc_set_rgb_fg_color(gc, &rgb_light_gray);
+    cairo_set_source_rgb(cr, rgb_light_gray[0], rgb_light_gray[1], rgb_light_gray[2]);
     break;
 
   case GBS_user:
-    gdk_gc_set_rgb_fg_color(gc, &rgb_user_guide_bar);
+    cairo_set_source_rgb(cr, rgb_user_guide_bar[0], rgb_user_guide_bar[1], rgb_user_guide_bar[2]);
     break;
 
   case GBS_normal:
-    gdk_gc_set_rgb_fg_color(gc, &rgb_dark_gray);
+    cairo_set_source_rgb(cr, rgb_dark_gray[0], rgb_dark_gray[1], rgb_dark_gray[2]);
     break;
   }
 
@@ -596,7 +606,7 @@ draw_guide_label(const PStatGraph::GuideBar &bar, int last_y) {
     if (find_user_guide_bar(from_height, to_height) >= 0) {
       // Omit the label: there's a user-defined guide bar in the same space.
       g_object_unref(layout);
-      g_object_unref(gc);
+      cairo_destroy(cr);
       return last_y;
     }
   }
@@ -612,13 +622,14 @@ draw_guide_label(const PStatGraph::GuideBar &bar, int last_y) {
 
     int this_y = y - height / 2;
     if (last_y < this_y || last_y > this_y + height) {
-      gdk_draw_layout(window, gc, 0, this_y, layout);
+      cairo_move_to(cr, 0, this_y);
+      pango_cairo_show_layout(cr, layout);
       last_y = this_y;
     }
   }
 
   g_object_unref(layout);
-  g_object_unref(gc);
+  cairo_destroy(cr);
   return last_y;
 }
 

+ 3 - 4
pandatool/src/gtk-stats/gtkStatsStripChart.h

@@ -54,7 +54,7 @@ protected:
   virtual void draw_cursor(int x);
   virtual void end_draw(int from_x, int to_x);
 
-  virtual void additional_graph_window_paint();
+  virtual void additional_graph_window_paint(cairo_t *cr);
   virtual DragMode consider_drag_start(int graph_x, int graph_y);
   virtual void set_drag_mode(DragMode drag_mode);
 
@@ -64,8 +64,8 @@ protected:
   virtual gboolean handle_motion(GtkWidget *widget, int graph_x, int graph_y);
 
 private:
-  void draw_guide_bar(GdkDrawable *surface, int from_x, int to_x,
-          const PStatGraph::GuideBar &bar);
+  void draw_guide_bar(cairo_t *cr, int from_x, int to_x,
+                      const PStatGraph::GuideBar &bar);
   void draw_guide_labels();
   int draw_guide_label(const PStatGraph::GuideBar &bar, int last_y);
 
@@ -74,7 +74,6 @@ private:
           GdkEventExpose *event, gpointer data);
 
 private:
-  int _brush_origin;
   std::string _net_value_text;
 
   GtkWidget *_top_hbox;