作図ソフト dia の改良版
修订版 | c90262781e619bd22d8ab25a7b4c1da669353fea (tree) |
---|---|
时间 | 2014-11-16 01:14:04 |
作者 | Hans Breuer <hans@breu...> |
Commiter | Hans Breuer |
cairo: use surface mime data to decrease file size for PDF and SVG
Assuming that the linked image file is already in the best possible
format/encoding to be used rather than recompressing. If the image
in the PDF turns black, that's becuase of a bug in cairo and Dia
not providing the fallback uncompressed rendering.
@@ -951,6 +951,52 @@ draw_string(DiaRenderer *self, | ||
951 | 951 | DIAG_STATE(renderer->cr) |
952 | 952 | } |
953 | 953 | |
954 | +static cairo_surface_t * | |
955 | +_image_to_mime_surface (DiaCairoRenderer *renderer, | |
956 | + DiaImage *image) | |
957 | +{ | |
958 | + cairo_surface_type_t st; | |
959 | + const char *fname = dia_image_filename (image); | |
960 | + int w = dia_image_width(image); | |
961 | + int h = dia_image_height(image); | |
962 | + const char *mime_type = NULL; | |
963 | + | |
964 | + if (!renderer->surface) | |
965 | + return NULL; | |
966 | + | |
967 | + /* We only use the "mime" surface if: | |
968 | + * - the target supports it | |
969 | + * - we have a file name with a supported format | |
970 | + * - the cairo version is new enough including | |
971 | + * http://cgit.freedesktop.org/cairo/commit/?id=35e0a2685134 | |
972 | + */ | |
973 | + if (g_str_has_suffix (fname, ".jpg") || g_str_has_suffix (fname, ".jpeg")) | |
974 | + mime_type = CAIRO_MIME_TYPE_JPEG; | |
975 | + else if (g_str_has_suffix (fname, ".png")) | |
976 | + mime_type = CAIRO_MIME_TYPE_PNG; | |
977 | + st = cairo_surface_get_type (renderer->surface); | |
978 | + if ( mime_type | |
979 | + && cairo_version() >= CAIRO_VERSION_ENCODE(1, 12, 18) | |
980 | + && (CAIRO_SURFACE_TYPE_PDF == st || CAIRO_SURFACE_TYPE_SVG == st)) | |
981 | + { | |
982 | + cairo_surface_t *surface; | |
983 | + gchar *data = NULL; | |
984 | + gsize length = 0; | |
985 | + | |
986 | + /* we still ned to create the image surface, but dont need to fill it */ | |
987 | + surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h); | |
988 | + cairo_surface_mark_dirty (surface); /* no effect */ | |
989 | + if ( g_file_get_contents (fname, &data, &length, NULL) | |
990 | + && cairo_surface_set_mime_data (surface, mime_type, | |
991 | + (unsigned char *)data, | |
992 | + length, g_free, data) == CAIRO_STATUS_SUCCESS) | |
993 | + return surface; | |
994 | + cairo_surface_destroy (surface); | |
995 | + g_free (data); | |
996 | + } | |
997 | + return NULL; | |
998 | +} | |
999 | + | |
954 | 1000 | static void |
955 | 1001 | draw_rotated_image (DiaRenderer *self, |
956 | 1002 | Point *point, |
@@ -968,7 +1014,11 @@ draw_rotated_image (DiaRenderer *self, | ||
968 | 1014 | DIAG_NOTE(g_message("draw_image %fx%f [%d(%d),%d] @%f,%f", |
969 | 1015 | width, height, w, rs, h, point->x, point->y)); |
970 | 1016 | |
971 | - if (dia_image_rgba_data (image)) | |
1017 | + if ((surface = _image_to_mime_surface (renderer, image)) != NULL) | |
1018 | + { | |
1019 | + data = NULL; | |
1020 | + } | |
1021 | + else if (dia_image_rgba_data (image)) | |
972 | 1022 | { |
973 | 1023 | const guint8 *p1 = dia_image_rgba_data (image); |
974 | 1024 | /* we need to make a copy to rearrange channels ... */ |