gvdevice_quartz.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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 <gvc/gvplugin_device.h>
  12. #include "gvplugin_quartz.h"
  13. #include <stdbool.h>
  14. #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1040 && defined(HAVE_PANGOCAIRO)
  15. static const void *memory_data_consumer_get_byte_pointer(void *info)
  16. {
  17. return info;
  18. }
  19. CGDataProviderDirectCallbacks memory_data_provider_callbacks = {
  20. 0,
  21. memory_data_consumer_get_byte_pointer,
  22. NULL,
  23. NULL,
  24. NULL
  25. };
  26. static void quartz_format(GVJ_t *job)
  27. {
  28. /* image destination -> data consumer -> job's gvdevice */
  29. /* data provider <- job's imagedata */
  30. CGDataConsumerRef data_consumer = CGDataConsumerCreate(job, &device_data_consumer_callbacks);
  31. CGImageDestinationRef image_destination =
  32. CGImageDestinationCreateWithDataConsumer(data_consumer,
  33. format_to_uti((format_type)job->device.id), 1, NULL);
  34. CGDataProviderRef data_provider = CGDataProviderCreateDirect(job->imagedata, BYTES_PER_PIXEL * job->width * job->height, &memory_data_provider_callbacks);
  35. /* add the bitmap image to the destination and save it */
  36. CGColorSpaceRef color_space = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
  37. CGImageRef image = CGImageCreate (
  38. job->width, /* width in pixels */
  39. job->height, /* height in pixels */
  40. BITS_PER_COMPONENT, /* bits per component */
  41. BYTES_PER_PIXEL * 8, /* bits per pixel */
  42. BYTES_PER_PIXEL * job->width, /* bytes per row: exactly width # of pixels */
  43. color_space, /* color space: sRGB */
  44. kCGImageAlphaPremultipliedFirst|kCGBitmapByteOrder32Little, /* bitmap info: corresponds to CAIRO_FORMAT_ARGB32 */
  45. data_provider, /* data provider: from imagedata */
  46. NULL, /* decode: don't remap colors */
  47. false, // don't interpolate
  48. kCGRenderingIntentDefault /* rendering intent (what to do with out-of-gamut colors): default */
  49. );
  50. CGImageDestinationAddImage(image_destination, image, NULL);
  51. CGImageDestinationFinalize(image_destination);
  52. /* clean up */
  53. CGImageRelease(image);
  54. CGColorSpaceRelease(color_space);
  55. CGDataProviderRelease(data_provider);
  56. if (image_destination)
  57. CFRelease(image_destination);
  58. CGDataConsumerRelease(data_consumer);
  59. }
  60. static gvdevice_engine_t quartz_engine = {
  61. NULL, /* quartz_initialize */
  62. quartz_format,
  63. NULL, /* quartz_finalize */
  64. };
  65. static gvdevice_features_t device_features_quartz = {
  66. GVDEVICE_BINARY_FORMAT
  67. | GVDEVICE_DOES_TRUECOLOR,/* flags */
  68. {0.,0.}, /* default margin - points */
  69. {0.,0.}, /* default page width, height - points */
  70. {96.,96.}, /* dpi */
  71. };
  72. gvplugin_installed_t gvdevice_quartz_types_for_cairo[] = {
  73. {FORMAT_BMP, "bmp:cairo", 7, &quartz_engine, &device_features_quartz},
  74. {FORMAT_GIF, "gif:cairo", 7, &quartz_engine, &device_features_quartz},
  75. {FORMAT_EXR, "exr:cairo", 7, &quartz_engine, &device_features_quartz},
  76. {FORMAT_ICNS, "icns:cairo", 7, &quartz_engine, &device_features_quartz},
  77. {FORMAT_ICO, "ico:cairo", 7, &quartz_engine, &device_features_quartz},
  78. {FORMAT_JPEG, "jpe:cairo", 7, &quartz_engine, &device_features_quartz},
  79. {FORMAT_JPEG, "jpeg:cairo", 7, &quartz_engine, &device_features_quartz},
  80. {FORMAT_JPEG, "jpg:cairo", 7, &quartz_engine, &device_features_quartz},
  81. {FORMAT_JPEG2000, "jp2:cairo", 7, &quartz_engine, &device_features_quartz},
  82. {FORMAT_PICT, "pct:cairo", 7, &quartz_engine, &device_features_quartz},
  83. {FORMAT_PICT, "pict:cairo", 7, &quartz_engine, &device_features_quartz},
  84. {FORMAT_PNG, "png:cairo", 7, &quartz_engine, &device_features_quartz},
  85. {FORMAT_PSD, "psd:cairo", 7, &quartz_engine, &device_features_quartz},
  86. {FORMAT_SGI, "sgi:cairo", 7, &quartz_engine, &device_features_quartz},
  87. {FORMAT_TIFF, "tif:cairo", 7, &quartz_engine, &device_features_quartz},
  88. {FORMAT_TIFF, "tiff:cairo", 7, &quartz_engine, &device_features_quartz},
  89. {FORMAT_TGA, "tga:cairo", 7, &quartz_engine, &device_features_quartz},
  90. {0, NULL, 0, NULL, NULL}
  91. };
  92. #endif