]> granicus.if.org Git - graphviz/commitdiff
GDI+ loadimage plugin; more conscientious allocation of GDI+ text strings
authorglenlow <devnull@localhost>
Fri, 18 Apr 2008 14:10:43 +0000 (14:10 +0000)
committerglenlow <devnull@localhost>
Fri, 18 Apr 2008 14:10:43 +0000 (14:10 +0000)
plugin/gdiplus/gvloadimage_gdiplus.cpp [new file with mode: 0755]
plugin/gdiplus/gvplugin_gdiplus.cpp
plugin/gdiplus/gvplugin_gdiplus.h [new file with mode: 0755]
plugin/gdiplus/gvrender_gdiplus.cpp

diff --git a/plugin/gdiplus/gvloadimage_gdiplus.cpp b/plugin/gdiplus/gvloadimage_gdiplus.cpp
new file mode 100755 (executable)
index 0000000..9d94d12
--- /dev/null
@@ -0,0 +1,91 @@
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "gvplugin_loadimage.h"
+#include "gvplugin_gdiplus.h"
+
+#include <windows.h>
+#include "GdiPlus.h"
+
+#include "FileStream.h"
+
+using namespace Gdiplus;
+
+static void gdiplus_freeimage(usershape_t *us)
+{
+       delete (Image*)us->data;
+}
+
+static Image* gdiplus_loadimage(GVJ_t * job, usershape_t *us)
+{
+    assert(job);
+    assert(us);
+    assert(us->name);
+
+    if (us->data && us->datafree != gdiplus_freeimage) {
+            us->datafree(us);        /* free incompatible cache data */
+            us->data = NULL;
+            us->datafree = NULL;
+       }
+    
+    if (!us->data) { /* read file into cache */
+               if (!gvusershape_file_access(us))
+                       return NULL;
+
+               /* create image from the usershape file */
+               /* NOTE: since Image::FromStream consumes the stream, we assume FileStream's lifetime should be shorter than us->name and us->f... */   
+               IStream *stream = FileStream::Create(us->name, us->f);
+               us->data = Image::FromStream (stream);
+               
+               /* clean up */
+               if (us->data)
+                       us->datafree = gdiplus_freeimage;
+               stream->Release();
+                       
+               gvusershape_file_release(us);
+    }
+    return (Image *)(us->data);
+}
+
+static void gdiplus_loadimage_gdiplus(GVJ_t * job, usershape_t *us, boxf b, boolean filled)
+{
+       /* get the image from usershape details, then blit it to the context */
+       Image *image = gdiplus_loadimage(job, us);
+       if (image)
+               ((Graphics *)job->context)->DrawImage(image, RectF(b.LL.x, b.LL.y, b.UR.x - b.LL.x, b.UR.y - b.LL.y));
+}
+
+static gvloadimage_engine_t engine = {
+    gdiplus_loadimage_gdiplus
+};
+
+gvplugin_installed_t gvloadimage_gdiplus_types[] = {
+       {FORMAT_BMP, "bmp:gdiplus", 8, &engine, NULL},
+       {FORMAT_GIF, "gif:gdiplus", 8, &engine, NULL},
+       {FORMAT_JPEG, "jpe:gdiplus", 8, &engine, NULL},
+       {FORMAT_JPEG, "jpeg:gdiplus", 8, &engine, NULL},
+       {FORMAT_JPEG, "jpg:gdiplus", 8, &engine, NULL},
+       {FORMAT_PNG, "png:gdiplus", 8, &engine, NULL},
+       {0, NULL, 0, NULL, NULL}
+};
index 6a2c0fcb625106b9353edcc8de3ba2da417c27b9..0301de1b724eca13543a4708e3a06feae90dff68 100755 (executable)
 
 extern gvplugin_installed_t gvrender_gdiplus_types;
 // extern gvplugin_installed_t gvtextlayout_gdiplus_types;
-// extern gvplugin_installed_t gvloadimage_gdiplus_types;
+extern gvplugin_installed_t gvloadimage_gdiplus_types;
 extern gvplugin_installed_t gvdevice_gdiplus_types;
 
 static gvplugin_api_t apis[] = {
     {API_render, &gvrender_gdiplus_types},
   //  {API_textlayout, &gvtextlayout_gdiplus_types},
-  //  {API_loadimage, &gvloadimage_gdiplus_types},
+       {API_loadimage, &gvloadimage_gdiplus_types},
     {API_device, &gvdevice_gdiplus_types},
     {(api_t)0, 0},
 };
diff --git a/plugin/gdiplus/gvplugin_gdiplus.h b/plugin/gdiplus/gvplugin_gdiplus.h
new file mode 100755 (executable)
index 0000000..6ddc0fc
--- /dev/null
@@ -0,0 +1,31 @@
+/* $Id$ $Revision$ */
+/* vim:set shiftwidth=4 ts=8: */
+
+/**********************************************************
+*      This software is part of the graphviz package      *
+*                http://www.graphviz.org/                 *
+*                                                         *
+*            Copyright (c) 1994-2004 AT&T Corp.           *
+*                and is licensed under the                *
+*            Common Public License, Version 1.0           *
+*                      by AT&T Corp.                      *
+*                                                         *
+*        Information and Software Systems Research        *
+*              AT&T Research, Florham Park NJ             *
+**********************************************************/
+
+#ifndef GVPLUGIN_GDIPLUS_H
+#define GVPLUGIN_GDIPLUS_H
+
+typedef enum {
+       FORMAT_NONE,
+       FORMAT_BMP,
+       FORMAT_EMF,
+       FORMAT_EMFPLUS,
+       FORMAT_GIF,
+       FORMAT_JPEG,
+       FORMAT_PNG,
+       FORMAT_TIFF
+} format_type;
+
+#endif
index ddb84abb9f0b1828e99eb38405733bb66a8c0c35..26b40380b37266a40f8c1ed245b2662dc5d43e46 100755 (executable)
@@ -24,6 +24,7 @@
 #include "gvplugin_device.h"
 #include "gvplugin_render.h"
 #include "graph.h"
+#include "gvplugin_gdiplus.h"
 
 #include <windows.h>
 #include "GdiPlus.h"
@@ -36,18 +37,9 @@ extern "C" size_t gvdevice_write(GVJ_t *job, const unsigned char *s, unsigned in
 using namespace std;
 using namespace Gdiplus;
 
-typedef enum {
-       FORMAT_BMP,
-       FORMAT_EMF,
-       FORMAT_EMFPLUS,
-       FORMAT_GIF,
-       FORMAT_JPEG,
-       FORMAT_PNG,
-       FORMAT_TIFF
-} format_type;
-
 /* class id corresponding to each format_type */
 static GUID format_id [] = {
+       GUID_NULL,
        ImageFormatBMP,
        ImageFormatEMF,
        ImageFormatEMF,
@@ -220,6 +212,7 @@ static auto_ptr<Font> find_font(char *fontname, double fontsize)
                (LPARAM)&found_font,
                0) == 0) {
                found_font.lfHeight = (LONG)-fontsize;
+               found_font.lfWidth = 0;
                return auto_ptr<Font>(new Font(reference.hdc, &found_font));
        }
        else
@@ -230,9 +223,11 @@ static void gdiplusgen_textpara(GVJ_t *job, pointf p, textpara_t *para)
 {
        /* convert incoming UTF8 string to wide chars */
        /* NOTE: conversion is 1 or more UTF8 chars to 1 wide char */
-       vector<WCHAR> wide_str(strlen(para->str) + 1);
-       int wide_count = MultiByteToWideChar(CP_UTF8, 0, para->str, -1, &wide_str.front(), wide_str.size());
+       int wide_count = MultiByteToWideChar(CP_UTF8, 0, para->str, -1, NULL, 0);
        if (wide_count > 1) {
+               vector<WCHAR> wide_str(wide_count);
+               MultiByteToWideChar(CP_UTF8, 0, para->str, -1, &wide_str.front(), wide_count);
+               
                /* adjust text position */
                switch (para->just) {
                case 'r':