gvdevice_gdk.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*************************************************************************
  2. * Copyright (c) 2011 AT&T Intellectual Property
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors: Details at https://graphviz.org
  9. *************************************************************************/
  10. #include "config.h"
  11. #include <assert.h>
  12. #include <gvc/gvplugin_device.h>
  13. #include <gvc/gvio.h>
  14. #include <limits.h>
  15. #include <util/unreachable.h>
  16. #ifdef HAVE_PANGOCAIRO
  17. #include <gdk-pixbuf/gdk-pixbuf.h>
  18. typedef enum {
  19. FORMAT_BMP,
  20. FORMAT_ICO,
  21. FORMAT_JPEG,
  22. FORMAT_PNG,
  23. FORMAT_TIFF,
  24. } format_type;
  25. /*
  26. * Does an in-place conversion of a CAIRO ARGB32 image to GDK RGBA
  27. */
  28. static void
  29. argb2rgba ( unsigned int width, unsigned int height, char *data)
  30. {
  31. /* define indexes to color bytes in each format */
  32. #define Ba 0
  33. #define Ga 1
  34. #define Ra 2
  35. #define Aa 3
  36. #define Rb 0
  37. #define Gb 1
  38. #define Bb 2
  39. #define Ab 3
  40. unsigned int x, y;
  41. for (y = 0; y < height; y++) {
  42. for (x = 0; x < width; x++) {
  43. /* swap red and blue */
  44. char r = data[Ra];
  45. data[Bb] = data[Ba];
  46. data[Rb] = r;
  47. data += 4;
  48. }
  49. }
  50. }
  51. static gboolean writer(const char *buf, gsize count, GError **error,
  52. void *data) {
  53. (void)error;
  54. return count == gvwrite(data, buf, count);
  55. }
  56. static void gdk_format(GVJ_t * job)
  57. {
  58. char *format_str = "";
  59. GdkPixbuf *pixbuf;
  60. switch (job->device.id) {
  61. case FORMAT_BMP:
  62. format_str = "bmp";
  63. break;
  64. case FORMAT_ICO:
  65. format_str = "ico";
  66. break;
  67. case FORMAT_JPEG:
  68. format_str = "jpeg";
  69. break;
  70. case FORMAT_PNG:
  71. format_str = "png";
  72. break;
  73. case FORMAT_TIFF:
  74. format_str = "tiff";
  75. break;
  76. default:
  77. UNREACHABLE();
  78. }
  79. argb2rgba(job->width, job->height, job->imagedata);
  80. assert(job->width <= (unsigned)INT_MAX / 4 && "width out of range");
  81. assert(job->height <= (unsigned)INT_MAX && "height out of range");
  82. pixbuf = gdk_pixbuf_new_from_data(
  83. (unsigned char*)(job->imagedata), // data
  84. GDK_COLORSPACE_RGB, // colorspace
  85. TRUE, // has_alpha
  86. 8, // bits_per_sample
  87. (int)job->width, // width
  88. (int)job->height, // height
  89. 4 * (int)job->width, // rowstride
  90. NULL, // destroy_fn
  91. NULL // destroy_fn_data
  92. );
  93. gdk_pixbuf_save_to_callback(pixbuf, writer, job, format_str, NULL, NULL);
  94. g_object_unref(pixbuf);
  95. }
  96. static gvdevice_engine_t gdk_engine = {
  97. NULL, /* gdk_initialize */
  98. gdk_format,
  99. NULL, /* gdk_finalize */
  100. };
  101. static gvdevice_features_t device_features_gdk = {
  102. GVDEVICE_BINARY_FORMAT
  103. | GVDEVICE_DOES_TRUECOLOR,/* flags */
  104. {0.,0.}, /* default margin - points */
  105. {0.,0.}, /* default page width, height - points */
  106. {96.,96.}, /* dpi */
  107. };
  108. #endif
  109. gvplugin_installed_t gvdevice_gdk_types[] = {
  110. #ifdef HAVE_PANGOCAIRO
  111. {FORMAT_BMP, "bmp:cairo", 6, &gdk_engine, &device_features_gdk},
  112. {FORMAT_ICO, "ico:cairo", 6, &gdk_engine, &device_features_gdk},
  113. {FORMAT_JPEG, "jpe:cairo", 6, &gdk_engine, &device_features_gdk},
  114. {FORMAT_JPEG, "jpeg:cairo", 6, &gdk_engine, &device_features_gdk},
  115. {FORMAT_JPEG, "jpg:cairo", 6, &gdk_engine, &device_features_gdk},
  116. {FORMAT_PNG, "png:cairo", 6, &gdk_engine, &device_features_gdk},
  117. {FORMAT_TIFF, "tif:cairo", 6, &gdk_engine, &device_features_gdk},
  118. {FORMAT_TIFF, "tiff:cairo", 6, &gdk_engine, &device_features_gdk},
  119. #endif
  120. {0, NULL, 0, NULL, NULL}
  121. };