TealPrint Application Developer's Notes

Introduction

TealPrint is a powerful and flexible application which adds universal text and graphics printing support to any application. This package exists to help an application developer add TealPrint printing support to their product.

Overview

TealPrint is a standalone application that provides both built-in printing functionality and an external printing interface for other programs. It communicates with the printer hardware through software printer drivers, which are also implemented as individual programs for easy maintenance and testing.

TealPrint supports printing of both text and graphics to supported printers, including printing spooled print jobs to any Windows printer through the hotsync cradle.

Native text mode printing is supported with selectable automatic text wrapping and word breaks. Bitmap graphics, lines and filled rectangles are supported, as well as a complete expandable font system for printing graphic text.

The application interface to TealPrint takes a tiered approach, offering a range of function calls ranging from quick interfaces for simple printing to a more complex page-layout method for more complex printing, with scaling, rotating, and mirroring effects.

Calling Mechanism

Start TealPrint with SysAppLaunch(), passing it one of the custom program launch codes defined in TealPrnt.h, and a corresponding data structure for the call. Unused or unknown fields in the data structure should be set to zero. A handy function for calling TealPrint follows:
	int CallTealPrint( int command, PrintParamsType *data )
	{
		DmSearchStateType sst;
		DWord retval;
		LocalID id;
		UInt card;

		if ( DmGetNextDatabaseByTypeCreator( true, &sst, (ULong)'appl', (ULong)'TlPr',
  	                                        true, &card, &id ) == 0 ) {

			SysAppLaunch( card, id, 0, command, (void *)data, &retval );

			if (command==PRINT_CMD_InstantPrintText   ||
			    command==PRINT_CMD_InstantPrintWindow ) {
				return 0;
			} else {
				return data.generic_params.retval;
			}

		} else {
			FrmAlert( ID_ALERT_tealprint_not_found );
			return -1;
		}
	}

Driver Launch Codes

PRINT_CMD_SystemInfo
Return information about the system including system version, revision, and name in a SystemInfoParams structure.
PRINT_CMD_GetSettings
Copy the contents of the global system PrintSettings structure to the passed structure pointed in a GetSettingsParams structure.
PRINT_CMD_SetSettings
Copy the contents of the passed PrintSettings structure over the global system PrintSettings structure.
PRINT_CMD_PrintObject
Print the contents of a PrintTextObject, PrintBitmapObject, PrintPageObject, etc structure. This is the multipurpose "meaty" print routine. All of these objects begin with a PrintObject structure. The contents of the type field determines the form of the rest of the structure.
PRINT_CMD_PrintClipboard
Print the contents of the clipboard.
PRINT_CMD_ChooseSettings
Instruct TealPrint to bring up a dialog to set the contents of the PrintSettings structure indicated in the ps field of a ChooseSettingsParams struct. If the field is zero, then the default global structure is modified instead.
PRINT_CMD_ChooseOptions
Bring up a dialog to set the text or graphic options flags in the indicated PrintSettings structure indicated in the ps field of a ChooseOptionsParams struct. If the field is zero, then the default global structure is modified instead. If the print_mode field in the PrintSettings struct is set to PRINT_MODE_text, then the text options are set. If it's PRINT_MODE_graphic, then the graphic print options are set.
PRINT_CMD_ChooseFont
Bring up a font selection dialog to alter in the contents of a FontSpec structure. Set the font field in the ChooseFontParams struct to zero to alter the default graphic text font.
PRINT_CMD_ChooseDriver
Bring up a dialog to allow changing printer drivers.
PRINT_CMD_ChoosePaper
Bring up a dialog to allow setting a different paper size. Paper sizes are maintained by the current printer driver.
PRINT_CMD_ChooseGfxMode
Call the current printer driver to set the current graphics print mode.
PRINT_CMD_ChooseTxtMode
Call the current printer driver to set the current text printing mode.
PRINT_CMD_CallDriver
Pass a call directly down to the current printer driver
PRINT_CMD_InstantPrintText
Quickly and most-painlessly print a null-terminated text string using the global default settings. Pass a pointer to the string itself in the data field.
PRINT_CMD_InstantPrintWindow
Quickly and most-painlessly print the full contents of a Window. Pass the window handle itself in the data field.

Example: Printing text

Using the CallTealPrint() call defined above, printing a simple text string can be as easy as:
CallTealPrint( PRINT_CMD_InstantPrintText, "Hello World" );
To bring up a dialog box to set setting before print the text, the code balloons to:
	{
		ChooseSettingsParams csp;
		long retval;

		csp.flags = PRINT_CHOOSE_SET_print;		// show "Print" button instead of "Ok"
		csp.ps = 0L;									// change global settings

		CallTealPrint( PRINT_CMD_ChooseSettings, (void *)&csp, &retval );

		if (!retval) {
			CallTealPrint( PRINT_CMD_InstantPrintText, "Hello World" );
		}
	}
	

Example: Printing a graphic

Printing graphics are almost as easy as printing text. For instance, to quickly dump the screen:
CallTealPrint( PRINT_CMD_InstantPrintWindow, WinGetDisplayWindow() );
Note that in practice, you probably want to allocate a temporary window and make a copy of the current screen before printing, as some printer drivers can be set to display status information to the screen, and this may show up in the screen dump if you aren't working off a copy.

Example: Printing text objects

While the previous examples take care of simple printing tasks, in general, most programs require tighter control of printing parameters. To do this, TealPrint support printing of more complex print "objects" that can be individually placed and nested.

At the core of this functionality is the PrintObject structure, which appears at the top of every specialized print object.

	typedef struct PrintObject {
			  
		int      type;
		int      dx,dy,dw,dh;
		long     print_flags;
		struct   PrintObject *ref_obj;	// for relative positioning
		void    *system_data;				// reserved for system use

	} PrintObject;
type
This defines the type of object being printed, and thus the form of the rest of the defining structure. For instance, some memory-resident text would typically be printed with an object of type PRINT_OBJECT_simple_string.
dx
Printed position of this object's left edge relative to its parent box. The root print object's parent box is the region inside the current page margins, unless the PRINT_OUTFLAG_ignore_margins flag bit is set. The units for the printed position and size are specified by bits in the print_flags field.
dy
Printed position of this object's top edge relative to its parent box.
dw
Printed width of this object.
dh
Printed height of this object.
print_flags
Flags for how this object is defined. The printed size and position of this object are defined by dx,dy,dw,dh, and one of the following flag values:
		#define PRINT_OUTFLAG_size_percent	   0x0000	// final size based on 75dpi palm screen res
		#define PRINT_OUTFLAG_size_pixels	   0x4000	// actual size pixels
		#define PRINT_OUTFLAG_size_mils		   0x8000	// actual size in thousandsths of an inch
		#define PRINT_OUTFLAG_size_multiple	   0x10000L	// multiple of printer resolution in percent
		#define PRINT_OUTFLAG_size_fraction    0x20000L	// fraction of printable paper area in percent
		#define PRINT_OUTFLAG_size_chars		   0x40000L	// actual size characters
		
In addition, other flags for centering, justification, inverting, rotating, and flipping are defined in tealprnt.h
ref_obj
When multiple objects contained in a Page Object (described below), objects can be placed relative to other objects appearing earlier to itself in the list. To do so, a pointer to the other object should be set in ref_obj, and one or more of the print flag bits should be set below:
		#define PRINT_OUTFLAG_relative_left		0x0400000L
		#define PRINT_OUTFLAG_relative_right	0x0800000L
		#define PRINT_OUTFLAG_relative_top		0x1000000L
		#define PRINT_OUTFLAG_relative_bottom	0x2000000L
		
system_data
This field is used exclusively by TealPrint as part of the printing process. As a consequence, all PrintObject structures must reside in writable memory.
Here is example code from TealPhone for printing an address label using a PrintTextObject:
		{
			PrintObjectParams pop;
			PrintTextObject pto;

			pop.ps = 0;
			pop.po = (PrintObject *)&pto;

			MemSet( &pto, sizeof(pto), 0 );
			pto.type = PRINT_OBJECT_simple_string;
			pto.dw = pto.dh = 100;
			pto.print_flags = PRINT_OUTFLAG_size_fraction | PRINT_OUTFLAG_center_x | PRINT_OUTFLAG_center_y );
			pto.text_length = StrLen(ptr);
			pto.easy_text = ptr;
			pto.text_font = font;

			SysAppLaunch( card, id, 0, PRINT_CMD_PrintObject, (void *)&pop, &retval );
			retval = pop.retval;
		}
	

Using virtual text and graphics

Of course, the example above doesn't do much more than the quick text option did. One of the powerful features of PrintObjects is in allowing you to print documents or images larger than can fit in available memory. You can even print procedural bitmaps like Mandelbrots this way. This is done using the PRINT_OBJECT_virtual_string, or PRINT_OBJECT_virtual_bitmap print objects.

Although text and graphics are fundamentally different, the calling mechanisms for both are similar. Basically, you provide a callback function to the print routines when you begin. The system then periodically calls your routine to decompress, generate, or otherwise return back the information it needs to print a particular section of the page.

For printing virtual text, you fill in the PrintTextObject structure, setting len to the full length of the text to be printed, and provide the system with the following function:

void CopyFunc( char *buffer, long offset, long count, void *app_data )
buffer
A pointer to return the generated text
offset
A offset into the virtual string of where the returned text belongs
count
A count of bytes to return
app_data
This is a copy of the longword value in the callback_data field of the PrintTextObject struct

For printing a virtual bitmap, you fill in the PrintBitmapObject structure, setting sw and sh with the full size of the virtual bitmap in pixels. TealPrint will call your routine periodically with a smaller rendering window with corresponding offsets of where the small window is located relative to the large virtual bitmap. Provide the system with the following rendering function:

void DrawFunc( WindowType *window, int x,int y,int w,int h, void *app_data )
window
The window where you should do your rendering
x,y,w,h
The coordinates of the rendering window within the large virtual bitmap. You usually subtract x and y from your normal rendering routines to obtain the correct offset.
app_data
This is a copy of the longword value in the callback_data field of the PrintBitmapObject struct

Example: Printing mixed pages

Another powerful feature of PrintObjects is the ability to mix and nest print objects on a single page. To to this, use the PrintPageObject to contain the other objects. PrintPageObjects can also contain other PrintPageObjects.

PrintPageObjects contain the standard PrintObject fields and only two other fields: objects, which is an array of pointers to PrintObjects contained in this page, and num_objects, which is a count of the number of objects contained.

The PrintPageObject's coordinates are defined relative to the printable space on the paper within the defined margins. The objects it contains are defined relative to the PrintPageObject's bounds. Thus, scaling a PrintPageObject will also affect all of its child objects. When printing graphic text, font will automatically remap to try to accomodate the scaling.

In addition, special effects such as rotating, flipping, and inverting are also inherited by all "child" objects within a page. If a page is rotated using the "landscape" flag, all of the objects within move and rotate as well to maintain the PrintPageObject's internal layout.

Printing multiple pages

PrintObjects are designed to print out data on a single sheet. To print text that may span multiple pages, use the chars_used field that is filled in in the PrintTextObject struct after a print operation. This indicates the total number of characters that actually fit within the bounds of the defined object and thus can be used to increment a string pointer for where to start printing a following page.

Flowing text

TealPrint supports flowing text between text objects on a single page as well, using the preflow_ptxt field in a PrintTextObject. When nonzero, this field indicates that a given objects takes text overflowing from the indicated PrintTextObject. When using this feature, the text pointers and lengths for all text objects should be set identically and the preflow_ptxt field set on all but the first object set to point to its predecessor.

How settings work

A default set of global settings for output size, special effects, and font mappings is maintained within TealPrint itself. For most print operations, it's best to pass zero in optional settings fields so that TealPrint uses these default values. This gives the user maximum flexibility and control.

In some cases, it may be desireable to override the default settings from within a program, perhaps to provide even more control like independent fonts for different parts of a document, or maybe to restrict control when printing, say, a standard form or insert that requires tightly-controlled positioning.

In either case, TealPrint lets you create a modified interface to print settings by providing access to the standard dialogs at multiple levels and flag bits to hide non-applicable options.

Tabs

Tab support is pretty simple at this point. Currently, printing with internal Palm fonts sets tab stops at every 20 pixels, emulating the Palm display code. Custom fonts support tab stops at every 50 pixels, and printing native printer text supports tabs every 4 characters.

Customizable tab stops will likely be available in a future release.

Extensible Fonts

TealPrint supports addition of external bitmap fonts for graphic text printing. The fonts are in custom-formatted databases consisting of a simple header in the first record and Palm bitmap structures in all other records.

Conversion utilities will probably be forthcoming.

Future Enhancements

Future releases of TealPrint will likely support color, the ability to imbed font and color-change information within text strings (for mixing fonts), customizable tab stops, and perhaps the ability to easily link graphics into a text string so that they flow together.

Conclusion

That's it. Questions? Please contact support@tealpoint.com. Check the developer's section of our Software page for other hints, tools, and information. Thanks,

TealPoint Software Staff