8c49e02306243cba27d3e50389f872331c5f7dc5
[tbo.git] / src / textobj.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <gtk/gtk.h>
4 #include <cairo.h>
5 #include "textobj.h"
6 #include "text-tool.h"
7 #include "tbo-types.h"
8
9 typedef struct
10 {
11     GString *text;
12     PangoFontDescription *description;
13     Color *font_color;
14 } text_data;
15
16 text_data *
17 text_data_new (const char *text, char *font, double r, double g, double b)
18 {
19     text_data *txt = malloc (sizeof (text_data));
20     txt->text = g_string_new (text);
21     Color *color = malloc (sizeof (Color));
22     color->r = r;
23     color->g = g;
24     color->b = b;
25     txt->font_color = color;
26     txt->description = pango_font_description_from_string (font);
27
28     return txt;
29 }
30
31 void
32 text_data_free (text_data *txt)
33 {
34     free (txt->font_color);
35     g_string_free (txt->text, TRUE);
36     pango_font_description_free (txt->description);
37     free (txt);
38 }
39
40 void
41 tbo_text_change_font (TextObj *self, char *font)
42 {
43     text_data *txt = (text_data*)self->data;
44     pango_font_description_free (txt->description);
45     txt->description = pango_font_description_from_string (font);
46 }
47
48 void
49 tbo_text_change_color (TextObj *self, double r, double g, double b)
50 {
51     text_data *txt = (text_data*)self->data;
52     txt->font_color->r = r;
53     txt->font_color->g = g;
54     txt->font_color->b = b;
55 }
56
57 TextObj *
58 tbo_text_new ()
59 {
60     TextObj *text;
61     text = malloc (sizeof(TextObj));
62     text->data = text_data_new ("text", "Sans Normal 27", 0, 0, 0);
63     text->free = tbo_text_free;
64     text->draw = tbo_text_draw;
65     text->save = tbo_text_save;
66     text->type = TEXTOBJ;
67     text->flipv = FALSE;
68     text->fliph = FALSE;
69     return text;
70 }
71
72 TextObj *
73 tbo_text_new_width_params (int x,
74                            int y,
75                            int width,
76                            int height,
77                            const char *text,
78                            char *font,
79                            double r, double g, double b)
80 {
81     TextObj *textobj;
82     textobj = tbo_text_new ();
83     textobj->x = x;
84     textobj->y = y;
85     textobj->width = width;
86     textobj->height = height;
87     textobj->data = text_data_new (text, font, r, g, b);
88     textobj->type = TEXTOBJ;
89     textobj->flipv = FALSE;
90     textobj->fliph = FALSE;
91     return textobj;
92 }
93
94 void
95 tbo_text_free (TextObj *self)
96 {
97     text_data_free (self->data);
98     free (self);
99 }
100
101 void
102 tbo_text_draw (TextObj *self, Frame *frame, cairo_t *cr)
103 {
104     text_data *data = self->data;
105     gchar *text = data->text->str;
106
107     PangoLayout *layout;
108     PangoFontDescription *desc = data->description;
109
110     int w;
111     int h;
112
113     cairo_set_source_rgb(cr, data->font_color->r, data->font_color->g, data->font_color->b);
114
115     layout = pango_cairo_create_layout (cr);
116     pango_layout_set_text (layout, text, -1);
117     pango_layout_set_font_description (layout, desc);
118     pango_layout_get_size (layout, &w, &h);
119     pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
120     w = (double)w / PANGO_SCALE;
121     h = (double)h / PANGO_SCALE;
122
123     if (!self->width) self->width = w;
124     if (!self->height) self->height = h;
125
126     float factorw = (float)self->width / (float)w;
127     float factorh = (float)self->height / (float)h;
128     if (factorh == 1)
129     {
130         factorh = factorw;
131         self->height = self->height * factorw;
132     }
133
134     cairo_matrix_t mx = {1, 0, 0, 1, 0, 0};
135     tbo_object_get_flip_matrix (self, &mx);
136
137     cairo_rectangle(cr, frame->x+2, frame->y+2, frame->width-4, frame->height-4);
138     cairo_clip (cr);
139     cairo_translate (cr, frame->x+self->x, frame->y+self->y);
140     cairo_rotate (cr, self->angle);
141     cairo_transform (cr, &mx);
142     cairo_scale (cr, factorw, factorh);
143
144     pango_cairo_show_layout (cr, layout);
145
146     cairo_scale (cr, 1/factorw, 1/factorh);
147     cairo_transform (cr, &mx);
148     cairo_rotate (cr, -self->angle);
149     cairo_translate (cr, -(frame->x+self->x), -(frame->y+self->y));
150     cairo_reset_clip (cr);
151 }
152
153 char *
154 tbo_text_get_text (TextObj *self)
155 {
156     return ((text_data *)self->data)->text->str;
157 }
158
159 void
160 tbo_text_set_text (TextObj *self, const char *text)
161 {
162     g_string_assign (((text_data *)self->data)->text, text);
163     self->height = 0;
164 }
165
166 void
167 tbo_text_get_color (TextObj *self, GdkColor *color)
168 {
169     text_data *data = (text_data*)self->data;
170     color->red = data->font_color->r * 65535;
171     color->green = data->font_color->g * 65535;
172     color->blue = data->font_color->b * 65535;
173 }
174
175 char *
176 tbo_text_get_string (TextObj *self)
177 {
178     text_data *data = (text_data *)self->data;
179     return pango_font_description_to_string (data->description);
180 }
181
182 void
183 tbo_text_save (TextObj *self, FILE *file)
184 {
185     char buffer[1024];
186
187     text_data *data = (text_data*)self->data;
188     snprintf (buffer, 1024, "   <text x=\"%d\" y=\"%d\" "
189                            "width=\"%d\" height=\"%d\" "
190                            "angle=\"%f\" flipv=\"%d\" fliph=\"%d\" "
191                            "font=\"%s\" "
192                            "r=\"%f\" g=\"%f\" b=\"%f\">\n",
193                            self->x, self->y, self->width, self->height,
194                            self->angle, self->flipv, self->fliph,
195                            pango_font_description_to_string (data->description),
196                            data->font_color->r, data->font_color->g,
197                            data->font_color->b);
198     fwrite (buffer, sizeof (char), strlen (buffer), file);
199
200     snprintf (buffer, 1024, "%s", data->text->str);
201     fwrite (buffer, sizeof (char), strlen (buffer), file);
202
203     snprintf (buffer, 1024, "\n   </text>\n");
204     fwrite (buffer, sizeof (char), strlen (buffer), file);
205 }