Graphviz 13.0.0~dev.20250607.1528
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#include <util/gv_math.h>
17
19#include "gvplugin_gdiplus.h"
20#include <stringapiset.h>
21#include <windows.h>
22#include <gdiplus.h>
23#include <vector>
24
25using namespace Gdiplus;
26
28 delete reinterpret_cast<Image*>(us->data);
29}
30
31// convert a UTF-8 string to UTF-16
32static std::vector<wchar_t> utf8_to_utf16(const char *s) {
33
34 // how much space do we need for the UTF-16 string?
35 const int wide_count = MultiByteToWideChar(CP_UTF8, 0, s, -1, nullptr, 0);
36
37 // translate it
38 std::vector<wchar_t> utf16(wide_count);
39 if (wide_count > 0) {
40 (void)MultiByteToWideChar(CP_UTF8, 0, s, -1, utf16.data(), wide_count);
41 } else {
42 utf16.push_back(0);
43 }
44
45 return utf16;
46}
47
48static Image *gdiplus_loadimage(usershape_t *us) {
49 assert(us);
50 assert(us->name);
51
52 if (us->data && us->datafree != gdiplus_freeimage) {
53 us->datafree(us); /* free incompatible cache data */
54 us->data = nullptr;
55 us->datafree = nullptr;
56 }
57
58 if (!us->data) { /* read file into cache */
60 return nullptr;
61
62 /* create image from the usershape file */
63 const std::vector<wchar_t> filename = utf8_to_utf16(us->name);
64 us->data = Image::FromFile(filename.data());
65
66 /* clean up */
67 if (us->data)
69
71 }
72 return reinterpret_cast<Image*>(us->data);
73}
74
75static void gdiplus_loadimage_gdiplus(GVJ_t * job, usershape_t *us, boxf b, bool)
76{
77 /* get the image from usershape details, then blit it to the context */
78 if (Image *image = gdiplus_loadimage(us)) {
79 assert(job != NULL);
80 auto g = reinterpret_cast<Graphics*>(job->context);
81 g->DrawImage(image, RectF(d2f(b.LL.x), d2f(b.LL.y), d2f(b.UR.x - b.LL.x),
82 d2f(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};
node NULL
Definition grammar.y:180
void gvusershape_file_release(usershape_t *us)
bool gvusershape_file_access(usershape_t *us)
Arithmetic helper functions.
static float d2f(double v)
Definition gv_math.h:152
static gvloadimage_engine_t engine
static Image * gdiplus_loadimage(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:37
@ FORMAT_GIF
Definition gvrender_gd.c:36
@ FORMAT_PNG
Definition gvrender_gd.c:38
T_cell image
Definition htmlparse.y:340
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:89