gvplugin_gdiplus.cpp 2.8 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 <gvc/gvplugin.h>
  11. #include "gvplugin_gdiplus.h"
  12. extern gvplugin_installed_t gvrender_gdiplus_types[];
  13. extern gvplugin_installed_t gvtextlayout_gdiplus_types[];
  14. extern gvplugin_installed_t gvloadimage_gdiplus_types[];
  15. extern gvplugin_installed_t gvdevice_gdiplus_types[];
  16. extern gvplugin_installed_t gvdevice_gdiplus_types_for_cairo[];
  17. using namespace std;
  18. using namespace Gdiplus;
  19. /* class id corresponding to each format_type */
  20. static GUID format_id [] = {
  21. GUID_NULL,
  22. GUID_NULL,
  23. ImageFormatBMP,
  24. ImageFormatEMF,
  25. ImageFormatEMF,
  26. ImageFormatGIF,
  27. ImageFormatJPEG,
  28. ImageFormatPNG,
  29. ImageFormatTIFF
  30. };
  31. static ULONG_PTR _gdiplusToken = 0;
  32. static void UnuseGdiplus()
  33. {
  34. GdiplusShutdown(_gdiplusToken);
  35. }
  36. void UseGdiplus()
  37. {
  38. /* only startup once, and ensure we get shutdown */
  39. if (!_gdiplusToken)
  40. {
  41. GdiplusStartupInput input;
  42. GdiplusStartup(&_gdiplusToken, &input, nullptr);
  43. atexit(&UnuseGdiplus);
  44. }
  45. }
  46. const Gdiplus::StringFormat* GetGenericTypographic()
  47. {
  48. const Gdiplus::StringFormat* format = StringFormat::GenericTypographic();
  49. return format;
  50. }
  51. void SaveBitmapToStream(Bitmap &bitmap, IStream *stream, int format)
  52. {
  53. /* search the encoders for one that matches our device id, then save the bitmap there */
  54. GdiplusStartupInput gdiplusStartupInput;
  55. ULONG_PTR gdiplusToken;
  56. GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
  57. UINT encoderNum;
  58. UINT encoderSize;
  59. GetImageEncodersSize(&encoderNum, &encoderSize);
  60. vector<char> codec_buffer(encoderSize);
  61. ImageCodecInfo *codecs = (ImageCodecInfo *)&codec_buffer.front();
  62. GetImageEncoders(encoderNum, encoderSize, codecs);
  63. for (UINT i = 0; i < encoderNum; ++i)
  64. if (memcmp(&(format_id[format]), &codecs[i].FormatID, sizeof(GUID)) == 0) {
  65. bitmap.Save(stream, &codecs[i].Clsid, nullptr);
  66. break;
  67. }
  68. }
  69. static gvplugin_api_t apis[] = {
  70. {API_render, gvrender_gdiplus_types},
  71. {API_textlayout, gvtextlayout_gdiplus_types},
  72. {API_loadimage, gvloadimage_gdiplus_types},
  73. {API_device, gvdevice_gdiplus_types},
  74. {API_device, gvdevice_gdiplus_types_for_cairo},
  75. {(api_t)0, 0},
  76. };
  77. #ifdef __cplusplus
  78. extern "C" {
  79. #endif
  80. #ifdef GVDLL
  81. #define GVPLUGIN_GDIPLUS_API __declspec(dllexport)
  82. #else
  83. #define GVPLUGIN_GDIPLUS_API
  84. #endif
  85. GVPLUGIN_GDIPLUS_API gvplugin_library_t gvplugin_gdiplus_LTX_library = {
  86. const_cast<char*>("gdiplus"), apis
  87. };
  88. #ifdef __cplusplus
  89. }
  90. #endif