Drawing Text


The Bitmap class also provides methods to allow you to write text on the display. The character designs are expressed as font rasters, which cannot be scaled; instead, you must provide versions for each size that you require. The font raster that you wish to use can be stored as a data resource that you need to add to the project. The Font instance itself is created from a font resource:

 Font myFont = Resources.GetFont(Resources.FontResources.NinaB) 

This font can now be supplied to the methods that draw text in a bitmap.

Drawing Text in a Bitmap

The Bitmap class provides the DrawText method, which can be used to place text on the display at a particular position.

 Font myFont = Resources.GetFont(Resources.FontResources.NinaB); myBitmap.DrawText(     "Hello World",                             // string     myFont,                                    // font     Colors.White,                              // text color     10,10);                                    // draw position myBitmap.Flush(); 

This code displays the message "Hello World" in white, starting at position (10, 10) in the top left of the display. The font that is used is loaded from the resources under the name NinaB. The coordinate specifies the top left corner of the text to be drawn.

Figure 7-10 shows the text as drawn on the display. You can have multiple fonts available and draw using each of them, as required.

image from book
Figure 7-10: "Hello World" display from DrawText method call.

Note 

Using this version of the text drawing method, you have no confirmation that the text was actually written correctly. If the text does not fit on the display, this form of DrawText will not inform you of the problem. You are strongly advised to use one of the methods that will draw text inside a rectangle and does detect when the text will not fit into a target area. Alternatively, you can calculate the size of the text before you draw it, as discussed in the next section.

Calculating the Length of Rendered Text

You may want to work out the length of a string of text before you print it so that you can make sure it will fit or align it correctly. The Font class provides the ComputeExtent method to do this for you.

 int x, y; messageFont.ComputeExtent(    "hello",                                 // input string    out x, out y);                           // locations for result Debug.Print("x: " + x.ToString() + " y: " + y.ToString()); 

This code will calculate and display the size of the rectangle needed to display "hello" using the Font instance referred to by messageFont. This method uses the out form of the C# method parameter. This allows a method to change the contents of a parameter variable when the method runs. In the case of the out parameter form, the method is allowed to store a value in the variable, which is what is required so that we can be given the size information.

Drawing Text in a Rectangle

The DrawText method will draw a string on the display. This is adequate for situations in which you just want to display a simple message. However, you may want to display a block of text. In this case, you can use the DrawTextInRect method.

 myBitmap.DrawTextInRect(    "Jackdaws love my big sphinx of quartz.",       // input string    20, 20,                                         // rectangle position x,y    150, 150,                                       // width and height    1,                                              // format    Colors.White,                                   // text color    myFont);                                        // font to use 

This method call will draw the string inside the given rectangle. The style value is used to select the required text formatting.

Figure 7-11 shows the effects of the different format values on the text layout.

image from book
Figure 7-11: Effects of different DrawTextInRect format values on the text layout.

Building Up a Display

The method call in the preceding section will draw text at a given position on the display. However, it does not allow us to build up a text display from several successive calls of the DrawInTextRect method because there is no way of knowing the position in the destination rectangle where a text drawing action has completed. You need to use a version of the method that can deliver this information to the caller.

 string myString = "hello"; int x=0; int y=0; myBitmap.DrawTextInRect(     ref myString,                             // input string     ref x,                                    // x position in rectangle     ref y,                                    // y position in rectangle     20, 20,                                   // position of rectangle on display     150, 150,                                 // size of rectangle on display     1,                                        // formatting     Colors.White,                             // text color     myFont);                                  // font 

This version of the DrawTextInRect method is provided with references to the input string and the draw position X and Y values. This makes it possible for the method to set the values of X and Y so that it can tell you where on the display it finished drawing the text. At the end of the preceding call, using the value of myfont set previously, the value of X will be updated to 34 with the value of Y remaining at 0. So after rendering the "hello" text string, the X position of the cursor is 34 pixels across and the Y position remains on the top line.

This means that you can build up text on a bitmap, perhaps to allow you to display words in different colors.

 string str = "hello "; int x=0; int y=0; myBitmap.DrawTextInRect(     ref str,                             // input string     ref x,                               // x position in rectangle     ref y,                               // y position in rectangle     20, 20,                              // position of rectangle on display     150, 150,                            // size of rectangle on display     1,                                   // formatting     Colors.White,                        // text color     messageFont);                        // font str = "world"; myBitmap.DrawTextInRect(    ref str,    ref x,    ref y,    20, 20,    150, 150,    1,    Colors.Red,    messageFont); myBitmap.Flush(); 

This code displays "hello" in white and "world" in red.

Note 

The string that is to be printed is trimmed at the start (that is, all leading spaces are removed) but not at the end (that is, all trailing spaces remain). To get the space between the words "hello" and "world," we need to put the interval space on the end of "hello," and not on the start of "world."

Drawing Large Amounts of Text

Sometimes you might want to display so much text that it won't actually fit in a single rectangle. For example, you might have several pages of help information that you would like the user to be able to page through on the device. This actually turns out to be very easy to do. The DrawTextInRect method updates the input string parameter each time it is called, so when the method is finished, the input string holds the text that has not been drawn yet.

 private string messageString = null; private Bitmap myBitmap = new Bitmap(SystemMetrics.ScreenWidth,    SystemMetrics.ScreenHeight); private int relX = 0; private int relY = 0; private Font messageFont = Resources.GetFont(Resources.FontResources.NinaB); private bool StartMessage(string message) {    messageString = message;    return ShowMessagePage(); } 

The preceding code shows how this technique can be used. The method StartMessage is called to begin the display of a large amount of text. The text to be drawn is stored in the member variable messageString. Then the method ShowMessagePage is called.

 private bool ShowMessagePage() {    // return if we have finished drawing    if (messageString == null)    {       return true;    }    // draw a black rectangle to clear the page    myBitmap.DrawRectangle(Colors.Black,       1, 20, 20, 150, 150, 0, 0,       Colors.Black, 0, 0, Colors.Black, 150, 150, 0xff);    // move to the top of the rectangle    relX = 0;    relY = 0;    // draw this page of text    bool result = myBitmap.DrawTextInRect(       ref messageString,       ref relX,       ref relY,       20, 20,       150, 150,       1,       Colors.White,       messageFont);    myBitmap.Flush();    return result; } 

This method shows a page of the message. If the message is complete, the method call returns true, otherwise it returns false to indicate that further calls will be required to complete the text display.

When ShowMessagePage is called, it checks to see if the message string has been set to null by the last call of DrawTextInRect. If the message is now empty, ShowMessagePane can return true to indicate that the text has been drawn completely. If the message string contains text, the method first clears the draw area by drawing a black rectangle the size of the text area, then sets the draw position to the top left corner of the draw area. It then calls DrawTextInRect to render another page of text.

The following call will set up the paged display of the first paragraph of this chapter:

 StartMessage(    "Many small-footprint devices have no need for complex displays. "+    "They can present perfectly usable interfaces by means of " +    "individual light-emitting diodes (LEDs) or simple single digit "+    " outputs. However, an increasing number of devices now have a need "+    " for more complex user interactions that can only be met by more "+    " detailed text and graphical displays."); 

Figure 7-12 shows the display produced by the first call to start the message display. A further call will produce the second and final page of text. You may want to improve the capabilities of this method to allow the color of the text and the dimensions of the text area to be selected.

image from book
Figure 7-12: Paged display of text.

Note 

If you want to perform more advanced methods of text display and manipulation, you are strongly advised to investigate the Windows Presentation Foundation, described in the next section, because it provides much more powerful text display and manipulation facilities.

The WPF and the .NET Micro Framework

The Windows Presentation Foundation is the latest generation of display management for Windows applications. It is one of the major components of the .NET 3.0 Framework and provides a number of advanced user interface technologies to the programmer. On the Windows personal computer platform, it provides a means by which the design of the user interface, that is, the appearance of the display components, their position on the display, and any animations and display transitions, can be expressed separately from the program code. Separating the presentation issues from the program makes changing the appearance of the components easier because there is no need for the source code to be updated if the design of the user interface is changed.

This design information is held in the Extensible Application Markup Language (or XAML) files attached to a project. The content of these files is used in conjunction with the program to produce the display the user sees. However, the XAML file provides only an additional method for configuring display components; the component properties can also be set within a program.

The library of display components provided by the .NET Micro Framework can be described as being based on the WPF in that the display architecture is the same and the methods and properties provided by display components are in line with the WPF standards. However, this library does not support the use of XAML files to express the design of a program display. Instead, you must configure and use the display components from software. In the case of the .NET Micro Framework, this is not a serious problem because the size and complexity of the displays to be produced is not as great as those for a larger system.

Note 

Although the .NET Micro Framework presentation classes have similar names and behaviors to those in the personal computer-based realization of the Windows Presentation Foundation, precise implementation details are not the same. In this book, we do not have time to provide a detailed guide to the framework. For a good description of this subject, we recommend the book Applications = Code + Markup by Charles Petzold (Microsoft Press, 2006). The first part of this book provides a very good description of the software components used to generate displays using WPF.




Embedded Programming with the Microsoft .Net Micro Framework
Embedded Programming with the Microsoft .NET Micro Framework
ISBN: 0735623651
EAN: 2147483647
Year: 2007
Pages: 118

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net