Mercurial > geeqie.yaz
comparison src/print.c @ 1723:25471efb11ba
print text using pango renderer
- the text is sent to postscript as a bitmap
- this fixes printing of non-ascii characters
http://sourceforge.net/tracker/index.php?func=detail&aid=2836135&group_id=222125&atid=1054680
author | nadvornik |
---|---|
date | Sat, 26 Sep 2009 08:47:28 +0000 |
parents | 3f47ab223486 |
children |
comparison
equal
deleted
inserted
replaced
1722:844714862249 | 1723:25471efb11ba |
---|---|
1334 if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); | 1334 if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); |
1335 | 1335 |
1336 return ret; | 1336 return ret; |
1337 } | 1337 } |
1338 | 1338 |
1339 static const gchar *ps_text_to_hex_array(FILE *f, const gchar *text, gdouble x, gdouble y) | 1339 static gdouble convert_pango_dpi(gdouble points); |
1340 { | |
1341 static gchar hex_digits[] = "0123456789abcdef"; | |
1342 const gchar *p; | |
1343 | |
1344 if (!text) return NULL; | |
1345 | |
1346 g_fprintf(f, "%f %f moveto\n", x, y); | |
1347 g_fprintf(f, "<"); | |
1348 | |
1349 /* fixme: convert utf8 to ascii or proper locale string.. */ | |
1350 | |
1351 p = text; | |
1352 while (*p != '\0' && *p != '\n') | |
1353 { | |
1354 gchar text[3]; | |
1355 | |
1356 text[0] = hex_digits[*p >> 4]; | |
1357 text[1] = hex_digits[*p & 0xf]; | |
1358 text[2] = '\0'; | |
1359 | |
1360 g_fprintf(f, "%s", text); | |
1361 | |
1362 p++; | |
1363 } | |
1364 | |
1365 g_fprintf(f, ">\n"); | |
1366 g_fprintf(f, "dup stringwidth pop 2 div neg 0 rmoveto show\n"); | |
1367 | |
1368 return p; | |
1369 } | |
1370 | |
1371 static void ps_text_parse(FILE *f, const gchar *text, gdouble x, gdouble y, gdouble point_size) | |
1372 { | |
1373 const gchar *p; | |
1374 | |
1375 if (!text) return; | |
1376 | |
1377 g_fprintf(f, "newpath\n"); | |
1378 | |
1379 p = text; | |
1380 while (p && *p != '\0') | |
1381 { | |
1382 p = ps_text_to_hex_array(f, p, x, y); | |
1383 if (p && *p == '\n') p++; | |
1384 y -= point_size; | |
1385 } | |
1386 | |
1387 g_fprintf(f, "closepath\n"); | |
1388 } | |
1389 | 1340 |
1390 static gboolean print_job_ps_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, | 1341 static gboolean print_job_ps_page_text(PrintWindow *pw, const gchar *text, gdouble point_size, |
1391 gdouble x, gdouble y, gdouble width, | 1342 gdouble x, gdouble y, gdouble width, |
1392 guint8 r, guint8 g, guint8 b) | 1343 guint8 r, guint8 g, guint8 b) |
1393 { | 1344 { |
1394 FILE *f; | 1345 PangoLayout *layout; |
1395 PipeError *pe; | 1346 PangoFontDescription *desc; |
1396 gchar *lc_pointer; | 1347 GdkPixbuf *pixbuf; |
1348 gint lw, lh; | |
1397 gboolean ret; | 1349 gboolean ret; |
1398 | 1350 gdouble scale_to_max_dpi = (pw->max_dpi >= PRINT_PS_DPI_MIN) ? pw->max_dpi / 72.0 : 1200.0 / 72.0; |
1399 if (!text) return TRUE; | 1351 |
1400 | 1352 layout = gtk_widget_create_pango_layout(pw->dialog->dialog, NULL); |
1401 f = print_job_ps_fd(pw); | 1353 |
1402 if (!f) return FALSE; | 1354 desc = pango_font_description_new(); |
1403 | 1355 pango_font_description_set_size(desc, convert_pango_dpi(point_size) * PANGO_SCALE * scale_to_max_dpi); |
1404 lc_pointer = g_strdup(setlocale(LC_NUMERIC, NULL)); | 1356 pango_layout_set_font_description(layout, desc); |
1405 setlocale(LC_NUMERIC, POSTSCRIPT_LOCALE); | 1357 pango_font_description_free(desc); |
1406 | 1358 |
1407 pe = pipe_handler_new(); | 1359 pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); |
1408 | 1360 pango_layout_set_text(layout, text, -1); |
1409 g_fprintf(f, "/Sans findfont\n"); | 1361 |
1410 g_fprintf(f, "%f scalefont\n", point_size); | 1362 pango_layout_get_pixel_size(layout, &lw, &lh); |
1411 g_fprintf(f, "setfont\n"); | 1363 x = x - (gdouble)lw / 2.0 / scale_to_max_dpi; |
1412 | 1364 |
1413 g_fprintf(f, "%f %f %f setrgbcolor\n", (gdouble)r / 255.0, (gdouble)g / 255.0, (gdouble)b / 255.0); | 1365 pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, lw, lh); |
1414 ps_text_parse(f, text, x, pw->layout_height - y - point_size, point_size); | 1366 gdk_pixbuf_fill(pixbuf, 0xffffffff); |
1415 | 1367 pixbuf_draw_layout(pixbuf, layout, pw->dialog->dialog, 0, 0, r, g, b, 255); |
1416 ret = !pipe_handler_check(pe); | 1368 g_object_unref(G_OBJECT(layout)); |
1417 pipe_handler_free(pe); | 1369 |
1418 | 1370 ret = print_job_ps_page_image(pw, pixbuf, x, y, |
1419 if (lc_pointer) | 1371 /* do not allow rescaling of the pixbuf due to rounding errors */ |
1420 { | 1372 ((gdouble)lw + 0.01) / scale_to_max_dpi, |
1421 setlocale(LC_NUMERIC, lc_pointer); | 1373 ((gdouble)lh + 0.01) / scale_to_max_dpi, |
1422 g_free(lc_pointer); | 1374 0, 0); |
1423 } | 1375 |
1424 | 1376 g_object_unref(G_OBJECT(pixbuf)); |
1425 if (!ret) print_job_throw_error(pw, _("SIGPIPE error writing to printer.")); | |
1426 | 1377 |
1427 return ret; | 1378 return ret; |
1428 } | 1379 } |
1429 | 1380 |
1430 static gboolean print_job_ps_end(PrintWindow *pw) | 1381 static gboolean print_job_ps_end(PrintWindow *pw) |