Using InkEdit, InkPicture, and Enhancing the Appearance of Ink

 

Leszynski Group Inc.

July 2003

Applies to:
   Microsoft® Windows® XP Tablet PC Edition

Summary: This article discusses using ink controls for the Microsoft Windows XP Tablet PC Edition operating system. We will discuss the InkEdit and InkPicture controls, which are provided in the Tablet PC SDK. We will also cover enhancing the appearance of ink strokes within these controls. This discussion covers practical application and potential benefits.

This article is intended for developers creating ink-based applications. Code samples were created using Microsoft Visual Basic .NET and C#, and the Microsoft Tablet PC Platform SDK (Beta) Build 2149. (9 printed pages)

Contents

Introduction
Using the InkEdit control
Using the InkPicture Control to Annotate
Conclusion

Introduction

The InkEdit and InkPicture controls give developers options when creating ink-enabled applications for different user scenarios. In some cases, developers may want the control to recognize ink, and, in other cases, developers may not. The same is true for displaying image files as a background, or leaving it blank. InkEdit and InkPicture provide this flexibility.

The InkEdit and InkPicture controls provide the ability to capture ink and perform handwriting recognition. However, there is no text display area within an InkPicture control.

Using the InkEdit control

The InkEdit control is derived from the RichTextBox base class. In default the default configuration, the control captures ink, recognizes the handwriting, removes the ink, and then displays the recognized ink as text within the text box. This allows users to enter text using the pen instead of the keyboard. Recognition is fast.

Adding InkEdit to Visual Studio

To use the InkEdit control, add it to your Microsoft® Visual Studio® .NET Toolbox.

  1. Right-click on the Toolbox.
  2. Select Customize Toolbox.
  3. Select the .NET Framework Components tab.
  4. Check InkEdit and then click OK.

You can also add this control by referencing and creating it in code. However, adding it to your Toolbox is the quickest means.

Adding InkEdit to Your Form

To add an instance of the InkEdit control to your form, select the InkEdit control in your Toolbox, and then draw a rectangle region on your form.

Note   The ink region is contained within the bounds of the control. If the control is too small, the user may not have enough room in which to write and recognition may not work to its potential. We recommend that you make the control large enough for users to easily write several words inside the control boundaries.

Enabling InkEdit and Mouse Input

By default the InkEdit control will collect ink and gestures from a pen input device on a Tablet PC.

If you are developing ink-enabled applications on a desktop machine with no pen input device, you will not be able to draw ink inside of the InkEdit control. The following setting allows you to use your mouse as a pen input device inside of the InkEdit control:

me.InkEdit1.UseMouseForInput = True

You can now practice using the InkEdit control. Figure 1 illustrates the written ink.

Figure 1. Handwritten ink

Figure 2 illustrates the text displayed after the control has performed text recognition.

Figure 2. Handwritten ink after text recognition by the InkEdit control

Retaining Ink

There may be a scenario when you do not want the InkEdit control to recognize the ink and display it as text. You can set the control to shrink and organize the ink into distinctive lines on the control. This would allow the user to write a letter or capture the user's signature. However, this feature will only work on the Tablet PC edition of Windows XP.

To retain ink within the control, set the following property:

me.InkEdit1.InkInsertMode = InsertAsInk

Now you can run your sample again. Write "Hello" and notice that the ink is reduced in size and placed in-line within the InkEdit control.

Controlling Recognition

You can control the amount of delay time between the end of a stroke and the beginning of the text recognition by changing the following property, where n is a 32-bit number that indicates the number of milliseconds between the last ink stroke collected and the beginning of the recognition:

me.InkEdit1.RecoTimeout = n

The default value is 2000 (two seconds). The default value works well, but there may be some cases when you want a longer or shorter delay. For example, if you were writing a training program for elementary school children, you would slow down the delay to give the children more time to finish writing their words.

Employing Factoids

A factoid provides context for recognized ink in the context of a particular field. The Factoid property returns or sets the name of a factoid that the recognizer uses to constrain its search for the recognition results.

Typically, you would specify a factoid only if an input field is of a known type, such as a date field. Some of the supported Factoids are: PostalCode, Email, Web, Telephone, Filename. For more information about factoids and how to use them, see Using Factoids in the Tablet PC SDK Documentation. For a list of supported factoids, search for the Factoid object and for Supported Factoids in the Tablet PC SDK Documentation.

To change the Factoid on the InkEdit control, set the following property, where [Name] is the name of one of the supported Factoids:

me.InkEdit1.Factoid=[Name]

Setting the ZoomFactor

The ZoomFactor property increases or decreases the magnification of the text or ink within the control. The default value is 1.0, which makes the control contents appear at 100 percent. Larger values will cause the text or ink contained within the control to appear larger. Smaller values will make the text or ink appear smaller. You may want to increase this value for users with visual impairments who could benefit from a larger rendering of the text or ink.

You can change the following property to set the zoom value, where n is a single precision number:

me.InkEdit1.ZoomFactor = n

Saving InkEdit Contents

You can save the contents of your InkEdit control by calling the .SaveFile method. This overloaded method will enable you to save to a file or a stream. The following example saves the file to "C:\MyInk.rtf":

In C#

me.InkEdit1.SaveFile("C:\\MyInk.rtf");

In VB .NET

me.InkEdit1.SaveFile("C:\MyInk.rtf")

Opening Saved InkEdit Files

Opening an InkEdit file is accomplished by using the .LoadFile method. This overloaded method will enable you to open from a file or a stream. The following example opens a file from "C:\MyInk.rtf":

In C#

me.InkEdit1.LoadFile("C:\\MyInk.rtf");

In VB .NET

me.InkEdit1.LoadFile("C:\MyInk.rtf")

Using the InkPicture Control to Annotate

The InkPicture control is derived from the Picture base class and offers a space in which the user can annotate. This control is useful for capturing signatures, drawings, markups, or other annotation that need not be recognized as text.

This control can also contain an image onto which the user can draw, which is useful in cases where the underlying image is a scanned form. The accepted image file formats for InkPicture include: .jpg, .bmp, .png, or .gif format.

Adding InkPicture to Visual Studio

To use the InkPicture control, add it to your Visual Studio .NET Toolbox.

  1. Right-click on the Toolbox.
  2. Select Customize Toolbox.
  3. Select the .NET Framework Components tab.
  4. Check InkPicture and click OK.

Add InkPicture to Your Form

You can add an instance of the InkPicture control to your form by selecting the InkPicture control in your Toolbox. Then draw a rectangle region on your form. Again, it is important that you make the control large enough for users to easily write several words inside the control boundaries.

It is not required that you place a picture within the control. To create a region where users can draw pictures or annotate, you can leave the Image property empty.

Enabling InkPicture

By default, the InkPicture control captures and displays Ink. You do not need to set any properties to activate this control at run time.

Smoothing Ink

By default, ink that is drawn on the InkPicture control is not anti-aliased, or smoothed. This can result in jagged edges and blocky looking strokes. You can anti-alias and curve strokes in the InkPicture control. This improves the aesthetic appearance of strokes, especially on machines with low resolution.

The following code sets both anti-aliasing and curving processes:

In C#

private void InkPicture1_Stroke(object sender,
 Microsoft.Ink.InkCollectorStrokeEventArgs e)
    {
        
        //First Get a Rectangle that contains all of the 
        //points in a stroke.
        
            Rectangle Rect = e.Stroke.GetBoundingBox(Microsoft.Ink.BoundingBoxMode.PointsOnly);
            
        //Note that the rectangle is in InkSpace sizing which is 
much larger
        //than pixels. It has to be converted from InkSpace coordinates
        //to Pixels so we can invalidate the
        //pixels on the screen.

        //Get the TopLeft point
         Point pointTopLeft = new Point(Rect.Left, Rect.Top);

        //Get the BottomRight point
        Point pointBottomRight = new Point(Rect.Left, Rect.Top);
        pointBottomRight.Offset(Rect.Width, Rect.Height);

        //Now call the Renderer.InkSpaceToPixel method
        //and it will convert the TopLeft point from InkSpace into
        //Pixel measurements
        InkPicture1.Renderer.InkSpaceToPixel(InkPicture1.CreateGraphics(),ref 
pointTopLeft);

        //Do the same for the BottomRight point
        InkPicture1.Renderer.InkSpaceToPixel(InkPicture1.CreateGraphics(),ref 
pointBottomRight);

        //Now we can create a new Rectangle that encompasses
        //the Ink in Pixel space, instead of InkSpace.
         Rectangle ConvertedRect = new Rectangle(pointTopLeft.X, 
pointTopLeft.Y, pointBottomRight.X - pointTopLeft.X, pointBottomRight.Y 
- pointTopLeft.Y);

        //In order for the Ink to smooth out and be 
        //anti-alised, you must turn those options on
        //I usually set these properties in the Form_Load event.
        InkPicture1.DefaultDrawingAttributes.AntiAliased = true;
        InkPicture1.DefaultDrawingAttributes.FitToCurve = true;

        //This method will invalidate the Rectangular region
        //on the screen, forcing the InkPicture object to
        //re-draw the ink. During redraw, it will AntiAlias and 
        //fit to curve the ink strokes.
        InkPicture1.Invalidate(ConvertedRect);

        //The next method forces the InkPicture to redraw itself
        //now.
        InkPicture1.Update();
        }

In VB .NET

    Private Sub InkPicture1_Stroke( _
            ByVal sender As Object, _
            ByVal e As Microsoft.Ink.InkCollectorStrokeEventArgs) _
            Handles InkPicture1.Stroke
        'First Get a Rectangle that contains all of the
        'points in a stroke.
        Dim Rect As Rectangle = _
          e.Stroke.GetBoundingBox(Microsoft.Ink.BoundingBoxMode.PointsOnly)

        'Note that the rectangle is in InkSpace sizing which is much 
larger
        'than pixels. It has to be converted from InkSpace coordinates
        'to Pixels so we can invalidate the
        'pixels on the screen.

        'Get the TopLeft point
        Dim pointTopLeft As New Point(Rect.Left, Rect.Top)

        'Get the BottomRight point
        Dim pointBottomRight As New Point(Rect.Left, Rect.Top)
        pointBottomRight.Offset(Rect.Width, Rect.Height)


        'Now call the Renderer.InkSpaceToPixel method
        'and it will convert the TopLeft point from InkSpace into
        'Pixel measurements
        InkPicture1.Renderer.InkSpaceToPixel(InkPicture1.CreateGraphics, 
pointTopLeft)

        'Do the same for the BottomRight point
        InkPicture1.Renderer.InkSpaceToPixel(InkPicture1.CreateGraphics, 
pointBottomRight)

        'Now we can create a new Rectangle that encompasses
        'the Ink in Pixel space, instead of InkSpace.
        Dim ConvertedRect As New Rectangle(pointTopLeft.X, 
pointTopLeft.Y, pointBottomRight.X - pointTopLeft.X, pointBottomRight.Y 
- pointTopLeft.Y)

        'In order for the Ink to smooth out and be 
        'anti-alised, you must turn those options on
        'I usually set these properties in the Form_Load event.
        InkPicture1.DefaultDrawingAttributes.AntiAliased = True
        InkPicture1.DefaultDrawingAttributes.FitToCurve = True

        'This method will invalidate the Rectangular region
        'on the screen, forcing the InkPicture object to
        're-draw the ink. During redraw, it will AntiAlias and 
        'fit to curve the ink strokes.
        InkPicture1.Invalidate(ConvertedRect)

        'The next method forces the InkPicture to redraw itself
        'now.
        InkPicture1.Update()
    End Sub

Conclusion

The InkEdit and InkPicture controls provide broad functionality when developing for different user scenarios. You can use the InkEdit for scenarios when text recognition is required, such as address text boxes, and use InkPicture for scenarios when you don't need text recognition, such as when you need to capture signatures. You can also lay images in the InkPicture control. These controls provide both flexibility and ease of use for developers and users alike.

About Leszynski Group Inc.

Leszynski Group develops line-of-business applications and retail software built around databases, XML, and ink, using Microsoft® .NET architecture. Leszynski Group was the first solution provider to develop and ship ink-based applications for the Tablet PC.