[giv] Major memory leak fixes and addition of multi line strings.
- From: Dov Grobgeld <dov src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [giv] Major memory leak fixes and addition of multi line strings.
- Date: Wed, 16 May 2012 19:44:29 +0000 (UTC)
commit aee7c62e671a8a1e275db60c53e55a5409041b88
Author: Dov Grobgeld <dov grobgeld gmail com>
Date: Wed May 16 22:43:52 2012 +0300
Major memory leak fixes and addition of multi line strings.
examples/text-unicode.giv | 8 ++++
src/GivPainterAgg.cc | 1 +
src/GivRenderer.cc | 30 +++++++++++++-
src/giv-data.cc | 14 ++++++-
src/giv-data.h | 10 +++++
src/giv-parser.cc | 97 ++++++++++++++++++++++++++++++++++++++++-----
src/giv-win.gob | 37 +++++++----------
src/givimage.c | 3 +-
8 files changed, 164 insertions(+), 36 deletions(-)
---
diff --git a/examples/text-unicode.giv b/examples/text-unicode.giv
index ff8f295..aa8081b 100644
--- a/examples/text-unicode.giv
+++ b/examples/text-unicode.giv
@@ -24,3 +24,11 @@ $color red/80
T5 100 50 <span size="xx-large">x<sup>2</sup>+y<sup>2</sup>=z<sub>2</sub></span>
T5 100 20 <u><span color="red">R</span><span color="green">G</span><span color="blue">B</span></u>
+$pango_markup
+$color green
+$scale_font 1
+$font sans
+$text_style shadow
+$shadow_color black/0.3
+$shadow_offset 1 1
+T5 100 200 Multi\nlines\nare\nnice.
diff --git a/src/GivPainterAgg.cc b/src/GivPainterAgg.cc
index 7f1a563..3144b1b 100644
--- a/src/GivPainterAgg.cc
+++ b/src/GivPainterAgg.cc
@@ -249,6 +249,7 @@ GivPainterAgg::add_text(const char *text,
pango_layout_set_markup(d->layout, text, -1);
else
pango_layout_set_text (d->layout, text, -1);
+ pango_layout_set_alignment(d->layout, PangoAlignment((text_align-1)%3));
pango_layout_get_extents(d->layout,
NULL,
diff --git a/src/GivRenderer.cc b/src/GivRenderer.cc
index 2775989..8669b90 100644
--- a/src/GivRenderer.cc
+++ b/src/GivRenderer.cc
@@ -219,11 +219,39 @@ void GivRenderer::paint()
for (int p_idx=0; p_idx<(int)dataset->points->len; p_idx++) {
point_t p = g_array_index(dataset->points, point_t, p_idx);
- if (p.op == OP_TEXT) {
+ if (p.op == OP_TEXT)
+ {
double m_x = p.x * scale_x - shift_x;
double m_y = p.y * scale_y - shift_y;
const char *text = p.text_object->string;
int text_align = p.text_object->text_align;
+ if (dataset->text_style == TEXT_STYLE_DROP_SHADOW)
+ {
+ double rr = cs*dataset->shadow_color.red;
+ double gg = cs*dataset->shadow_color.green;
+ double bb = cs*dataset->shadow_color.blue;
+ double alpha = cs*dataset->shadow_color.alpha;
+
+ double shift_x = dataset->shadow_offset_x;
+ double shift_y = dataset->shadow_offset_y;
+ if (dataset->do_scale_fonts)
+ {
+ shift_x *= scale_x;
+ shift_y *= scale_y;
+ }
+ painter.set_color(rr,gg,bb,alpha);
+ painter.add_text(text,
+ m_x+shift_x,
+ m_y+shift_y,
+ text_align,
+ dataset->do_pango_markup);
+ // Reset color
+ rr = cs*dataset->color.red;
+ gg = cs*dataset->color.green;
+ bb = cs*dataset->color.blue;
+ alpha = cs*dataset->color.alpha;
+ painter.set_color(rr,gg,bb,alpha);
+ }
painter.add_text(text, m_x, m_y, text_align, dataset->do_pango_markup);
}
}
diff --git a/src/giv-data.cc b/src/giv-data.cc
index f3f64e5..d3fcb2b 100644
--- a/src/giv-data.cc
+++ b/src/giv-data.cc
@@ -48,7 +48,12 @@ giv_dataset_t *new_giv_dataset(int num_datasets)
dataset_p->font_name = NULL;
dataset_p->file_name = NULL;
dataset_p->color = color_of_black;
+ dataset_p->shadow_color = color_of_black;
+ dataset_p->shadow_offset_x = 0.5;
+ dataset_p->shadow_offset_y = 0.5;
+ dataset_p->text_style = TEXT_STYLE_NORMAL;
dataset_p->outline_color = color_of_black;
+ dataset_p->outline_color.alpha = 128*256;
dataset_p->quiver_color = color_of_black;
dataset_p->quiver_scale = 1.0;
#if 0
@@ -70,12 +75,17 @@ void free_giv_data_set(giv_dataset_t *dataset_p)
g_free(dataset_p->path_name);
if (dataset_p->set_name)
g_free(dataset_p->set_name);
- g_array_free(dataset_p->points, TRUE);
if (dataset_p->file_name)
g_free(dataset_p->file_name);
if (dataset_p->balloon_string)
g_string_free(dataset_p->balloon_string, TRUE);
-
+ for (int i=0; i<(int)dataset_p->points->len; i++)
+ {
+ point_t p = g_array_index(dataset_p->points, point_t, i);
+ if (p.op == OP_TEXT)
+ g_free(p.text_object->string);
+ }
+ g_array_free(dataset_p->points, TRUE);
g_free(dataset_p);
}
diff --git a/src/giv-data.h b/src/giv-data.h
index c91b0e9..c7a1e36 100644
--- a/src/giv-data.h
+++ b/src/giv-data.h
@@ -38,6 +38,12 @@ enum GivArrowType
ARROW_TYPE_BOTH = 3,
};
+enum GivTextStyle
+{
+ TEXT_STYLE_NORMAL,
+ TEXT_STYLE_DROP_SHADOW
+};
+
typedef struct {
guint16 red;
guint16 green;
@@ -50,6 +56,7 @@ typedef struct
GivColor color;
GivColor outline_color;
GivColor quiver_color;
+ GivColor shadow_color;
gdouble line_width;
gdouble quiver_scale;
gint line_style;
@@ -57,6 +64,7 @@ typedef struct
gdouble text_size;
gboolean do_scale_fonts;
gboolean do_pango_markup;
+ enum GivTextStyle text_style;
gint num_dashes;
gdouble mark_size;
gboolean do_scale_marks;
@@ -75,6 +83,8 @@ typedef struct
GString *balloon_string;
char *font_name;
gdouble *dashes;
+ gdouble shadow_offset_x;
+ gdouble shadow_offset_y;
} giv_dataset_t;
typedef struct
diff --git a/src/giv-parser.cc b/src/giv-parser.cc
index 5ee9e9d..5f0f6bb 100644
--- a/src/giv-parser.cc
+++ b/src/giv-parser.cc
@@ -27,6 +27,8 @@ enum
STRING_CHANGE_COLOR,
STRING_CHANGE_OUTLINE_COLOR,
STRING_CHANGE_QUIVER_COLOR,
+ STRING_CHANGE_SHADOW_COLOR,
+ STRING_CHANGE_SHADOW_OFFSET,
STRING_CHANGE_QUIVER_SCALE,
STRING_CHANGE_LINE_WIDTH,
STRING_CHANGE_MARKS,
@@ -56,7 +58,8 @@ enum
STRING_STYLE,
STRING_DEF_STYLE,
STRING_HIDE,
- STRING_IGNORE
+ STRING_IGNORE,
+ STRING_TEXT_STYLE
};
#define COLOR_NONE 0xfffe
@@ -304,8 +307,8 @@ string_strdup_word (const char *string, int idx)
return word;
}
-char *
-string_strdup_rest (const char *string, int idx)
+static char *
+string_strdup_rest (const char *string, int idx, bool parse_escape)
{
const char *p = string;
int in_word = 0;
@@ -317,10 +320,12 @@ string_strdup_rest (const char *string, int idx)
/* printf("p = 0x%x\n", p); */
while (*p)
{
+ char ch = *p;
+
/* printf("%c\n", *p); fflush(stdout); */
if (!in_word)
{
- if (*p != ' ' && *p != '\n' && *p != '\t')
+ if (ch != ' ' && ch != '\n' && ch != '\t')
{
in_word = 1;
word_count++;
@@ -330,7 +335,7 @@ string_strdup_rest (const char *string, int idx)
}
else if (in_word)
{
- if (*p == ' ' || *p == '\n' || *p == '\t')
+ if (ch == ' ' || ch == '\n' || ch == '\t')
{
if (idx == word_count)
break;
@@ -347,6 +352,36 @@ string_strdup_rest (const char *string, int idx)
word = g_new (char, nchr + 1);
strncpy (word, word_start, nchr);
word[nchr] = 0;
+ if (parse_escape)
+ {
+ gchar *word_copy = g_strdup(word);
+ char *p = word_copy;
+ char *pd = word;
+ while(*p)
+ {
+ char ch = *p;
+ if (ch == '\\')
+ {
+ p++;
+ if (!*p)
+ break;
+ if (*p=='n')
+ ch = '\n';
+ else if (*p == '\\')
+ ch = '\\';
+ else
+ {
+ // ignore the escape character
+ ch = '\\';
+ p--;
+ }
+ }
+ *pd++ = ch;
+ p++;
+ }
+ *pd=0;
+ g_free(word_copy);
+ }
}
return word;
}
@@ -414,6 +449,14 @@ parse_string (const char *string, const char *fn, gint linenum)
{
type = STRING_CHANGE_QUIVER_COLOR;
}
+ NCASE ("$shadow_color")
+ {
+ type = STRING_CHANGE_SHADOW_COLOR;
+ }
+ NCASE ("$shadow_offset")
+ {
+ type = STRING_CHANGE_SHADOW_OFFSET;
+ }
NCASE ("$quiver_scale")
{
type = STRING_CHANGE_QUIVER_SCALE;
@@ -454,6 +497,10 @@ parse_string (const char *string, const char *fn, gint linenum)
{
type = STRING_FONT;
}
+ NCASE ("$text_style")
+ {
+ type = STRING_TEXT_STYLE;
+ }
NCASE ("$nomark")
{
type = STRING_CHANGE_NO_MARK;
@@ -647,7 +694,7 @@ giv_parser_giv_marks_data_add_line(GivParser *gp,
tm->text_align = 1;
if (S_[1] >= '0' && S_[1] <= '9')
tm->text_align = atoi(&S_[1]);
- tm->string = string_strdup_rest(S_, 3);
+ tm->string = string_strdup_rest(S_, 3, TRUE);
p.op = OP_TEXT;
p.text_object = tm;
g_array_append_val(marks->points, p);
@@ -658,7 +705,7 @@ giv_parser_giv_marks_data_add_line(GivParser *gp,
break;
case STRING_BALLOON:
{
- char *s = string_strdup_rest(S_,1);
+ char *s = string_strdup_rest(S_,1,TRUE);
if (!marks->balloon_string)
marks->balloon_string = g_string_new(s);
else {
@@ -769,7 +816,7 @@ giv_parser_giv_marks_data_add_line(GivParser *gp,
case STRING_FONT:
if (marks->font_name)
g_free(marks->font_name);
- marks->font_name = string_strdup_rest(S_, 1);
+ marks->font_name = string_strdup_rest(S_, 1, TRUE);
break;
case STRING_CHANGE_COLOR:
{
@@ -811,6 +858,28 @@ giv_parser_giv_marks_data_add_line(GivParser *gp,
g_free(color_name);
break;
}
+ case STRING_CHANGE_SHADOW_COLOR:
+ {
+ char *color_name = string_strdup_word(S_, 1);
+ GivColor color = {0,0,0,0};
+ if ((slip)color_name == "none")
+ marks->shadow_color.alpha = COLOR_NONE;
+ else {
+ if (color_parse(color_name,&color))
+ marks->shadow_color = color;
+ }
+ g_free(color_name);
+ break;
+ }
+ case STRING_CHANGE_SHADOW_OFFSET:
+ {
+ char *arg1 = string_strdup_word(S_, 1);
+ char *arg2 = string_strdup_word(S_, 2);
+ marks->shadow_offset_x = atof(arg1);
+ marks->shadow_offset_y = atof(arg2);
+ g_free(arg1);
+ g_free(arg2);
+ }
case STRING_CHANGE_QUIVER_SCALE:
marks->quiver_scale = string_to_atof(S_, 1);
@@ -848,12 +917,12 @@ giv_parser_giv_marks_data_add_line(GivParser *gp,
case STRING_PATH_NAME:
if (marks->path_name)
g_free(marks->path_name);
- marks->path_name = string_strdup_rest(S_, 1);
+ marks->path_name = string_strdup_rest(S_, 1,FALSE);
break;
case STRING_DEF_STYLE:
{
char *style_name = string_strdup_word(S_, 1);
- char *style_string = string_strdup_rest(S_, 2);
+ char *style_string = string_strdup_rest(S_, 2,FALSE);
giv_parser_giv_style_add_string(gp, style_name, style_string);
g_free(style_name);
g_free(style_string);
@@ -871,6 +940,14 @@ giv_parser_giv_marks_data_add_line(GivParser *gp,
marks->is_visible = false;
break;
}
+ case STRING_TEXT_STYLE:
+ {
+ char *text_style = string_strdup_word(S_,1);
+ if (strcmp(text_style, "shadow") == 0)
+ marks->text_style = TEXT_STYLE_DROP_SHADOW;
+ g_free(text_style);
+ break;
+ }
default:
;
#if 0
diff --git a/src/giv-win.gob b/src/giv-win.gob
index 27c5c1e..651171f 100644
--- a/src/giv-win.gob
+++ b/src/giv-win.gob
@@ -460,22 +460,16 @@ class Giv:Win from Gtk:Window
destroy {
if (img_org) {
giv_image_unref(img_org);
+ img_org = NULL;
}
};
private double contrast_min = -1;
private double contrast_max = -1;
private gchar *format = NULL destroy { g_free(format); };
-// private GdkPixbuf *img_org = NULL
-// destroy {
-// if (img_org) {
-// g_object_unref(img_org);
-// };
-// };
private GdkPixbuf *img_display = NULL
destroy {
- if (img_display) {
- g_object_unref(img_display);
- };
+ if (img_display)
+ g_object_unref(img_display);
};
// This image is a copy of the img display but with label
@@ -1051,7 +1045,7 @@ class Giv:Win from Gtk:Window
{
num_top_levels--;
gtk_widget_destroy(GTK_WIDGET(self));
-
+
if (num_top_levels == 0)
gtk_main_quit();
}
@@ -1118,13 +1112,12 @@ class Giv:Win from Gtk:Window
selfp->auto_reload_trigger = false;
if (selfp->img_org)
+ {
giv_image_unref(selfp->img_org);
- if (selfp->img_display) {
- g_object_unref(selfp->img_display);
- selfp->img_display = NULL;
- }
-
+ selfp->img_org = NULL;
+ }
selfp->img_org = new_img;
+
if (selfp->do_auto_contrast)
giv_image_get_min_max(new_img,
// output
@@ -1272,10 +1265,11 @@ class Giv:Win from Gtk:Window
// If the new entry does not contain an image, then clear
// the old image.
if (!has_image) {
- if (selfp->img_org) {
+ if (selfp->img_org)
+ {
giv_image_unref(selfp->img_org);
selfp->img_org = NULL;
- }
+ }
if (selfp->img_display) {
g_object_unref(selfp->img_display);
selfp->img_display = NULL;
@@ -1419,9 +1413,10 @@ class Giv:Win from Gtk:Window
GivImage *image)
{
if (selfp->img_org)
+ {
giv_image_unref(selfp->img_org);
- if (selfp->img_display)
- g_object_ref(selfp->img_display);
+ selfp->img_org = NULL;
+ }
selfp->img_org = image;
apply_color_map(self);
gtk_image_viewer_set_image(GTK_IMAGE_VIEWER(selfp->w_imgv),
@@ -1874,7 +1869,6 @@ cb_key_press_event (GtkWidget * widget,
selfp->current_slice = 0;
// Redraw the image
- giv_image_ref(selfp->img_org);
giv_win_set_image(GIV_WIN(self),
selfp->img_org);
giv_win_set_image_info(GIV_WIN(self));
@@ -3264,9 +3258,8 @@ apply_color_map(GivWin *self)
GdkPixbuf *org_pixbuf = giv_image_get_pixbuf(selfp->img_org,
selfp->current_slice,
min, max);
-
if (selfp->img_display)
- g_object_unref(selfp->img_display);
+ g_object_unref(selfp->img_display);
const guint8 *tmap = NULL;
if (selfp->colormap == PSEUDO_COLOR_OFF
diff --git a/src/givimage.c b/src/givimage.c
index d355788..d21cb88 100644
--- a/src/givimage.c
+++ b/src/givimage.c
@@ -161,7 +161,7 @@ GivImage *giv_image_new_from_file(const char *filename,
gdk_pixbuf_get_pixels(pixbuf),
row_stride * height);
}
- gdk_pixbuf_unref(pixbuf);
+ g_object_unref(pixbuf);
}
// Space separated value. A simple text format parser. Still
// doesn't support comments. Fix this!
@@ -335,6 +335,7 @@ void giv_image_unref(GivImage *img)
if (img->ref_count !=0)
return;
+ g_free(img->buf.buf);
g_hash_table_unref(img->attribute_map);
g_free(img);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]