From fee4138c38f897a25c22261b017d4d32cb0d8611 Mon Sep 17 00:00:00 2001 From: glenlow Date: Fri, 18 Apr 2008 14:10:43 +0000 Subject: [PATCH] GDI+ loadimage plugin; more conscientious allocation of GDI+ text strings --- plugin/gdiplus/gvloadimage_gdiplus.cpp | 91 ++++++++++++++++++++++++++ plugin/gdiplus/gvplugin_gdiplus.cpp | 4 +- plugin/gdiplus/gvplugin_gdiplus.h | 31 +++++++++ plugin/gdiplus/gvrender_gdiplus.cpp | 19 ++---- 4 files changed, 131 insertions(+), 14 deletions(-) create mode 100755 plugin/gdiplus/gvloadimage_gdiplus.cpp create mode 100755 plugin/gdiplus/gvplugin_gdiplus.h diff --git a/plugin/gdiplus/gvloadimage_gdiplus.cpp b/plugin/gdiplus/gvloadimage_gdiplus.cpp new file mode 100755 index 000000000..9d94d124e --- /dev/null +++ b/plugin/gdiplus/gvloadimage_gdiplus.cpp @@ -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 +#include +#include + +#include "gvplugin_loadimage.h" +#include "gvplugin_gdiplus.h" + +#include +#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} +}; diff --git a/plugin/gdiplus/gvplugin_gdiplus.cpp b/plugin/gdiplus/gvplugin_gdiplus.cpp index 6a2c0fcb6..0301de1b7 100755 --- a/plugin/gdiplus/gvplugin_gdiplus.cpp +++ b/plugin/gdiplus/gvplugin_gdiplus.cpp @@ -18,13 +18,13 @@ 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 index 000000000..6ddc0fc9b --- /dev/null +++ b/plugin/gdiplus/gvplugin_gdiplus.h @@ -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 diff --git a/plugin/gdiplus/gvrender_gdiplus.cpp b/plugin/gdiplus/gvrender_gdiplus.cpp index ddb84abb9..26b40380b 100755 --- a/plugin/gdiplus/gvrender_gdiplus.cpp +++ b/plugin/gdiplus/gvrender_gdiplus.cpp @@ -24,6 +24,7 @@ #include "gvplugin_device.h" #include "gvplugin_render.h" #include "graph.h" +#include "gvplugin_gdiplus.h" #include #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 find_font(char *fontname, double fontsize) (LPARAM)&found_font, 0) == 0) { found_font.lfHeight = (LONG)-fontsize; + found_font.lfWidth = 0; return auto_ptr(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 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 wide_str(wide_count); + MultiByteToWideChar(CP_UTF8, 0, para->str, -1, &wide_str.front(), wide_count); + /* adjust text position */ switch (para->just) { case 'r': -- 2.40.0