Pixelated Text When Using ObjectListView Custom Renderer

310 views Asked by At

I found an example online of how to create a business card listview item using the ObjectListView. It demonstrates using a custom renderer to manually draw each Tile within the control.

The sample involves creating buffered graphics and manually drawing each item. I have this working, however, I am finding that all text I draw on the tile is looking pixelated (no matter what settings I use), especially if I draw small text. For example, using a default system font on a normal form looks fine, but in my renderer it looks jagered.

The code looks like this:

Imports BrightIdeasSoftware
Imports System.Drawing.Drawing2D
Imports System.IO

Public Class StoreListRenderer
    Inherits AbstractRenderer
    Public Overrides Function RenderItem(e As DrawListViewItemEventArgs, g As Graphics, itemBounds As Rectangle, rowObject As Object) As Boolean
        ' If we're in any other view than Tile, return false to say that we haven't done
        ' the rendereing and the default process should do it's stuff
        Dim olv As ObjectListView = TryCast(e.Item.ListView, ObjectListView)
        If olv Is Nothing OrElse olv.View <> View.Tile Then
            Return False
        End If

        ' Use buffered graphics to kill flickers
        Dim buffered As BufferedGraphics = BufferedGraphicsManager.Current.Allocate(g, itemBounds)
        g = buffered.Graphics
        g.Clear(olv.BackColor)
        g.SmoothingMode = ObjectListView.SmoothingMode
        g.TextRenderingHint = ObjectListView.TextRenderingHint

        If e.Item.Selected Then
            Me.BorderPen = Pens.White
            Me.HeaderBackBrush = New SolidBrush(olv.HighlightBackgroundColorOrDefault)
        Else
            Me.BorderPen = New Pen(Color.FromArgb(&H33, &H33, &H33))
            Me.HeaderBackBrush = New SolidBrush(Color.FromArgb(&H33, &H33, &H33))
        End If

        DrawStoreCard(g, itemBounds, rowObject, olv, DirectCast(e.Item, OLVListItem))

        ' Finally render the buffered graphics
        buffered.Render()
        buffered.Dispose()

        ' Return true to say that we've handled the drawing
        Return True
    End Function

    Friend BorderPen As New Pen(Color.FromArgb(&H33, &H33, &H33))
    Friend TextBrush As Brush = New SolidBrush(Color.FromArgb(&H22, &H22, &H22))
    Friend HeaderTextBrush As Brush = Brushes.AliceBlue
    Friend HeaderBackBrush As Brush = New SolidBrush(Color.FromArgb(&H33, &H33, &H33))
    Friend BackBrush As Brush = Brushes.LemonChiffon
    Friend BackgroundBrush As Brush = New SolidBrush(Color.FromArgb(38, 38, 38))

    Public Sub DrawStoreCard(g As Graphics, itemBounds As Rectangle, rowObject As Object, olv As ObjectListView, item As OLVListItem)
        Try
            Dim _store As StoreObject = TryCast(rowObject, StoreObject)

            ' Allow a border around the card
            itemBounds.Inflate(-5, -5)
            g.FillRectangle(BackgroundBrush, itemBounds)

            Dim ColouredPanelRect As Rectangle = New Rectangle(itemBounds.Left + 7, itemBounds.Top + 7, 70, 70)
            g.FillRectangle(Brushes.IndianRed, ColouredPanelRect)

            Dim fmt As New StringFormat()
            fmt.Alignment = StringAlignment.Center
            fmt.LineAlignment = StringAlignment.Center

            For i As Integer = 0 To olv.Columns.Count - 1
                Dim column As OLVColumn = olv.GetColumn(i)
                If column.IsTileViewColumn Then

                    'Draw Store Number
                    Using font As New Font(fontMgr("Mentone Lig"), 36, FontStyle.Regular, GraphicsUnit.Pixel)
                        g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit
                        g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
                        g.DrawString(_store.StoreID, font, BackgroundBrush, ColouredPanelRect, fmt)
                    End Using

                    'Draw Store Name
                    Using string_format As New StringFormat()
                        string_format.Alignment = StringAlignment.Center
                        string_format.LineAlignment = StringAlignment.Near
                        g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
                        g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit
                        g.DrawString(_store.StoreName.ToUpper, New Font("Segoe UI", 9, FontStyle.Regular), Brushes.White, itemBounds, string_format)
                    End Using

...

I have tried playing around AntiAlias and ClearType but both have the same affect.

UPDATE

Here are my results below with using the same font at the same size:

enter image description here

The text at the top represents a normal label placed on a form. The text at the bottom is text drawn on to a listview item (in Tile mode) using the code above. You can easily identify the difference and see that it is not as smooth. Also the larger I make the text the more unsmooth it gets. I have tried playing around with all the settings and currently have it set to:

g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
g.PixelOffsetMode = PixelOffsetMode.HighQuality

Thanks

1

There are 1 answers

0
Riples On BEST ANSWER

Okay, I ended up working this out by going through the example again. The problem was that I was dropping the scaling element from my code which seemed to be causing the pixilation of the text.

By adding the following code back in, it has corrected the smoothness of the text:

Dim size As SizeF = g.MeasureString(txt, font, CInt(itemBounds.Width), fmt)
g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit

So my overall code looks like this:

Using font As New Font("Segoe UI", 9, FontStyle.Regular)
     ' Measure the height of the title
     txt = column.GetStringValue(rowObject)
     Dim size As SizeF = g.MeasureString(txt, font, CInt(itemBounds.Width), fmt)
     g.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
     g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
     g.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
     g.PixelOffsetMode = PixelOffsetMode.HighQuality
     g.DrawString(txt, font, Brushes.LightGray, itemBounds, fmt)
End Using