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)