views:

57

answers:

2

WPF 4.0 notoriously fixed the blurry text issue. Setting TextOptions.TextFormattingMode="Display" uses pixel hints to line up characters, which works really well to improve clarity.

However, it does not work while the program is running as a Windows service in session 0; the text goes back to "Ideal" rendering, which at small sizes is completely unreadable. Below is a comparison of the two renderings.

Not running as a service:

Good text

Running as a service:

Good text

Rendering code:

//rtb is a RenderTargetBitmap
//c is a FormatConvertedBitmap with rtb as it's source
while (displayRunning) {
    if (lcd != null) {
        Dispatcher.Invoke(new ThreadStart(delegate() {

            if (dv == null) {
                dv = new DrawingVisual();
                using (DrawingContext dc = dv.RenderOpen()) {
                    dc.DrawRectangle(Brushes.White, new Pen(), new Rect(0, 0, 256, 64));
                    dc.Close();
                }
            }

            rtb.Render(dv);
            rtb.Render((Visual)Content);

            //bitmap output just for testing
            PngBitmapEncoder e = new PngBitmapEncoder();
            e.Frames.Add(BitmapFrame.Create(c));
            using (FileStream f = File.Open("C:\\test.png", FileMode.Create))
                e.Save(f);

            WriteableBitmap bitmapdata = new WriteableBitmap(c);
            srcdata = new byte[bitmapdata.BackBufferStride * bitmapdata.PixelHeight];
            System.Runtime.InteropServices.Marshal.Copy(bitmapdata.BackBuffer, srcdata, 0, srcdata.Length);

        }));
        try {
            framesender.Send(new PicoLCDFrame(srcdata, lcd.OutputReportLength), lcd);
        } catch (NullReferenceException) { } // device was unplugged
    }
    Thread.Sleep(33);
}

I realize there are no screen pixels for hints when rendering the fonts as a service, but shouldn't it get the pixel hints from the bitmap it is rendering to? Is there anything I can do about this?

EDIT: Apparently, it IS using pixel hints, but it is anti-aliasing for some reason. Below is the rendered bitmap before it is downsampled to 1 bits/pxel.

Bad text again

I do have TextOptions.TextRenderingMode="Aliased" set and it seems that WPF is ignoring that when running as a service? It needs to be on to look good when downsampled. How can I force it?

EDIT2: It may have something to do with WPF rendering in Tier 0 (software mode) when running as a service and Tier 2 (hardware) when not.

EDIT3: On Windows XP, as a service, it renders like this:

Good, kinda

Notice the margin difference, the font size difference, and an otherwise perfect rendering. WTF?

A: 

RenderTargetBitmap always renders in software. Not sure if that is the cause...or a bug, but in any case the result is that RTB does not seem to honor the text options.

What if you create your RTB at twice the resolution, then scale the image back down to the visuals native size. A poor man's anti-aliasing.

Jeremiah Morrill
RenderTargetBitmap in .NET 4 will render in hardware if available. And I don't want anti-aliasing; the image needs to be downsampled to 1 bit/pixel and will look bad if there are any grey tones.
Nick Whaley
RTB does not render in hardware...ever. Not even in 4.0. Check Brendan Clark's answer here: http://social.msdn.microsoft.com/Forums/en/wpfprerelease/thread/e2ebf264-e087-4bfe-a69b-24c884675c80
Jeremiah Morrill
@Jeremiah Morrill, thank you, I was wrong about that. But I do not see why RenderTargetBitmap.Render will render differently in software mode vs hardware mode.
Nick Whaley
A: 

UserInterface code in windows service is not a good idea its an unsupported scenario. The same limitation was there with GDI+ (System.Drawing.*) and same limitation applies to WPF also.

Signcodeindie
Have you also tried looking into Windows API CodePack? It might have something that can help you.http://code.msdn.microsoft.com/WindowsAPICodePack
Signcodeindie