ailon's DevBlog: Development related stuff in my life

Converting HTML font sizes to pixels

3/7/2008 11:40:12 AM

When you create a custom ASP.NET control most of the times you inherit it from WebControl class or one of it's derivatives. Among other properties WebControl has a Font property of FontInfo type which in turn has a Size property of FontUnit type. Users can set the yourControl.Font.Size to any HTML/CSS compatible value from 12pt to 1.2em to x-large.

This is all fine while your control outputs plain HTML. But at this moment I'm working on a controls which use Flash controls as their output and Flash knows nothing about font sizes in points let alone x-small & co. (at least I was told so by my flash developer colleague). So what I needed was a way to convert all the reasonable FontUnit values to some more or less equivalent pixel sizes. So after some experiments I came up with this FontSizeConverter class with only one static method to convert FontUnit to pixels.

Keep in mind that this is only a raw approximation and doesn't pretend to be completely correct and universal solution. Em and Percentage values use 16px as base.

public class FontSizeConverter
    public static int ToPixels(FontUnit unitSize)
        int result = 16;

        if (unitSize.Type != FontSize.NotSet && unitSize.Type != FontSize.AsUnit)
            // size in x-small, etc
            switch (unitSize.Type)
                case FontSize.XXSmall:
                    result = 9;
                case FontSize.XSmall:
                    result = 10;
                case FontSize.Smaller:
                case FontSize.Small:
                    result = 13;
                case FontSize.Medium:
                    result = 16;
                case FontSize.Large:
                case FontSize.Larger:
                    result = 18;
                case FontSize.XLarge:
                    result = 24;
                case FontSize.XXLarge:
                    result = 32;
                    result = 16;
        else if (unitSize.Type == FontSize.AsUnit)
            switch (unitSize.Unit.Type)
                case UnitType.Pixel:
                    result = (int)Math.Round(unitSize.Unit.Value);
                case UnitType.Point:
                    result = (int)Math.Round(unitSize.Unit.Value*1.33);
                case UnitType.Em:
                    result = (int)Math.Round(unitSize.Unit.Value * 16);
                case UnitType.Percentage:
                    result = (int)Math.Round(unitSize.Unit.Value * 16 / 100);
                    // other types are not supported. just return the medium
                    result = 16;

        return result;
kick it on

Tags: , ,

Internet Explorer, HTTPS/SSL and ASPX pretending to be XLS

2/22/2008 5:51:24 PM

I've developed a system for a client where among other things he was able to export a certain product list as CSV file to import it into Excel/OpenOffice etc. I did it the usual way: created an ASPX page which was outputting data in CSV and pretending to be XLS with code like this:

Response.ContentType = "application/";
Response.AddHeader("Content-Disposition", "filename=\"catalog.xls\"");

It all worked fine but then we ran into the Opera's dumb-caching issue, so I added

<%@ OutputCache Location="None" %>

to all sensitive pages. "Excel" export still worked fine. Then we moved the app under https and suddenly export stopped working in IE with the message box claiming

Internet Explorer cannot download file from server.
Internet Explorer was not able to open this Internet site. The requested site is either unavailable or cannot be found. Please try again later.

In Firefox and Opera it still worked fine.

I found this article in Microsoft's KB explaining that caching should be allowed in order for IE to save the file to temporary folder and then open it from there (hence the file not found error). This solved the problem. Hope this helps someone or myself in the future.

kick it on

Tags: , ,

The DotNetKicks Effect - Enjoy While it Lasts

2/14/2008 12:24:59 PM

DotNetKicks is a great source to stay on track with latest .NET related developments, tutorials, tips, etc. It is also a great way to promote your .NET related articles or products. Here's a "kicked" article by Ryan Lanciaux about how cool it is for a small blog to get "kicked".

This is all true but if we can learn from digg (of which DotNetKicks is a clone) this is not going to last forever. To understand why let's analyze the only 2 ways how your article can get kicked/digged/whatever:

  1. Someone sees your article in the "upcoming stories" section of DotNetKicks and kicks it
  2. Someone reads the article on your site and presses the "kick it" button (if you have one)

Now those of you who read the "upcoming stories" section of DotNetKicks please stand up. Anyone? I don't. And judging from the quantity of hits I got to my articles submitted to DotNetKicks but not kicked to the front page I can assume that not more than 50 people do. Lets not fight about this number cause the actual number is not that important. What's important that only a small percentage of DotNetKicks readers read the "upcoming stories" too.

So this leaves us with only one actual way of getting kicked -- through the link on your own site. While the threshold of becoming "popular" on DotNetKicks is low (6 kicks?) it's ok. You can expect that out of 50 visitors to your small site 10% would bother to kick your article. But as DNK becomes more popular this bar would go higher to filter not that interesting stories which would inevitably grow in quantity the more popular the DNK becomes. So let's say the bar is raised to 30 and (if we assume that 10% of your visitors would kick your article) you'll need to have something like 300 readers already to get kicked to the front page.

You can see this effect on digg. For example to get your story about some gadget digged to "popularity" you have to be Engadget or Gizmodo or at least your article should be linked from some popular site(s) (or many less popular ones) before being digged. Here's a good article on the same subject by DownloadSquad.

So let's enjoy the great DotNetKicks while we can and while noise ratio there is low. It's not going to last forever. At least I don't have that much faith in humanity.

kick it on

Update: read the follow-up: More on "The DotNetKicks Effect"

Tags: , ,

SPAW Editor .NET Edition Released!

1/3/2008 4:18:08 PM

We have released a stable version of .NET Edition of our web based WYSIWYG HTML/rich text editor control - SPAW Editor v.2.

Download it from here.

Tags: ,

First .NET App

12/13/2007 10:27:05 AM

Windows Live Writer is the first full-scale consumer product to ship out of Microsoft's camp built on the .NET Framework.

This is fun. Never thought about it.

Tags: ,

Opera, caching and ASP.NET

12/4/2007 4:45:00 PM

How do you create a fastest browser in the whole world? You just CACHE everything in a dumb way!

I just ran into a problem when a client reported anomalies with shopping cart functionality in a project I'm working on. Apparently when you add a product to a cart using Opera and then just navigate to a shopping cart page you see the (client) cached version of that page. If you refresh you see the actual version, then you remove a product from the cart using POST and you still see the actual version, then you just navigate to cart.aspx page and you see the cached version again.

I had no time to investigate the deep causes of this behavior but it looks like Opera by default is pulling from cache any page requested with GET and having no question mark in the URL if it was already requested less than 5 minutes ago.

Since I had no time to research the roots of this behavior I just solved (hopefully) the issue by adding

<%@ OutputCache Location="None" %>

to every sensitive aspx page.

Maybe I should do this all the time just to stay safe but neither IE nor Firefox were behaving in this crazy manner without this. So I'm guessing it's just because they are not after the "fastest browser on the market" crown and can justify creating a smart caching system sacrificing "speed".

So, I guess now I can declare that I hate all of the 3 major browsers (haven't spent enough time with Safari to start hating it). I hate MSIE for lack of support for standards and being slow in adding new features (thankfully there's IE7Pro plugin). I started hating Firefox while developing Gecko support in SPAW 1.x and running into some Gecko bugs that were known for more than 3 years and publicly ignored and for overall stubbornness of Mozilla developers and... I just don't like how it "feels" as a user. I discovered that you can crash Opera with JavaScript while working on Opera support for SPAW 2.x but they've fixed it by now which is nice, but now this...

Update: No caching results in back button not working... hmm... I hate these issues...

Tags: ,

Effectively Disabling Themes in ASP.NET Web Forms

11/29/2007 11:19:32 AM

Apparently, if you have Theme set across your web application, it's not enough to just set EnableTheming="false" in the @Page directive of your ASPX file to disable theming. You have to set Theme="" StyleSheetTheme="" too. Otherwise, if your aspx pretends it's something else (image, javascript, etc.) and has no <head> element, you'll get a nice exception like:

System.InvalidOperationException: Using themed css files requires a header control on the page. (e.g. <head runat="server" />).



11/26/2007 8:24:34 PM

We've released SPAW Editor .NET Edition version Release Candidate.

Tags: ,

Using Symlinks to Ease Development with Visual Studio Express

11/21/2007 8:01:16 PM

As you probably know, since Visual Web Developer Express and Visual C# Express (or VB for that matter) are separate products and you can't create DLLs in VWD or build web sites in VCS it is painful to develop ASP .NET controls using the Express editions of Visual Studio.

There are several ways to workaround this limitation. Personally I prefer the one where you develop your control in App_Code directory of a test web site in VWD and then when you are ready you copy the .cs files to a project in Visual C# Express and build your DLL(s) from there.


The problem with this approach is that you have 2 copies of your files and as it often happens sometimes you edit the files in one place then in the other dir and you have a mess.

Fortunately this problem can be solved using symbolic links - feature well known to *nix guys and now available in Windows Vista using mklink. As far as I understand you can get the same effect using linkd command in Windows Resource Kit for Windows 2000 and newer but mklink comes with Vista out of the box.

So, what I do is make a symbolic link in my Visual C# project directory which points to a subdirectory in my Visual Web Developer web site:


The syntax for mklink in our case is this:

mklink /D new_dir_path original_dir_path

Now we just need to include our newly created "fake" directory into Visual C# Express project and we are all set


This approach can be used in many different scenarios. Currently I work on a couple of related web sites with a colleague. All of the sites originate from one "base" web site. The class files of this base web site are still under development (we update them from time to time). It's too early to compile them and include in our "inherited" web sites as DLLs, so we use the same technique to "include" these common files in our "child" projects.

kick it on

Tags: , , ,

?? operator in C#

11/14/2007 11:24:00 AM

As embarrassing as it sounds I somehow missed the "new" ?? operator and Nullable types (int?, etc.) in C# 2.0. It helps preserve my self-esteem a little that ScottGu thought that this was new in C# 3.0 too. :)

Tags: ,

Copyright © 2003 - 2018 Alan Mendelevich
Powered by BlogEngine.NET