gtk-stats: Use cairo instead of GDK for drawing

Drawing via GDK is deprecated and no longer supported in GTK 3
This commit is contained in:
rdb 2022-02-01 15:36:08 +01:00
parent 3a38543f65
commit 4c3bc5a42e
8 changed files with 154 additions and 167 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
/*

View File

@ -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);
}
/**

View File

@ -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);

View File

@ -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);
}
// 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_set_source_surface(_cr, temp_surface, 0, 0);
cairo_rectangle(_cr, dest_x, 0, end_x - start_x, get_ysize());
cairo_fill(_cr);
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;
}

View File

@ -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;