Monthly Archives: January 2014

Using IE to Save SVGs as Bitmaps to Wherever

You know, something that'll make you appreciate .NET really fast is programming COM by hand in C++. I suspect what follows can be converted into C# but I didn't go that route because while working to get to this point, I didn't want to worry about doing COM Interop in .NET on top of the problem I was trying to solve. Therefore, I ended up in C++ and COM.

For the SVG to bitmap problem I was originally trying to solve, I started out by going using the canvg JavaScript library. Definitely a recommended way to go if you're trying to solve this problem and the output works for you. Personally, the Graphic Designer side of me looked at my nice pretty anti-aliased browser handled SVG renderings, then at my jaggy HTML Canvas rendering and went, "Aw." I also didn't like being limited because SVG has those spiffy diffy filters and I wanted to be able to use them too. So I figured I was going to have to do the rendering server side.

On writing that last, now seems like a good time to remind folks, sanitize/be mindful of your inputs! 🙂

I knew I could get another library to handle the rendering but I didn't see why I needed to. I have a perfectly good SVG renderer on my computer after all. It's just embedded in Internet Explorer and much of IE is COM. That means I can get at its objects too, if one knows how.

I'm going to assume that most of the people who read this are more comfortable with C#. I'm also going to assume that because you've made it this far after I've talked about C++ and COM, odds are you're my kind of developer! 🙂

Finally, before the good stuff a note that as is my motif I'm not going to be giving ya'll a final working solution here but I will give you the knowledge to make it work for you. I'm a teach a developer to code kind of gal after all!

I like to start with the beginning so, here's your includes because it drives me batty when people leave those out of their code walk throughs!

#include <windows.h>
#include <mshtml.h>
#include <gdiplus.h>
#include <functional> 
#include <iostream>

#import <mshtml.tlb>

#pragma comment( lib, "gdiplus" )

const int HIMETRIC_INCH = 2540;

using namespace Gdiplus;
using namespace std;

I'll assume knowledge of the basic #include, the #import directive is going to pull in type description information for the COM interfaces I'll be using. The #pragma comment() is a way to add a reference to a type library in code instead of adding the reference to the project. Great way to avoid, "Gagh! I setup my libraries for Debug/Release mode only!" Finally, HIMETRIC_INCH is a constant needed to get the output to render at the right size. We'll see that again later.

From here we're clear to look at main:

int main(int argc, char* argv[])
{
 GdiplusStartupInput gdiplusStartupInput;
 ULONG_PTR gdiplusToken;
 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
 CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
 ConvertToImage();
 CoUninitialize();
 GdiplusShutdown(gdiplusToken);
 return 0;
}

First thing to note is the GdiplusStartup call. That's getting our application prepared to do the final rendering using GDI+. You wanna use GDI+ in your application, you gotta do this. As cleanup, when you're done you need to call GdiplusShutdown as shown above.

Next is the actual initialization of COM with CoInitalizeEx. This is responsible for setting up COM for use by the calling thread. I'm also calling it with COINIT_APARTMENTTHREADED so I don't have to worry about concurrency.

Ok, now on to ConvertToImage:

void ConvertToImage()
{ 
  HRESULT hr = E_FAIL; 
  int width = 120, height = 120; 
  MSHTML::IHTMLDocument2Ptr pDoc = nullptr; 
  hr = CoCreateInstance(CLSID_HTMLDocument, nullptr, CLSCTX_INPROC_SERVER, 
                        IID_IHTMLDocument2, (void**)&pDoc); 
  if(SUCCEEDED(hr)) 
   hr = SetDocumentViewPort(pDoc, width, height); 

 if(SUCCEEDED(hr)) 
  hr = LoadHTML(pDoc); 

 if(SUCCEEDED(hr))
  RenderImage(pDoc, width, height); 
}

I have some constants here (width, height) that just happen to match my SVG output. Bad, icky, terrible thing to do but I'm here to illustrate as simply as possible.

The most interesting thing happening here is the call to CoCreateInstance. Here I'm creating an HTML Document and note, I am bypassing IE entirely. Also note the CLSCTX_INPROC_SERVER parameter. That's telling COM To create the document in the space of the running process. This is one of the very extremely important things for our goal here.

The way that I'm checking if my HRESULTS succeed with SUCCEEDED(hr) is a result of my absolute abhorrence to using goto statements and desire to avoid arrow code. Also, I'm using smart COM pointers here. Usually I'd have to be aware of:

  • IUnknown->AddRef()
  • IUnknown->Release()

In order to avoid a memory leak. If you don't know what I'm talking about here, that's okay for the moment just if you find yourself working with raw COM you will need to know about it, else you're going to have a bad time. By that I mean you'll have a memory leak.

Next, we have to set the size of our document which SetDocumentViewPort handles.

HRESULT SetDocumentViewPort(MSHTML::IHTMLDocument2Ptr pDoc, int width, int height)
{ 
 auto hdc = GetDC(NULL); 
 auto x = MulDiv(width, HIMETRIC_INCH, GetDeviceCaps(hdc, LOGPIXELSX)); 
 auto y = MulDiv(height, HIMETRIC_INCH, GetDeviceCaps(hdc, LOGPIXELSY)); 
 ReleaseDC(NULL, hdc); IOleObjectPtr pOle = nullptr;
 HRESULT hr = pDoc->QueryInterface(IID_IOleObject, (void**)&pOle);
 if(SUCCEEDED(hr))
 {
  SIZEL size = {x , y}; 
  return pOle->SetExtent(DVASPECT_CONTENT, &size); 
 } 
 return hr;
}

In completing the task at hand, this was one of the trickiest things to figure out starting with what interface to use and setting it to size in what units? The MulDiv lines are handing the unit conversion from pixels to "device units". Then, via a IOleObject, SetExtent is called which tells the object, in our case our HTMLDocument its size.

Next for you JavaScript developers we're actually going to get into a little familiar territory.

HRESULT LoadHTML(MSHTML::IHTMLDocument2Ptr pDoc)
{
 SAFEARRAY* psa = SafeArrayCreateVector(VT_VARIANT, 0, 1); 
 VARIANT *param;
 _bstr_t bsData("<!DOCTYPE html><html>...<meta http-equiv=\"X-UA-Compatible\" 
                                        content=\"IE=11\" />...svg...</html>"); 
 HRESULT hr = SafeArrayAccessData(psa, (LPVOID*)&param); 
 if(SUCCEEDED(hr))
 {
  param->vt = VT_BSTR;
  param->bstrVal = bsData; 
  hr = pDoc->write(psa); 
  if(SUCCEEDED(hr)) 
   hr = pDoc->close(); 
  SafeArrayDestroy(psa); 
 }
 if(SUCCEEDED(hr))
 {
  MSHTML::IHTMLDocument6Ptr pDoc6 = nullptr; 
  if(SUCCEEDED(hr)) 
   hr = pDoc->QueryInterface(IID_IHTMLDocument6, (void**)&pDoc6); 

 if(SUCCEEDED(hr)) 
 {
  _variant_t mode = pDoc6->documentMode; 
  cout << mode.fltVal << endl; 
  MessagePump([&]() -> bool {return strcmp(pDoc->readyState, "complete") != 0;}); 
  cout << pDoc->readyState << endl; 
  } 
 } 
 return hr; 
}

Need to do a little manual memory management here around the SafeArrays. But another one of those very extremely important things to note is the X-UA-Compatible meta tag. This'll be familiar and I've got mine set to IE=11 for no good reason beyond it's not IE 7. It turns out, when you embed IE objects like this it will default to IE 7 for rendering. Therefore, to be able get the SVG rendering goodness we're after we need to tell IE to please be a current version of the browser.

The body tag of the HTML is elided but it'll also necessary to set your CSS margins and padding on your body element to be 0px.

Next see those calls to write() and close()? Those are in fact the same write() and close() you know of from JavaScript! They end up being a handy way to create the document we want to render.

From there I've got a check on the current documentMode to verify we're not using IE 7. The documentMode property however, is not implemented on the IHTMLDocument2Ptr I've got currently so I needed to get an IHTMLDocument6Ptr. From there I pump Windows messages to get the document into the complete state. Sleeping here will get you nowhere in the COM Context that we're using.

On to the home stretch.

void RenderImage(MSHTML::IHTMLDocument2Ptr pDoc, int width, int height)
{
 IViewObjectPtr pView = nullptr; 
 if(SUCCEEDED(pDoc->QueryInterface(IID_IViewObject, (void**)&pView))) 
 { 
  auto bmp = new Bitmap(width, height); 
  auto g = Graphics::FromImage(bmp); 
  auto graphicsHDC = g->GetHDC(); 
  RECT rcClient = {0, 0, width, height}; 
  HRESULT hr = pView->Draw(DVASPECT_CONTENT, -1, NULL, NULL, NULL, graphicsHDC, 
                            reinterpret_cast<LPRECTL>(&rcClient), NULL, NULL, 0); 
  g->ReleaseHDC(graphicsHDC); 
  if(SUCCEEDED(hr)) 
  { 
   CLSID pngClsid; 
   GetEncoderClsid(L"image/png", &pngClsid); 
   bmp->Save(L"circle.png", &pngClsid, nullptr); 
  } 
  delete g; 
  delete bmp; 
 }
}

And we've got our image! What this does is gets an IViewObject which handles rendering to a Device Context Handle, in this case our GDI+ graphics object context. Note, here is why we told COM we wanted to create objects in the current processes' memory space too. Had we not done that, we wouldn't have an image coming. But we did and do so we'll render out with the Save() call.

We could actually render out a whole lot more than just SVG here, I'm talking full webpages with no changes to the code. This has also been only one demonstration of what you can do with IE automation. I'm thinking of revisiting another soon. But for now, a demo project for ya is available here. Enjoy!

Making C# Curry

A colleague of mine told me about currying sometime ago and I've been intrigued by the idea ever since. After playing around a little bit with F# and coming to understand the concept better, I thought I'd take a crack at making it work in C# because it seemed like a fun technical challenge to take on.

To begin, currying is taking a function with multiple arguments like:

string Foo(string str, object obj, int num)

And transforming it so the function call be called as a chain of function where the single parameter to that function correlates to a parameter in the original function call.

Foo(str)(obj)(num)

Currying is apparently a common thing in functional programming languages, like F# is.

So I got to thinking that this is interesting, but I wanted to be able to use the concept on an arbitrary function in C#. I didn't want to create a bunch of Func<> templates by hand either. I just wanted it to work with any method that takes multiple parameters.

Now, I've chosen to start with focus here and so I didn't bother with instance methods yet. Not going to be hard to add, I just wanted as clean a path to solving the problem at hand: the transformation itself.

First, I started to think about the individual method signatures. In the case of Foo, they would be:

str = Func<String, Func<Object, Func<Int32, String>>>
obj = Func<Object, Func<Int32, String>>
num = Func<Int32, String>

I think you can see why I didn't want to get bogged down in Func<>s 🙂

What I needed to do then, was generate these types, define a way to capture the arguments passed in by the caller, and generate a function. The class I've come up with thus far to do that is as follows:

public static class Curry
{
   //Makes the return types for Func<,[THIS ONE!!!]>
   private static Type[] ReturnTypes(Type returnType, 
                                     ParameterInfo[] parameterInfo)
   {
       var result = new Stack<Type>();
       result.Push(returnType);
       foreach (var param in parameterInfo.Skip(1).Reverse())
           result.Push(typeof(Func<,>).MakeGenericType(param.ParameterType, 
                            result.Peek()));

       return result.ToArray();
   }

   private static LambdaExpression Make(MethodInfo methodInfo)
   {
       var parameters = methodInfo.GetParameters();
       //Prepare the pieces for the Func<>s
       var returnTypes = ReturnTypes(methodInfo.ReturnType, parameters);
       var expressions = new ParameterExpression[parameters.Length];

       //Create the expression parameters str, obj, num 
       for (int i = 0; i < expressions.Length; i++)
           expressions[i] = Expression.Parameter(parameters[i].ParameterType, 
                                                 parameters[i].Name);

       //Create the call Program.Foo(str, obj, num)
       Expression lastOperation = Expression.Call(methodInfo, expressions);
       //Build Curried Method Call, note I'm building back from 
       //the method invocation.
       //str => obj => num => Program.Foo(str, obj, num)
       for (int i = parameters.Length - 1; i >= 0; i--)
       {
           var genericType = typeof(Func<,>)
                            .MakeGenericType(parameters[i].ParameterType, 
                                             returnTypes[i]);
           lastOperation = Expression.Lambda(genericType, 
                                             lastOperation, 
                                             expressions[i]);
       }

       return (LambdaExpression)lastOperation;
   }
}

It takes a MethodInfo object so the user can choose whatever (currently static) method they want to use. Will need to be static and public right now. So what's happening here is Make() gets all the parameters from the MethodInfo passed in then creates the Func<>s in the way discussed above. In addition, it creates the parameter name expressions that will allow the final Lambda to capture and use the parameter values the user passes in. Note, the parameter names equal the supplied MethodInfo's for clarity. Then finally, starting from the Method call, it builds out the curried method structure before returning a lambda.

The first way that I came up to use this with was via a dynamic method call as such.

public static dynamic Dynamic(MethodInfo methodInfo)
{
     return Make(methodInfo).Compile();
}

Where the method is defined in my Curry static class and which I was then able to consume in my main program like so.

public class Program
{
   public static string Foo(string str, object obj, int num)
   {
       return string.Concat(str, obj, num);
   } 

   static void Main(string[] args)
   {
       var methodInfo = typeof(Program).GetMethod("Foo", BindingFlags.Static | 
                                                         BindingFlags.Public);
       dynamic fn = Curry.Dynamic(methodInfo);

       //Call made in pretty much the same way.
       //Prints string[System.Object]42
       var result = fn("string")(new object())(42);
       Console.WriteLine(result);

       //Reuse parameters
       //prints Hello, Worldx1
       //prints Hello, Worldx2
       //...
       //prints Hello, Worldx10
       var partial = fn("Hello, ")("World x");
       for (int i = 1; i <= 10; i++)
           Console.WriteLine(partial(i));

       Console.ReadKey();
    }
}

Which achieved my goals, but I'm not a fan of dynamic. I'm in a strongly typed language here so I'd like to take advantage of that. The best solution I've come up with to achieve that goal would be to build some kind of utility that integrates into Visual Studio to build the Curried Calls I want. Building the plugin is outside the scope of this document, but, I can render the C#:

public static string CSharp(MethodInfo methodInfo, string name)
{
    var lambda = Make(methodInfo);
    var builder = new StringBuilder();
    builder.AppendFormat("public static class {0}\r\n", name);
    builder.Append("{\r\n");
    //PrettyPrint is an extension method to render the type in C#
    builder.AppendFormat("\tpublic static {0} Exec()\r\n", 
                          lambda.Type.PrettyPrint());
    builder.Append("\t{\r\n");
    //Actually, the lamda.ToString() needs to be fixed in order to deal with
    //namespaces properly but I left that out as it's not germane to the 
    //theory I'm trying to work with.
    builder.AppendFormat("\t\treturn {0};\r\n", lambda.ToString());
    builder.Append("\t}\r\n");
    builder.Append("}\r\n");

    return builder.ToString();
}

Which I put in my Curry static class and will generate a static class like this for me...

public static class FooTarget
{
   public static Func<String, Func<Object, Func<Int32, String>>> Exec()
   {
       return str => obj => num => Program.Foo(str, obj, num);
   }
}

...that I can use exactly the same way as the dynamic calls above only now with strongly typed goodness which means intellisense.

I've gotten the ball rolling here on what I think is a pretty good start to enable currying in C#.

You can get a demo project here.

The Axiom is Wrong

Every once and a while I see people assert that being trans is a "mistake". Being trans isn't a mistake, it's just another way to be. So when someone takes as an axiom that being trans is somehow a "mistake", let me assure you, they are mistaken.