Graphviz 12.0.1~dev.20240716.0800
Loading...
Searching...
No Matches
gvloadimage_gdiplus.cpp
Go to the documentation of this file.
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
11#include "config.h"
12
13#include <stdlib.h>
14#include <stddef.h>
15#include <string.h>
16
18#include "gvplugin_gdiplus.h"
19#include <stringapiset.h>
20#include <windows.h>
21#include <gdiplus.h>
22#include <vector>
23
24using namespace Gdiplus;
25
27 delete reinterpret_cast<Image*>(us->data);
28}
29
30// convert a UTF-8 string to UTF-16
31static std::vector<wchar_t> utf8_to_utf16(const char *s) {
32
33 // how much space do we need for the UTF-16 string?
34 const int wide_count = MultiByteToWideChar(CP_UTF8, 0, s, -1, nullptr, 0);
35
36 // translate it
37 std::vector<wchar_t> utf16(wide_count);
38 if (wide_count > 0) {
39 (void)MultiByteToWideChar(CP_UTF8, 0, s, -1, utf16.data(), wide_count);
40 } else {
41 utf16.push_back(0);
42 }
43
44 return utf16;
45}
46
47static Image* gdiplus_loadimage(GVJ_t * job, usershape_t *us)
48{
49 assert(job);
50 (void)job;
51 assert(us);
52 assert(us->name);
53
54 if (us->data && us->datafree != gdiplus_freeimage) {
55 us->datafree(us); /* free incompatible cache data */
56 us->data = nullptr;
57 us->datafree = nullptr;
58 }
59
60 if (!us->data) { /* read file into cache */
62 return nullptr;
63
64 /* create image from the usershape file */
65 const std::vector<wchar_t> filename = utf8_to_utf16(us->name);
66 us->data = Image::FromFile(filename.data());
67
68 /* clean up */
69 if (us->data)
71
73 }
74 return reinterpret_cast<Image*>(us->data);
75}
76
77static void gdiplus_loadimage_gdiplus(GVJ_t * job, usershape_t *us, boxf b, bool)
78{
79 /* get the image from usershape details, then blit it to the context */
80 if (Image *image = gdiplus_loadimage(job, us)) {
81 auto g = reinterpret_cast<Graphics*>(job->context);
82 g->DrawImage(image, RectF(b.LL.x, b.LL.y, b.UR.x - b.LL.x, b.UR.y - b.LL.y));
83 }
84}
85
89
91 {FORMAT_BMP, "bmp:gdiplus", 8, &engine, nullptr},
92 {FORMAT_GIF, "gif:gdiplus", 8, &engine, nullptr},
93 {FORMAT_JPEG, "jpe:gdiplus", 8, &engine, nullptr},
94 {FORMAT_JPEG, "jpeg:gdiplus", 8, &engine, nullptr},
95 {FORMAT_JPEG, "jpg:gdiplus", 8, &engine, nullptr},
96 {FORMAT_PNG, "png:gdiplus", 8, &engine, nullptr},
97 {0, nullptr, 0, nullptr, nullptr}
98};
void gvusershape_file_release(usershape_t *us)
bool gvusershape_file_access(usershape_t *us)
static gvloadimage_engine_t engine
static Image * gdiplus_loadimage(GVJ_t *job, usershape_t *us)
static void gdiplus_loadimage_gdiplus(GVJ_t *job, usershape_t *us, boxf b, bool)
static std::vector< wchar_t > utf8_to_utf16(const char *s)
static void gdiplus_freeimage(usershape_t *us)
gvplugin_installed_t gvloadimage_gdiplus_types[]
@ FORMAT_BMP
@ FORMAT_JPEG
Definition gvrender_gd.c:32
@ FORMAT_GIF
Definition gvrender_gd.c:31
@ FORMAT_PNG
Definition gvrender_gd.c:33
T_cell image
Definition htmlparse.y:538
void * context
Definition gvcjob.h:295
Definition geom.h:41
pointf UR
Definition geom.h:41
pointf LL
Definition geom.h:41
ingroup plugin_api
Definition gvplugin.h:35
double x
Definition geom.h:29
double y
Definition geom.h:29
const char * name
Definition usershape.h:54
void(* datafree)(usershape_t *us)
Definition usershape.h:65
void * data
Definition usershape.h:63
Definition grammar.c:93