~ubuntu-branches/ubuntu/oneiric/evince/oneiric-updates

« back to all changes in this revision

Viewing changes to backend/impress/r_text.c

  • Committer: Bazaar Package Importer
  • Author(s): Rodrigo Moya, Josselin Mouette, Rodrigo Moya
  • Date: 2011-05-19 12:12:42 UTC
  • mfrom: (1.1.65 upstream) (1.3.6 experimental)
  • Revision ID: james.westby@ubuntu.com-20110519121242-967hbn2nh2hunp4y
Tags: 3.0.0-4ubuntu1
[ Josselin Mouette ]
* bug-presubj: please document where to report rendering bugs.
* evince.mime: dropped. We have desktop files to handle MIME 
  associations, no need to maintain an alternate system by hand.
  Closes: #619564, #627027, #551734, #581441.

[ Rodrigo Moya ]
* Rebase from Debian and GNOME3 PPA (thanks to Rico Tzschichholz).
  Remaining Ubuntu changes:
* debian/apparmor-profile:
* debian/apparmor-profile.abstraction:
* debian/evince.apport:
* debian/evince-common.dirs:
* debian/evince-common.postinst:
* debian/evince-common.postrm:
  - Add apparmor profile
* debian/control:
  - Build-Depend on debhelper (>= 7.4.20ubuntu5), gnome-common,
    hardening-includes and liblaunchpad-integration-3.0-dev
  - Standards-Version is 3.9.1
  - Depend on apparmor
* debian/rules:
  - Include hardening.make
  - Add rule to install apparmor files
* debian/watch:
  - Watch unstable series
* debian/patches/01_lpi.patch:
  - Launchpad integration patch
* debian/patches/04_gold.patch:
  - Link against libz
* debian/patches/05_library-path.patch:
  - Fix library path for g-ir-scanner

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* imposter (OO.org Impress viewer)
2
 
** Copyright (C) 2003-2005 Gurer Ozen
3
 
** This code is free software; you can redistribute it and/or
4
 
** modify it under the terms of GNU General Public License.
5
 
*/
6
 
 
7
 
#include <config.h>
8
 
#include "common.h"
9
 
#include "internal.h"
10
 
 
11
 
struct Span {
12
 
        struct Span *next;
13
 
        int x, y;
14
 
        int w, h;
15
 
        char *text;
16
 
        int len;
17
 
        int size;
18
 
        int styles;
19
 
        ImpColor fg;
20
 
};
21
 
 
22
 
struct Line {
23
 
        struct Line *next;
24
 
        struct Span *spans;
25
 
        struct Span *last_span;
26
 
        int x, y;
27
 
        int w, h;
28
 
};
29
 
 
30
 
struct Layout {
31
 
        ikstack *s;
32
 
        int x, y, w, h;
33
 
        int tw, th;
34
 
        struct Line *lines;
35
 
        struct Line *last_line;
36
 
        char spaces[128];
37
 
};
38
 
 
39
 
static struct Line *
40
 
add_line(struct Layout *lay)
41
 
{
42
 
        struct Line *line;
43
 
 
44
 
        line = iks_stack_alloc(lay->s, sizeof(struct Line));
45
 
        memset(line, 0, sizeof(struct Line));
46
 
 
47
 
        if (!lay->lines) lay->lines = line;
48
 
        if (lay->last_line) lay->last_line->next = line;
49
 
        lay->last_line = line;
50
 
 
51
 
        return line;
52
 
}
53
 
 
54
 
static struct Span *
55
 
add_span(struct Layout *lay, char *text, int len, int size, int styles)
56
 
{
57
 
        struct Line *line;
58
 
        struct Span *span;
59
 
 
60
 
        span = iks_stack_alloc(lay->s, sizeof(struct Span));
61
 
        memset(span, 0, sizeof(struct Span));
62
 
        span->text = text;
63
 
        span->len = len;
64
 
        span->size = size;
65
 
        span->styles = styles;
66
 
 
67
 
        line = lay->last_line;
68
 
        if (!line) line = add_line(lay);
69
 
        if (line->spans) {
70
 
                span->x = line->last_span->x + line->last_span->w;
71
 
                span->y = line->last_span->y;
72
 
        } else {
73
 
                span->x = line->x;
74
 
                span->y = line->y;
75
 
        }
76
 
 
77
 
        if (!line->spans) line->spans = span;
78
 
        if (line->last_span) line->last_span->next = span;
79
 
        line->last_span = span;
80
 
 
81
 
        return span;
82
 
}
83
 
 
84
 
static void
85
 
calc_sizes(ImpRenderCtx *ctx, void *drw_data, struct Layout *lay)
86
 
{
87
 
        struct Line *line;
88
 
        struct Span *span;
89
 
 
90
 
        for (line = lay->lines; line; line = line->next) {
91
 
                for (span = line->spans; span; span = span->next) {
92
 
                        ctx->drw->get_text_size(drw_data,
93
 
                                span->text, span->len,
94
 
                                span->size, span->styles,
95
 
                                &span->w, &span->h
96
 
                        );
97
 
                        line->w += span->w;
98
 
                        if (span->h > line->h) line->h = span->h;
99
 
                }
100
 
                if (line->w > lay->tw) lay->tw = line->w;
101
 
                lay->th += line->h;
102
 
        }
103
 
}
104
 
 
105
 
static void
106
 
calc_pos(ImpRenderCtx *ctx, struct Layout *lay)
107
 
{
108
 
        struct Line *line;
109
 
        struct Span *span;
110
 
        int x, y, x2;
111
 
 
112
 
        x = lay->x;
113
 
        y = lay->y;
114
 
        for (line = lay->lines; line; line = line->next) {
115
 
                line->x = x;
116
 
                line->y = y;
117
 
                y += line->h;
118
 
                x2 = x;
119
 
                for (span = line->spans; span; span = span->next) {
120
 
                        span->x = x2;
121
 
                        span->y = y;
122
 
                        x2 += span->w;
123
 
                }
124
 
        }
125
 
}
126
 
 
127
 
static void
128
 
_imp_draw_layout(ImpRenderCtx *ctx, void *drw_data, struct Layout *lay)
129
 
{
130
 
        struct Line *line;
131
 
        struct Span *span;
132
 
 
133
 
        for (line = lay->lines; line; line = line->next) {
134
 
                for (span = line->spans; span; span = span->next) {
135
 
                        ctx->drw->set_fg_color(drw_data, &span->fg);
136
 
                        ctx->drw->draw_text(drw_data,
137
 
                                span->x, span->y,
138
 
                                span->text, span->len,
139
 
                                span->size,
140
 
                                span->styles
141
 
                        );
142
 
                }
143
 
        }
144
 
}
145
 
 
146
 
static void
147
 
text_span(ImpRenderCtx *ctx, struct Layout *lay, iks *node, char *text, size_t len)
148
 
{
149
 
        struct Span *span;
150
 
        double cm;
151
 
        char *attr, *t, *s;
152
 
        int px = 0, cont = 1;
153
 
        int styles = IMP_NORMAL;
154
 
 
155
 
        attr = r_get_style(ctx, node, "fo:font-size");
156
 
        if (attr) {
157
 
                cm = atof(attr);
158
 
                if (strstr(attr, "pt")) cm = cm * 2.54 / 102;
159
 
                px = cm * ctx->fact_y;
160
 
        }
161
 
        attr = r_get_style(ctx, node, "fo:font-weight");
162
 
        if (attr && strcmp(attr, "bold") == 0) styles |= IMP_BOLD;
163
 
        attr = r_get_style(ctx, node, "style:text-underline");
164
 
        if (attr && strcmp(attr, "single") == 0) styles |= IMP_UNDERLINE;
165
 
        attr = r_get_style(ctx, node, "fo:font-style");
166
 
        if (attr && strcmp(attr, "italic") == 0) styles |= IMP_ITALIC;
167
 
 
168
 
        t = text;
169
 
        while (cont) {
170
 
                s = strchr(t, '\n');
171
 
                if (s) {
172
 
                        int len2 = s - t;
173
 
                        span = add_span(lay, t, len2, px, styles);
174
 
                        t = s + 1;
175
 
                        len -= len2;
176
 
                        add_line(lay);
177
 
                } else {
178
 
                        span = add_span(lay, text, len, px, styles);
179
 
                        cont = 0;
180
 
                }
181
 
                r_get_color(ctx, node, "fo:color", &span->fg);
182
 
        }
183
 
}
184
 
 
185
 
static void
186
 
text_p(ImpRenderCtx *ctx, struct Layout *lay, iks *node)
187
 
{
188
 
        iks *n, *n2;
189
 
 
190
 
        add_line(lay);
191
 
        for (n = iks_child(node); n; n = iks_next(n)) {
192
 
                if (iks_type(n) == IKS_CDATA) {
193
 
                        text_span(ctx, lay, node, iks_cdata(n), iks_cdata_size(n));
194
 
                } else if (iks_strcmp(iks_name(n), "text:span") == 0) {
195
 
                        for (n2 = iks_child(n); n2; n2 = iks_next(n2)) {
196
 
                                if (iks_type(n2) == IKS_CDATA) {
197
 
                                        text_span(ctx, lay, n2, iks_cdata(n2), iks_cdata_size(n2));
198
 
                                } else if (iks_strcmp(iks_name(n2), "text:s") == 0) {
199
 
                                        char *attr;
200
 
                                        int c = 1;
201
 
                                        attr = iks_find_attrib(n2, "text:c");
202
 
                                        if (attr) c = atoi(attr);
203
 
                                        if (c > 127) {
204
 
                                                c = 127;
205
 
                                                puts("bork bork");
206
 
                                        }
207
 
                                        text_span(ctx, lay, n, lay->spaces, c);
208
 
                                } else if (iks_strcmp(iks_name(n2), "text:a") == 0) {
209
 
                                        text_span(ctx, lay, n, iks_cdata(iks_child(n2)), iks_cdata_size(iks_child(n2)));
210
 
                                } else if (iks_strcmp(iks_name(n2), "text:tab-stop") == 0) {
211
 
                                        text_span(ctx, lay, n, "\t", 1);
212
 
                                } else if (iks_strcmp(iks_name(n2), "text:page-number") == 0) {
213
 
                                        char buf[8];
214
 
                                        sprintf(buf, "%d", ctx->page->nr);
215
 
                                        text_span(ctx, lay, n, iks_stack_strdup(lay->s, buf, 0), strlen(buf));
216
 
                                }
217
 
                        }
218
 
                } else if (iks_strcmp(iks_name(n), "text:line-break") == 0) {
219
 
                        add_line(lay);
220
 
                } else if (iks_strcmp(iks_name(n), "text:a") == 0) {
221
 
                        text_span(ctx, lay, n, iks_cdata(iks_child(n)), iks_cdata_size(iks_child(n)));
222
 
                } else if (iks_strcmp(iks_name(n), "text:page-number") == 0) {
223
 
                        char buf[8];
224
 
                        sprintf(buf, "%d", ctx->page->nr);
225
 
                        text_span(ctx, lay, n, iks_stack_strdup(lay->s, buf, 0), strlen(buf));
226
 
                }
227
 
        }
228
 
}
229
 
 
230
 
static void
231
 
text_list(ImpRenderCtx *ctx, struct Layout *lay, iks *node)
232
 
{
233
 
        iks *n, *n2;
234
 
 
235
 
        for (n = iks_first_tag(node); n; n = iks_next_tag(n)) {
236
 
                for (n2 = iks_first_tag(n); n2; n2 = iks_next_tag(n2)) {
237
 
                        if (strcmp(iks_name(n2), "text:p") == 0) {
238
 
                                text_p(ctx, lay, n2);
239
 
                        } else if (strcmp(iks_name(n2), "text:ordered-list") == 0) {
240
 
                                text_list(ctx, lay, n2);
241
 
                        } else if (strcmp(iks_name(n2), "text:unordered-list") == 0) {
242
 
                                text_list(ctx, lay, n2);
243
 
                        } else if (strcmp(iks_name(n2), "text:list") == 0) {
244
 
                                text_list(ctx, lay, n2);
245
 
                        }
246
 
                }
247
 
        }
248
 
}
249
 
 
250
 
void
251
 
r_text(ImpRenderCtx *ctx, void *drw_data, iks *node)
252
 
{
253
 
        struct Layout lay;
254
 
        iks *n;
255
 
 
256
 
        memset(&lay, 0, sizeof(struct Layout));
257
 
        memset(&lay.spaces, ' ', 128);
258
 
        lay.s = iks_stack_new(sizeof(struct Span) * 16, 0);
259
 
        lay.x = r_get_x(ctx, node, "svg:x");
260
 
        lay.y = r_get_y(ctx, node, "svg:y");
261
 
        lay.w = r_get_y(ctx, node, "svg:width");
262
 
        lay.h = r_get_y(ctx, node, "svg:height");
263
 
 
264
 
        for (n = iks_first_tag(node); n; n = iks_next_tag(n)) {
265
 
                if (strcmp(iks_name(n), "text:p") == 0) {
266
 
                        text_p(ctx, &lay, n);
267
 
                } else if (strcmp(iks_name(n), "text:ordered-list") == 0) {
268
 
                        text_list(ctx, &lay, n);
269
 
                } else if (strcmp(iks_name(n), "text:unordered-list") == 0) {
270
 
                        text_list(ctx, &lay, n);
271
 
                } else if (strcmp(iks_name(n), "text:list") == 0) {
272
 
                        text_list(ctx, &lay, n);
273
 
                }
274
 
        }
275
 
 
276
 
        calc_sizes(ctx, drw_data, &lay);
277
 
        calc_pos(ctx, &lay);
278
 
        _imp_draw_layout(ctx, drw_data, &lay);
279
 
 
280
 
        iks_stack_delete(lay.s);
281
 
}
282
 
/*
283
 
static void
284
 
text_span (render_ctx *ctx, text_ctx *tc, struct layout_s *lout, iks *node, char *text, int len)
285
 
{
286
 
        if (tc->bullet_flag && tc->bullet_sz) size = tc->bullet_sz; else size = r_get_font_size (ctx, tc, node);
287
 
}
288
 
 
289
 
static int
290
 
is_animated (render_ctx *ctx, text_ctx *tc, iks *node)
291
 
{
292
 
        if (!ctx->step_mode) return 0;
293
 
        if (!tc->id) return 0;
294
 
        while (strcmp (iks_name (node), "draw:page") != 0
295
 
                && strcmp (iks_name (node), "style:master-page") != 0)
296
 
                        node = iks_parent (node);
297
 
        node = iks_find (node, "presentation:animations");
298
 
        if (!node) return 0;
299
 
        if (iks_find_with_attrib (node, "presentation:show-text", "draw:shape-id", tc->id)) return 1;
300
 
        return 0;
301
 
}
302
 
 
303
 
static void
304
 
text_p (render_ctx *ctx, text_ctx *tc, iks *node)
305
 
{
306
 
        if (is_animated (ctx, tc, node) && ctx->step_cnt >= ctx->step) lout->flag = 0;
307
 
        ctx->step_cnt++;
308
 
 
309
 
        attr = r_get_style (ctx, node, "text:enable-numbering");
310
 
        if (attr && strcmp (attr, "true") == 0) {
311
 
                if (iks_child (node) && tc->bullet) {
312
 
                        tc->bullet_flag = 1;
313
 
                        text_span (ctx, tc, lout, node, tc->bullet, strlen (tc->bullet));
314
 
                        text_span (ctx, tc, lout, node, " ", 1);
315
 
                        tc->bullet_flag = 0;
316
 
                }
317
 
        }
318
 
 
319
 
        if (!lout->text) {
320
 
lout->h = 0;
321
 
attr = r_get_style (ctx, node, "fo:line-height");
322
 
if (attr) {
323
 
        int ratio = atoi (attr);
324
 
        lout->lh = ratio;
325
 
} else {
326
 
        lout->lh = 100;
327
 
}
328
 
tc->layouts = g_list_append (tc->layouts, lout);
329
 
//              g_object_unref (lout->play);
330
 
//              iks_stack_delete (s);
331
 
                return;
332
 
        }
333
 
 
334
 
        attr = r_get_style (ctx, node, "fo:text-align");
335
 
        if (attr) {
336
 
                if (strcmp (attr, "center") == 0)
337
 
                        pango_layout_set_alignment (lout->play, PANGO_ALIGN_CENTER);
338
 
                else if (strcmp (attr, "end") == 0)
339
 
                        pango_layout_set_alignment (lout->play, PANGO_ALIGN_RIGHT);
340
 
        }
341
 
        pango_layout_set_width (lout->play, tc->w * PANGO_SCALE);
342
 
        pango_layout_set_markup (lout->play, lout->text, lout->text_len);
343
 
        pango_layout_get_pixel_size (lout->play, &lout->w, &lout->h);
344
 
        attr = r_get_style (ctx, node, "fo:line-height");
345
 
        if (attr) {
346
 
                int ratio = atoi (attr);
347
 
                lout->lh = ratio;
348
 
        } else {
349
 
                lout->lh = 100;
350
 
        }
351
 
        tc->layouts = g_list_append (tc->layouts, lout);
352
 
}
353
 
 
354
 
static void
355
 
find_bullet (render_ctx *ctx, text_ctx *tc, iks *node)
356
 
{
357
 
        iks *x;
358
 
        char *t;
359
 
        x = r_get_bullet (ctx, node, "text:list-level-style-bullet");
360
 
        x = iks_find (x, "text:list-level-style-bullet");
361
 
        t = iks_find_attrib (x, "text:bullet-char");
362
 
        if (t) tc->bullet = t; else tc->bullet = "*";
363
 
        x = iks_find (x, "style:properties");
364
 
        t = iks_find_attrib (x, "fo:font-size");
365
 
        if (t) tc->bullet_sz = tc->last_sz * atoi (t) / 100;
366
 
        else tc->bullet_sz = 0;
367
 
}
368
 
 
369
 
void
370
 
r_text (render_ctx *ctx, iks *node)
371
 
{
372
 
        tc.id = iks_find_attrib (node, "draw:id");
373
 
        ctx->step_cnt = 0;
374
 
        for (n = iks_first_tag (node); n; n = iks_next_tag (n)) {
375
 
                if (strcmp (iks_name (n), "text:p") == 0) {
376
 
                        text_p (ctx, &tc, n);
377
 
                } else if (strcmp (iks_name (n), "text:ordered-list") == 0) {
378
 
                        text_list (ctx, &tc, n);
379
 
                } else if (strcmp (iks_name (n), "text:unordered-list") == 0) {
380
 
                        find_bullet (ctx, &tc, n);
381
 
                        text_list (ctx, &tc, n);
382
 
                        tc.bullet = 0;
383
 
                }
384
 
        }
385
 
 
386
 
*/