.net GraphicsPath to EPS (vector)

Sometimes when you are presented with a project you simply don’t know where to begin.  This was the case with my latest endeavor.  The core of the project, produce a vector based output of text to be able to outline and shadow it.  Once those operations are completed move the resulting data into an Adobe Illustrator compatible EPS file.  I like a good challenge and this was definitely one of them. 

Using .net to draw vector paths
The .net runtime features a vector class in the System.drawing.drawing2D  namespace called GraphicsPath.  With this class you can perform many common vector operations such as adding lines, polygons, beziers, and more.  You can also do transformations, scaling, and warping to name a few.  Another benefit is it is extremely easy to draw the resulting class to a form making it quick to see your work in action.  Point data is stored in an array and flagged by a mirror array called pathtype, using some references of what the enumeration values mean you can translate the type of each point.  Finally, one of the more useful methods is taking the vector data and moving it into a compatible format you can interface with other libraries.  Flatten() allows you to create an approximation based on the flatness input.  The result is a polygon of connected line segments.  For my uses this was perfect.

Union Boolean Operation
So I established my data container class and my search began on how exactly I was going to perform the outlining and union operations.  This proved to be the most complicated part of the project.  One requirement was the outline had to be round, not pointed this affected the type of algorithm I was looking for.  Like most programmers I hate trying to reinvent the wheel as I know all of what I was trying to do had been done many times before.  In my days of searching for graphics libraries in what started in just .net moved out to C and C++.  I had much more luck when I started looking at C and C++ open source projects.  I ran across the General Polygon Clipper Library which already has a wrapper in C#!  Perfect!  After some test using the code it works perfectly and is quick too.  GPC is written in C and output as a WIN32 dll.  With GPC in my toolbox I could now accomplish taking two graphics paths and performing a union(join) on them.  

Creating Outlines
My 2nd requirement however was that the vector needed to be able to be outlined at some distance to a rounded corner.  On the surface this may seem like a simple problem to tackle, however it isn’t.  At least not for me, this isn’t my specialty at all!  I was having trouble even finding something to look for.  Finally the keyword that landed the most useful information was polygon offset algorithm.  I came across CGAL with what looked like a nice algorithm to do offsets using a straight skeleton algorithm, however they weren’t rounded.  Luckily there is another section on their site about using Minkowski sums to offset a polygon.  After reading this page for a while and reviewing the images I decided I thought I could write this algorithm.  Long store short a few days of work I got what I was considered moderately good results, but if something like this doesn’t work perfect it is useless.  That was my issue, there were various scenarios where my code just didn’t work right, the logic was sound for simple cases, but for complex shapes (letters) it was falling short.  Since my inspiration came from the CGAL page I decided to give the library a shot.  I had serious reservations about using it because it was extreme overkill for what I was doing it seemed.  After nearly a full day (no kidding) I was able to get CGAL to compile out of visual studio.net 2008.  Yes it can be done!  It wasn’t that hard, just many steps and files that have to be downloaded and setup correctly before it will work.  Hint: make sure you have boost setup in your path correct, and get the CMAKE gui to build the project files for VS.net. 

CGAL is written in C++, basically I had not used C++ since college although at the time I was pretty comfortable for with.  It didn’t take me long to get back into the swing of writing C++ again, but I’m still a bit rusty.  My approach, peel out the pieces of CGAL I need into a WIN32 DLL and let that talk to my C# app.  I had never done any of the above before but yet another challenge I took on.  After some head banging and many searches on google I was able to expose the C++ methods (make sure you use a .def file)  and get to coding.  My work with CGAL in one word was… frustrating.  I think it is an excellent piece of work, but complicated.  I found the documentation hard to shuffle through, but complete enough you could usually figure out what was going on between one of the examples and the documentation.  My main source of confusion was the heavily templated structure which often left me wondering how various pieces of code worked.  Granted, a lot of these complaints fall on my lack of knowledge and experience with this sort of library (aka newbie!).  After much frustration and trail and error I was able to get a approximated_offset call in C++ to CGAL back out of the DLL and into C# onto the screen.  Reconstructing the CGAL general_polygon_2 structure proved very challenging since the data was in line segments and conic arcs.  .Net addArc method required input that I didn’t have from the CGAL data structure.  I have a feeling I was doing it the hard way, but in order to come up with an arc sweep, starting angle, and bounding box I had to use CGAls source circle and bounding box.  Interestingly enough CGAL already returned the intersection points to the bounding box, but I discovered there to actually be a bug in this calculation.  I plan to report it as a bug, basically the circle passes through the box to form an arc, two intersection points exist on the box, this calculation returned a point that was not bounded inside the box in some cases (the 2nd point in the line circle intersection).  At any rate it felt like I had climbed to the top of Mt. Everest at that point as I had an put together the major pieces of the project.  Little did I know that I spoke to soon. 

There is always a catch
CGAL is written very complete full of assertions, although these can be disabled they are there for a reason.  Various fonts I used kept tripping assertions, specifically my polygon was not simple.  A complex polygon is one that self intersects, I thought this is impossible since I am using a known working font.  I was mistaken, apparently there are fonts out there that infact have characters that are self intersecting polygons. This has proved to throw a major wrench in my work.  I see as I have two options either fix the polygon in some way that CGAL will perform operations on it or findanother way to offset complex polygons.  This particular issue I have not progressed on (more on that later).  I have found that the issue is not really shown in windows system fonts, moreso in fonts that you can download from free font sites.  My current plan for phase 2 of the project after completion is evaluate how hard it would be to discover intersections and split the polygon into two (or more) simple polygons, perform the offset, then join the resulting polygon.

Putting it all together
After choosing my battles and regrouping I began a search on how to get a graphicsPath object into Adobe Illustrator 8 file format.  After some searches it became clear the EPS is simply a variation on PostScript which there is a wealth of information.  After reviewing some sources on postscript I eventually found my way to the Adobe Illustrator file specification pdf.  After disecting some simple eps files out of illstrator it came to my attention that in general the file format is pretty bloated (about 400k) of built in postscript for gradient brushes, effects, andmore.  Come to find out moving a flattened GraphicsPath to eps format is pretty simple.  Things to remember are that the Y-Axis on a windows form and an EPS file are reversed so you need to translate the Y * -1.  Illustrator eps files have a few simple commands to assign color along with the type of point you are drawing.  One important thing I learned the hard way is the winding order of the polygon.  In order for polygon holes to actually show as holes you need to make sure the order of points are reversed from the outer polygon boundary.  Although it will work if they are not reversed you won’t see the path correctly in Illustrator. 

The entire project is about 80% complete and will hopefully be done this week.  Although I won’t consider this project totally done until I figure out the complex polygon outline issue, but for now I’m satisfied.  If anyone wants some code snippets I can post up some samples in the article.

FormsAuthentication.RedirectToLoginPage() does not stop page execution!

So it hit me like a ton of bricks today.  If you are utilizing asp.net’s built in forms authentication you need to read this closely!  A common chunk of code when using forms authentication is the actual authentication process and you will without a doubt be having people, spiders, bots, hackers fail at login request.  When someone fails a login the most common line of code to call is FormsAuthentication.RedirectToLoginPage(). I discovered a very nasty side effect to this line of code though.  When you call it you expect the same behavior as response.redirect().  Execution stops and immediately the page is redirected.  That is NOT the way RedirectToLoginPage() works.  The page continues to execute THEN proceeds to redirect.

This big question then why does this matter?  Say you have code on your page_load event that handles post backs or simple form data on an authenticated page when I request comes in it will continue to process all the code even if the user isn’t authenticated.  Basically giving a malicious user the ability to post commands directly into your site.  I cringe to think the number of sites that have this hole.

The Fix!
Always always use Response.end() after you RedirectToLoginPage().  This forces the execution to stop and do the redirect.

Other pitfalls of RedirectToLoginPage
Consider where you are placing your authentication code.  In my case my issues where two fold.  I was not using Response.end() like above and I also discovered I was not checking authentication soon enough.  If you have something like an admin section of a website you want totally locked away from view you want to authenticate basically before any of your actual code runs.  It is typical to utilize a master page file when desigining any section of pages and I did so.  I also included my authentication code in the master page file page_load event.  Mistake #1, any code that appears in the target files page_load that inherits from the Master page file will execute before the master page’s page_load.  Again we have a problem, if form request data is handled in the page load it is possible for a malicious user to post to the page and have it executed before being authenticated.  So how to fix??  You can always copy the authentication code into the page_load of every sub page but that defeats the purpose of a master page, instead use the page_init event in the master page file to hold your authentication code.

Moral of the story
Always be critical of your code even if it seems simple.  Unfortunately variants of this code were already in production in our case.  That great thing is this is a relatively minor fix.

Neil PUllinger’s blog offers a great explanation of the issue also.

Tagged: , , ,

Preload images in IE6

I spent a significant chunk of time today diagnosing an image preload bug with IE6.  Bug probably isn’t a fair word, but for a browser that is one big bug why not.   In short preloading worked as it should in every other browser I test against except for IE6.  IE6 would preload the image, onload event fires, I set the src for the image and it continued to download the image again! 

Doesn’t work

pic1= new Image();
pic1.src='/image.gif';
pic1.onload = function(){docimage.src='/images.gif'};

Works

pic1= new Image();
pic1.src='http://site.com/image.gif';
pic1.onload = function(){docimage.src='http://site.com/image.gif'};

*sigh*, who would’ve thought.  You MUST have the full path in the  src link or IE6 won’t preload it.  It really crossed my mind today to just bite the bullet and not support IE6 at all.  It still appears that about 25% of our visitors are IE6.  Don’t even get me started on the hoops I have to jump through because of no png support.

Tagged: , ,

Fast image pixel access with GDI+ and .net

I have yet again hit a brick wall with regards to speed in processing dynamic images server side using System.Drawing in asp.net.  As I have covered in a previous article regarding image cropping I have had difficulty in the past finding a quick way to access each individual pixel of an image.  Unfortunately my algorithm was only the result of a having to deal with a slow getpixel method.  Using what I had at the time that was the best I could come up with.

Enter ASP.net and a wealth of additional capability.  I came across a great set of articles from bobpowell.net One  great article in particular pertained to my issue exactly.  Direct memory access to pixel data using lock bits.  Here is a direct link.  It is not often that I find exactly what I need, but this was perfect.

Here is a snippet of Bob’s code, I also added some lines to elaborate where you can access the other 3 components of the image data Bob’s code did not illustrate.

     BitmapData bmd=bm.LockBits(new Rectangle(0, 0, 10, 10), System.Drawing.Imaging.ImageLockMode.ReadOnly, bm.PixelFormat);
 
      int PixelSize=4;
 
      for(int y=0; y< bmd.height; y++)
      {
 
        byte* row=(byte *)bmd.Scan0+(y*bmd.Stride);
 
        for(int x=0; x< bmd.width ; x++>
        {
 
          row[x*PixelSize]=255; //blue component
 
          row[(x*PixelSize)+1] = 255; // green component
 
          row[(x*PixelSize)+2] = 255; // red component
 
          row[(x*PixelSize)+3] = 255; // alpha component
 
        }
 
      }

So what is the advantage of this? One word SPEED. You can accomplish the same thing (reading,writing) pixel data using the managed code in system.drawing (getpixel() ), but you will find very quickly if you are doing any serious processing it is very slow.  This method is far superior assuming you know the risk (you can potentially mess with memory you aren’t supposed to).  I’m happy to report I have an efficient cropping function now that appears will speed up alot of code already in use.

Debug your javascript in style

So basically today I wanted to plug a plug-in (no pun intended) that I have really found to be invaluable to debug javascript.  The plug-in is firebug for FireFox.  In my recent dive into Dojo words cannot describe how convenient and handy firebug is.  The debug console alone is enough to make it worth while because Microsoft just doesn’t have anything like it at the moment. No need wasting my breathe explaining what all it does, click the link and see for yourself.  If you develop in javascript at all you’re missing out big time not using firebug.

Tagged: , ,