This page provides Topaz LCD tablet/software information for developers creating custom Electronic Signature applications.
Back to Software FAQ main page
NOTE: This page contains highly technical information about Topaz LCD products and software interactions and is not designed for the lay end-user.
DEVELOPER'S NOTE: When discussing x, y positions and sizes below, it is important to keep in mind the LCD specs of each Topaz tablet:
SignatureGemLCD1X5 (TL462) and SigLiteLCD (TL460): 240px x 64px (x, y origin: 0, 0 when using LCD coordinates)
SignatureGemLCD4x3 (TL755): 240px x 128px (x, y origin: 0, 0 when using LCD coordinates)
SignatureGemLCD4X5 (TL766): 320px x 240px (x, y origin: 0, 0 when using LCD coordinates)
When using coordinates in your method calls, be sure to keep your positions and sizes within these boundaries.
1. How do I write images to the LCD?
2. How do I manage hotspots correctly?
3. How do I tell when a user has tapped a hotspot? (difference between polling and pen events)?
4. How do I write text to the LCD?
5. How do I set a section of the lcd so that the signature will only be accepted in that section?
6. How many characters can I fit per line when writing text to the lcd? How many lines?
7. How do I use the pen events: Pen_Up and Pen_Down? Can I poll instead?
8. What is the difference between tablet logical coordinates and lcd coordinates? Which should I use when passing the 'Coords' argument in a method call requiring this argument?
9. How do I clear the background memory of the lcd tablet?
10. How can I manage displaying variable text of unkown length without line breaks on an LCD pad?
1. How do I write images to the LCD? Back to Top
ActiveX: Using either the LCDWriteBitmap() method or the LCDWriteFile() method. Both methods take the following 6 arguments: Dest, Mode, XPosition, YPosition, XSize, YSize
Dest: 0=foreground, 1=background
Mode: 0=Clear, 1=Complement, 2=Write Opaque, 3=Write Transparent (mode 2 is the most-often used)
XPosition: The x coord location of the upper-left corner of the image
YPosition: The y coord location of the upper-left corner of the image
XSize: The width of the image to display in px
YSize: The height of the image to display in px
The final argument is the difference between the two methods. LCDWriteBitmap() takes a Windows handle to the image (HBITMAP). For example, this can be obtained in Visual Basic by adding an Image object to the application, setting the Picture property to the image in question, and then using th Handle property of that object to assign to this argument.
LCDWriteFile() instead takes the path to the file in question. For example, "C:\somefolder\myimage.bmp".
In either case, the image must be a b&w 1-bit bmp file.
Java: Use the following method:
public boolean lcdWriteImage( int dest, int mode, int xPos, int yPos, int xSize, int ySize, Image imageData )
The first 6 arguments match the listing for the ActiveX control (see above). The last argument is an Image object, making us of a JPG.
2. How do I manage hotspots correctly? Back to Top
ActiveX: The KeyPadAddHotspot() method adds hotspots to the lcd tablet: hotspots are used to determine if the user has tapped within a specific area of the lcd, so the appropriate action can be taken in code. For example, if you place a "clear button" image on the lcd, you'll probably want to place a hotspot under this button so you'll know if the user has tapped it with the pen, and then take the appropriate action in code. KeyPadAddHotspot() takes the following 6 arguments:
KeyCode, Coords, XPos, YPos, XSize, YSize
Keycode: This is essentially a hotspot numbering system, controlled by the developer Coords: Coordinate system used for this hotspot: 0 = Logical tablet coordinates, 1 = LCD Coordinates (TOPAZ ALWAYS RECOMMENDS USING 1 = LCD Coordinates).
XPosition: The x coord location of the upper-left corner of the hotspot
YPosition: The y coord location of the upper-left corner of the hotspot
XSize: The width of the hotspot in px
YSize: The height of the hotspot in px
For example: KeyPadAddHotspot(0, 1, 20, 30, 40, 40)
(This is hotspot #0, using LCD coordinates. This hotspot's upper left corner is at 20, 30. It is 40 px wide and 40 px tall).
NOTE: hotspots have several characteristics worth mentioning that developers should note:
FIRST, the KeyPadAddHotspot() method will require slight variations in px coord location (arguments 3 and 4, varying for about 1 px to 5 px, the closer you get to the bottom of the lcd) from its counterpart LCDWriteBitmap(), LCDWriteFile(), or LCDWriteString() method calls. In other words, whereas LCDWriteBitmap(), LCDWriteFile(), or LCDWriteString() will line up precisely as expected, hotspots will start shifting slightly from 1 to 5 px as you move down the lcd.
For example, if you called:
LCDWriteBitmap(0, 2, 20, 90, 50, 30)
your call to KeyPadAddHotSpot might be something like:
KeyPadAddHotspot(0, 2, 18, 87, 52, 33)
For best results, Topaz recommends the following in terms of adding hotspots:
a. Make the hotspot larger than the image/text representing it
this eliminates hunting and tapping on the part of the user
b. Make all hotspots no smaller that 10 px in both height and width
c. Leave at least 10 px of space between hotspots
SECOND, do NOT add all the hotspots you will be using in your application at once if your users will be moving from one "screen" to another. In other words, if you have, for example, a page that the user first makes choices on, then they click something like "OK" (or equivalent) to move to the next "screen" where they might sign, you will need to create the hotspots for each page separately.
You do this by:
a. Create the hotspots for screen 1 ONLY. When you move to the next screen, you
b. Call KeyPadClearHotSpotList() to clear the hotspots out, then
c. Create the hotspots for the next screen, and so on
For example, let's assume I plan to display 2 screens: the first uses 3 hotspots, and the second uses 2 hotspots.
I would create the first three hotspots something like the following:
KeyPadAddHotspot(0, 2, 0, 10, 40, 20)
KeyPadAddHotspot(1, 2, 0, 50, 40, 20)
KeyPadAddHotspot(2, 2, 0, 90, 40, 20)
When it's time to move to the next screen, I would first call:
KeyPadClearHotSpotList()
then I would create my screen 2 hotspots, something like:
KeyPadAddHotspot(3, 2, 20, 10, 20, 10)
KeyPadAddHotspot(4, 2, 80, 10, 20, 10)
The issue involved is possible overlapping hotspots, which will cause issues to arise.
Java:
In java, all the same rules apply as above. The method calls are also the same.
3. How do I tell when a user has tapped a hotspot? Back to Top
ActiveX:
Let's assume you have hotspots created as outlined above. You can choose to manage them either by polling at a given rate of time (perhaps 200-300 milliseconds or so) or you can use the SigPlus-provided pen events (Pen_Up and Pen_Down).
Within the polling or pen event routine, you call a method KeyPadQueryHotSpot(), which takes the following argument:
KeyCode: This is the number assignment of the hotspot, as assigned in the Keycode argument of the KeyPadAddHotspot() method. Call this method within an if statement, checking whether the value returned from KeyPadQueryHotSpot() > 0.
For example:
'assume within polling routine or pen event
If SigPlus1.KeyPadQueryHotSpot(0) > 0 Then
'user has tapped hotspot #0
SigPlus1.ClearTablet
End If
or
//assume within polling routine or pen event
if(sigObj.keyPadQueryHotSpot(0) != 0)
{
//user has tapped hotspot #0
sigObj.clearTablet();
sigObj.ClearSigWindow(1);
}
It is very important that as soon as you fall within a KeyPadQueryHotSpot() routine you clear out the hotspot buffer (as shown in the code above), or your hotspot will trip every time your polling routine runs, or a pen event occurs. You can clear the hotspot buffer by calling ClearTablet() and/or ClearSigWindow(1).
Be sure that in your polling routine or pen event routine, you call ClearTablet() and/or ClearSigWindow(1), in case you do not trip any hotspots. If your code makes it through the routine without getting into one of the KeyPadQueryHotspot() routines, the hotspot buffer will still need to be cleared.
4. How do I write text to the LCD? Back to Top
ActiveX:
Using the LCDWriteString() method. This method takes 8 args:
Dest, Mode, XPos, YPos, XSize, YSize, Format, HexString
Dest: 0=foreground, 1=background
Mode: 0=Clear, 1=Complement, 2=Write Opaque, 3=Write Transparent (mode 2 is the most-often used)
XPosition: The x coord location of the upper-left corner of the image
YPosition: The y coord location of the upper-left corner of the image
XSize: The width of the image to display in px
YSize: The height of the image to display in px
Format: NOT CURRENTLY IMPLEMENTED - PASS A 0
HexString: String value to display
If 0's are passed for the size args, then the default size will be used. For example:
SigPlus1.LCDWriteString(0, 2, 0, 0, 0, 0, 0, "This is a test string")
You can also control the font more completely using the LCDSetFont() method. The arguments for this method are all defined in the LOGFONT data structure (see CreateFont function of Windows API) in Windows for logical fonts. They are:
Height, Width, Weight, Italic, Underline, PitchAndFamily, FaceName
The FaceName argument is used to specify a particular font. Again, see the CreateFont function of Windows API for details on the other args. Leaving the args at 0 will result in the default for each value to be used. An example is below:
SigPlus1.LCDSetFont(0, 0, 0, 0, 0, 0, "Courier New")
Java:
Use the lcdWriteString() method, which takes the following args:
Dest: 0=foreground, 1=background
Mode: 0=Clear, 1=Complement, 2=Write Opaque, 3=Write Transparent (mode 2 is the most-often used)
XPosition: The x coord location of the upper-left corner of the image
YPosition: The y coord location of the upper-left corner of the image
HexString: String value to display
Font: Font object based on java font class
For example:
Font myFont = new Font( "Dialog", Font.BOLD, 12 );
sigObj.lcdWriteString( 0, 2, 10, 10, "This is a sample line of text.", myFont );
5. How do I set a section of the LCD so that the signature will only be accepted in that section? Back to Top
ActiveX:
There are two methods that work together for this functionality (although you can certainly use them separately should your application have specific requirements):
SetSigWindow() and LCDSetWindow()
SetSigWindow() defines a specific area on the tablet that will accept pen data as "signature" data (collected in the signature object). Outside of this window, pen data will not be added to the signature. This is useful especially when hotspots are used; the area where the hotspots reside can be left out of the signature window, so that hotspot taps do not accumulate in the signature. It is important to indicate to the user, of course, the specific area set aside as the "signature" area (either with text or an image) when using the SetSigWindow() method. This method takes 5 args - Coords, XPos, YPos, XSize, YSize:
Coords: Coordinate system used for this hotspot:
0 = Logical tablet coordinates, 1 = LCD Coordinates (TOPAZ ALWAYS RECOMMENDS USING 1 = LCD Coordinates).
XPosition: The x coord location of the upper-left corner of the signature window
YPosition: The y coord location of the upper-left corner of the signature window
XSize: The width of the signature window in px
YSize: The height of the signature window in px
For example:
SigPlus1.SetSigWindow(1, 3, 30, 122, 30)
LCDSetWindow() defines a specific area on the LCD itself where "electronic ink" is displayed. It is important to note that this method has nothing to do with the captured signature...only the signature as it is displayed on the LCD. Typically, when you call the SetSigWindow() method to create a window which limits the area in which signature data is captured, you want to also limit the LCD itself to display the signature representation in the same manner. This method takes 4 args - XStart, YStart, XSize, YSize:
XPosition: The x coord location of the upper-left corner of the signature window
YPosition: The y coord location of the upper-left corner of the signature window
XSize: The width of the signature window in px
YSize: The height of the signature window in px
For example:
SigPlus1.LcdSetWindow(0, 0, 60, 32)
In other words, if you call SetSigWindow() without calling LCDSetWindow(), you will limit the signature in the SigPlus object to a certain area, but the LCD will display all of the ink drawn by the pen, even if it exceeds the window set by SetSigWindow(). Likewise, if you call LCDSetWindow() without calling SetSigWindow(), all of what is drawn by the pen will be captured in the SigPlus object, but the LCD will be limited to displaying "electronic ink" in the specified area only.
To inhibit ink on LCD screen completely, use the following code:
SigPlus1LCDSetWindow(0,0,0,0)
To inhibit ink in the SigPlus object completely, use the following code:
SigPlus1.SetSigWindow(1,0,0,1,1)
(be sure to leave at least one pixel in the Xsize and Ysize arguments)
If you are calling the LCDSetWindow() or SetSigWindow() and clearing and adding new hotspots in the same routine, be sure to first clear the hotspot list using SigPlus1.KeyPadClearHotSpotList(), then calling LCDSetWindow() or SetSigWindow(), then adding your new hotspots using the KeyPadAddHotSpot() method.
The idea is to set the windows while the hotspots are clear.
6. How many characters can I fit per line when writing text to the lcd? How many lines? Back to Top
Assuming you are using a fixed-width font (with a 5 px spread), you can expect the following (you may need to extrapolate further data based on these stats--and remember these are rough, rule-of-thumb values):
SignatureGemLCD1X5 and SigLiteLCD-
At font size 8, the total number of possible lines is: 12
Number of characters per line: 39
At font size 10, the total number of possible lines is: 10
Number of characters per line: 34
At font size 12, the total number of possible lines is: 9
Number of characters per line: 26
SignatureGemLCD4X3-
At font size 8, the total number of possible lines is: 24
Number of characters per line: 39
At font size 10, the total number of possible lines is: 20
Number of characters per line: 34
At font size 12, the total number of possible lines is: 18
Number of characters per line: 26
SignatureGemLCD4X5-
At font size 8, the total number of possible lines is: 45
Number of characters per line: 52
At font size 10, the total number of possible lines is: 37
Number of characters per line: 45
At font size 12, the total number of possible lines is: 33
Number of characters per line: 34
All characters after the cutoff will be lost.
7. How do I use the pen events: Pen_Up and Pen_Down? Can I poll instead? Back to Top
ActiveX:
You will need an event handler for Pen_Up, Pen_Down or for both, for example:
SigPlus1_PenUp()
or
SigPlus1_PenDown()
Place the code you wish to run in the event of a pen event in the appropriate event handler. The methods used by the tablet which will need to be called in the event handler is:
KeyPadQueryHotSpot()
Which is used to check if a hotspot has been tapped
It is very important to note that there is a method call necessary for the pen events to function: SetEventEnableMask(). The SetEventEnableMask() method takes a single arg - EventMask:
EventMask: an integer value used to set the mask for either 1=Pen Down, 2=Pen Up, 3=Both Pen Down and Pen Up
For each time the pen_up or pen_down event fires, the SetEventEnableMask() method must be called. Therefore, at the end of each event, you'll need to call the SetEventEnableMask() method to trigger the next pen event. This method is used to offer further control to the developer. A pen event will only fire once and will not fire again until the SetEventEnableMask() method is called. Otherwise, it could fire repeatedly should the user keep the pen pressed to the tablet.
Instead of using the pen events, you may choose to poll. This methodology entails the use of a timer of some sort that checks at a certain rate for pen activity (calling KeyPadQueryHotSpot(), etc.) Typically, the rate is somewhere between 100-300 ms. This methodology does not require the use of the pen event handlers, nor a call to SetEventEnableMask().
Java:
In java you can spin a new thread, and set the sleep rate as desired. Something like:
public void run()
{
try
{
while (true)
{
Thread.sleep(200);
//code here
}
}
catch (InterruptedException e)
{
}
}
No current implementation of the pen events currently exists in java...use the thread/sleep methodology shown above.
8. What is the difference between tablet logical coordinates and lcd coordinates? Which should I use when passing the 'Coords' argument in a method call requiring this argument? Back to Top
Tablet Logical coordinates are the original coordinate system designed for Topaz tablets. They are based on a 0, 0 position which exists up and left from where the active area of the tablet begins. So, the point at which the active area of a particular tablet (where the tablet will start capture pen data) never begins at 0, 0 in tablet logical coordinates, and can vary to different degrees. For example, the active coordinate origin for a SignatureGemLCD1X5 is 400, 350. For the SignatureGemLCD4X3, it is 500, 400. Other tablets will vary.
LCD coordinates were added to SigPlus for ease of use in terms of calls to methods where an x and y position are required, for instance KeyPadAddHotspot(). The LCD coordinate system makes the upper-left corner of the lcd itself the 0, 0 position, and the bottom-right corner of the lcd itself the extent of the lcd, which is:
for SignatureGemLCD1X5 (TL462) and SigLiteLCD (TL460): 240, 64
for SignatureGemLCD4x3 (TL755): 240, 128
for SignatureGemLCD4X5 (TL766): 320, 240
In terms of tablet logical coordinates, the top-left corner of the lcd is a counterintuitive value, far from 0, 0 since 0, 0 in tablet coordinates is a position not only far beyond the upper-left corner of the lcd, it is beyond the active area. This is the reason Topaz highly recommends using LCD coordinates over tablet logical coordinates.
9. How do I clear the background memory of the lcd tablet? Back to Top
The easiest way is to call the LCDWriteFile() method, passing an initial argument of 1 (to indicate write to the background memory), then followed by a 0 (indicating complete refresh). This will erase the background memory of the LCD. For example:
Clear background memory of LCD1x5:
SigPlus1.LCDWriteFile(1, 0, 0, 0, 240, 64, 0, "")
Clear background memory of LCD4x3:
SigPlus1.LCDWriteFile(1, 0, 0, 0, 240, 128, 0, "")
Clear background memory of LCD4x5:
SigPlus1.LCDWriteFile(1, 0, 0, 0, 320, 240, 0, "")
To clear only a portion of the LCD's background memory, use arguments 3, 4, 5, and 6 (XPos, YPos, XSize and YSize, respectively). For example,
SigPlus1.LCDWriteFile(1, 0, 160, 120, 160, 120, 0, "")
clears only the bottom-right 1/4 of the LCD's background memory.
10. How can I manage displaying variable text of unkown length without line breaks on an LCD pad? Back to Top
There are two methods that will allow for sizing. One will return the current LCD size, and the other (based on the text you pass in, and also on your current LCDSetFont() settings) provides the size in px you will need for that text.
GetLCDSize()
Function: Returns the XSize and YSize (in LCD coords) of the tablet currently specified in the SigPlus.ini.
Return Value: unsigned long - (YSize upper 16 bits, XSize lower 16 bits)
GetLCDTextSize(str StringToBeDisplayedOnLCD)
Function: Returns the XSize and YSize (in LCD coords) necessary to display on the LCD the string argument, based on the font parameters (see LCDSetFont() method for details). Use to determine the LCD size necessary for your display Text.
Argument: String Text to be displayed on the LCD
Return Value: unsigned long
|