Newton 2.x Q&A Category: Routing

Copyright © 1997 Newton, Inc. All Rights Reserved. Newton, Newton Technology, Newton Works, the Newton, Inc. logo, the Newton Technology logo, the Light Bulb logo and MessagePad are trademarks of Newton, Inc. and may be registered in the U.S.A. and other countries. Windows is a registered trademark of Microsoft Corp. All other trademarks and company names are the intellectual property of their respective owners.


For the most recent version of the Q&As on the World Wide Web, check the URL: http://www.newton-inc.com/dev/techinfo/qa/qa.htm
If you've copied this file locally, click here to go to the main Newton Q&A page.
This document was exported on 7/23/97.

Routing


Printing Resolution 72DPI/300DPI (2/8/94)

Q: I've tried to print PICT resources; the picture was designed in Illustrator and copied to the clipboard as a PICT. The picture printed correctly but at a very low resolution. Is there any way of printing PICTs with a higher resolution?

A: Currently the only supported screen resolution for PICT printing is 72dpi. This may change in future platforms, so stay tuned for more information.


PICT Printing Limitations (6/9/94)

Q: My large pictures cannot print on my LaserWriter. Is there a maximum size Newton picture?

A: The current PostScript printing system in the Newton ROMs is unable to print extremely large individual bitmap frames, the kind of pictures created using the NTK Picture editor or the GetPictAsBits routine. This is because in order to print these, the Newton must copy the bitmaps into an internal buffer. Thus the GetPictAsBits case fails (current limitation is a 168K buffer, but do not rely on a specific number for other Newton devices).

Using the GetNamedResource(..., 'picture) routine, you can use PICT resources to be drawn in clPictureViews. MacOS PICT resources often contain multiple opcodes (instructions). For single-opcode PICTs, compression is done for the whole picture. You can check Inside Macintosh documentation for specifications of the PICT format. If you are using very large bitmaps which you will print, you should use PICT resources composed of many smaller 'bitmap copy' opcodes because they will print much faster and more reliably on PostScript printers. This is because very large PICT opcodes printed to LaserWriters must be decompressed on the printer. The printer's decompression buffer is sometimes too small if the opcodes represent large bitmaps. Check your MacOS graphics application documentation for more information on segmenting your large PICTs into smaller pieces. For some applications, you might have two versions of the PICTs, one for displaying (using GetPictAsBits for faster screen drawing), and a large tiled PICT for printing.

Starting with Newton 2.1 OS, color PICTs (PICT 2) are supported. Colors will be interpolated into gray values.


Printing Fonts with a PostScript Printer (7/26/94)

Q: When printing from my application on the Newton to a PostScript Laser printer, I noticethat the fonts are substituted. Printing always looks fine on a fax or bitmap printer like the StyleWriter.

A: Yes, this is true.The additional System font (Espy Sans) or any custom Newton font created with the Newton Font Tool is not printed directly to a LaserWriter because the fonts are missing in the PostScript font versions. Just printing Espy Sans (Newton system fonts) is currently not possible on the LaserWriter, but is possible on faxes and bitmap printer drivers, since the rendering for those is done inside the Newton.

For the built-in Espy font, the troublesome characters are the Apple-specific ones, starting with Hex FC. The filled diamond is one of these characters, the specific tick box arrow is another.

For printing, you might need to include bitmaps for special characters or words in your application in order to print them (that is, if the normal LaserWriter fonts are unacceptable)

Note that if you want a monospaced font, check out the DTS sample "MonacoTest". That includes a font which will print as the monospaced Courier font.


Printing Does Not Have Access to My Application Slots (11/27/95)

Q: Why can't I find my application slots from my print format?

A: Print format does not have direct access to your application context because it is not a child of your application, so it cannot rely on the parent inheritance chain. All viewDefs should be designed so that they do not rely on your application being open or rely on state-specific information in your application. The application may be closed, or the user may continue to work in your application while the print/fax transport is imaging.

Print format does have access to the target variable (it will contain the "body" of the data sent; don't use fields.body). Note that if mulitiple items are sent, the value of target will change as the print format iterates over the list. Try to put the real "data" for the routing in the target using the view method GetTargetInfo.

If, for some reason, you need to access slots from your application, you can access them using GetRoot().(yourAppSymbol).theSlot.


How to Open the Call Slip or Other Route Slips (12/19/95)

Q: How do I open the call slip (or other route slips) programmatically?

A: Use the global function OpenRoutingSlip. Create a new item with the transport's NewItem method and add routing information such as the recipient information in the toRef slot. For the call slip, the transport symbol will be '|phoneHome:Newton|, but this approach will work for other transports. (For transports other than the call transports, you will also provide the data to route in the item.body slot.)

Determining the value of the toRef slot

The toRef slot in the item frame should contain an array of recipients in the form of nameRefs, which are the objects returned from protoPeoplePicker and other protoListPicker-based choosers. Each nameRef can be created from one of two forms: a cardfile soup entry, or just a frame of data with minimal slots. (The required slots vary depending on the transport. For instance, the current call transport requires only phone, name, and country.)

1. Cardfile entry:
        entry := myCursor:Entry();


2. Create your own pseudo-entry:
        entry := {
        phone:"408 555 1234",
        name: {first: "Glagly", last: "Wigout"},
        country: "UK",
    };



Make the entry into a "nameRef" using the nameRef's registered datadef -- an object which describes how to manipulate nameRefs of a specific class. Note that every transport stores its preferred nameRef class symbol in its transport.addressingClass slot. (Examples are '|nameRef.phone| and '|nameRef.email|).

local class := '|nameRef.phone|;
local nameRef := GetDataDefs(class):MakeNameRef(myData, class);



Setting up the targetInfo Frame

Your GetTargetInfo view method should return a targetInfo frame, consisting of target and targetView slots. Alternatively, you can create a frame consisting of these slots and pass it to OpenRoutingSlip. As a workaround to a ROM bug, you must also supply an appSymbol slot in the targetInfo frame containing your appSymbol. Note that targetInfo.target could be a multiple item target (see the CreateTargetCursor documentation for more info.)


Opening The Slip

You can use OpenRoutingSlip to open the slip after setting up slots such as toRef and cc within the item. You can use code such as the following:

/* example using Call Transport */
local item, entry, class, nameRef;

// just for testing, get an Name...
entry := GetUnionSoup("Names"):Query(nil):Entry();

item := TransportNotify('|phoneHome:Newton|, 'NewItem, [nil]);
if item = 'noTransport or not item then
    return 'noTransport; 

class := '|nameRef.phone|;
nameRef := GetDataDefs(class):MakeNameRef(entry, class);
item.toRef :=  [nameRef];
targetInfo := {
    targetView: getroot(), 
    target: {}/* for non-CALL transports, add your data here! */, 
    appsymbol: kAppSymbol
    };

// returns view (succeeded), or fails: nil or 'skipErrorMessage
OpenRoutingSlip(item, targetInfo);


Routing Multiple Items (5/15/96)

Q: How can my application route multiple items at one time?

A: The target must be a "multiple item target" created with the CreateTargetCursor function.
For instance, your application could use a GetTargetInfo method like:

        func(reason)
    begin
        local t := CreateTargetCursor(kDataClassSymbol, myItemArray);
        local tv := base; // the targetView

            return {target: t, targetView: tv};
    end;


The first argument to CreateTargetCursor is used as the class of the target, which is used to determine what formats and transports are available. You must register formats on that data class symbol in your part's InstallScript function.

The item array passed to CreateTargetCursor can contain any items, including soup entries or soup entry aliases. If you include soup entry aliases, they will automatically be resolved when accessing items using the GetTargetCursor function.

Print formats that have their usesCursors slot set to nil will automatically print items on separate pages -- print formats must use the target variable to image the current item. To print multiple items, set the format usesCursors slot to true and use GetTargetCursor(target, nil) to navigate through the items.

If either the format (the usesCursors slot) or the transport (the allowsBodyCursors slot) does not support cursors, the system will automatically split the items into separate Out Box items.


When to Call Inherited ProtoPrintFormat ViewSetupFormScript (1/6/97)

Q: Does it matter when I call the inherited method in my protoPrintFormat:viewSetupFormScript()?

A: Yes, you must call the inherited method before doing anything else in the viewSetupFormScript.

Among other things, the inherited method sets up the page size. After calling the inherited method, you can call self:LocalBox() and get the correct page size. Note that you cannot rely on the protoPrintFormat.viewBounds slot value. To position subviews within the print format centered or "full" width or height, use view justifications like centered, right, and full, or use theEnclosingView:LocalBox() to determine the exact size of the enclosing view.


Limitations with NewtOverview Data Class (1/8/97)

Q: I want to use code like CreateTargetCursor('newtOverview, myItemArray) in my application to simplify my code which handles overviews. Why would my print format throw an exception when I use this method?

A: There are limitations to using the 'newtOverview symbol as your data class with CreateTargetCursor. The biggest limitation is that it requires you to support exactly the set of of datatypes: ['frame, 'text, 'view]. In other words, you must register a protoFrameFormat (by default, it handles 'frame and 'text dataTypes) and a protoPrintFormat. However, there are two other limitations not mentioned in the final documentation: the system does not guarantee that it will call your print format's formatInitScript method or a format's SetupItem method.

This means that if your print format's viewSetupFormScript (or other code in the print format) assumed that the formatInitScript has been called, it could cause errors and/or exceptions. The workaround to this would be to set a flag in the formatInitScript; if it was not set at the beginning of viewSetupFormScript, send your format the formatInitScript message. Other problems could occur with SetupItem, but you'd probably not see any errors or exceptions until you tried to beam/mail a frame to another device and then tried to Put Away the item.

About the default overview class: when you use CreateTargetCursor to prepare a "multiple item target", you may be able to use this special 'newtOverview symbol as your data class. If your application prints every item on separate pages (in other words, not multiple items on one page) and you want to split beam and mail items into separate items in the Out Box, this might be useful to you. For more information, see the Newton Programmers Guide (not reference) in the Routing chapter "Using the Built-in Overview Data Class" section and the "Move It!" article in the Newton Technology Journal 2.02. Also, check out the MultiRoute DTS sample.


NEW: Beam is Partially Available for Text Routing (5/22/97)

Q: My application doesn't support 'frame dataTypes. Why is Beam available in my Action picker in Newton 2.1 OS?

A: The Beam transport in Newton 2.1 OS supports the 'text dataType. If any routing formats for your data supports text export (a format.dataTypes array includes 'text), Beam will be available. Unfortunately, there is a bug in current Newton 2.1 OS devices such that Beam does not convert the target to text before sending it. Transports that support sending text should use the kItemToTextFunc function (in the Newton 2.x platform files), and that function calls the format's TextScript to convert the item to text. Since Beam does not do this, this gives the appearance that the item is being sent as 'frame, a dataType that may not be supported by your application's routing formats.

There are several workarounds (with the first choice recommended):
#1) Add support for the 'frame datatype. In your routing format, add 'frame to the dataTypes slot. This will allow all 'frame transports, including mail transports that can send attachments, to send mail with your application. This will allow your application to avoid text-specific bugs in Beam. For the best user interface, we recommend that you write stationery for your data so that users can view the item in the In Box or Out Box. See the Newton Programmers Guide and Reference for more information about writing and registering stationery. Note that you can test your application with Put Away, using the built-in Beam transport as well as the DTS sample "Archive Transport".

#2) Provide a text-only format that converts the item to text in the format:SetupItem(...) method. If you don't support overviews or other mechanisms that use multiple item targets, change item.body to be a new frame of the form {text: "the converted item to text", class: 'text}. Note that this format should not also support the 'frame dataType because you are destructively modifying the item.

If you do support multiple item targets, you have to do more work because the items are not split up into seperate items before your SetupItem method is called. You can use the code like the following in your SetupItem format after calling the inherited method:

// get a 'cursor' to iterate over the items.
// Note: this still returns a 'cursor' even if item.body wasn't real
local cursor := GetTargetCursor(item.body, nil);
local newArray := [];
local entry := cursor:entry();
while (entry) do
    begin
        // convert item to text in whatever way you normally do it...
        // For instance, you might call your format's textscript...
        entry := {
            text: "blah blah" && entry.a && entry.b,
            class: 'text
            }; 
        AddArraySlot(newArray, entry);
        entry := cursor:Next();
    end;
        
item.body := CreateTargetCursor(classof(item.body), newArray);

// remember to return 'item' from SetupItem
item
 

You might be wondering if you could route the 'frame data by hiding the data in extra slots in item.body. If you did that, the item would be much larger than necessary to route 'frame data, and will not be Put Away properly because the 'class slot is set to 'text, not your original data class). If you actually want to support 'text and 'frame dataTypes, use a single protoFrameFormat with dataTypes ['frame, 'text] and do not convert the item.body as illustrated above. (This is actually recommendation #1 above).

Note that 'text stationery must be registered in order to view the item in the In Box and Out Box. Such stationery is not necessarily installed on the receiving device. Some mail transport packages may have installed 'text stationery, but you may choose not to rely on this. If you are interested in writing text stationery, see the DTS sample "MinMail" and the Newton Programmers Guide and Reference for more information about writing and registering stationery.


NEW: Page Sizes Cannot Be Determined Before Printing Begins (7/10/97)

Q: How can my application or print format determine the exact page size before the print job actually starts?

A: There is currently no supported API to do this. You cannot rely on a particular size for the actual printable area of the paper, nor the actual printable area as viewed by your print format. This is a limitation of the current Newton OS printing architecture.

The correct way for a print format to determine its size is for the print format to call :LocalBox() in its viewSetupFormScript, viewSetupChildrenScript, or viewSetupDoneScript. This is only accurate during the current print job to the printer or fax driver. You cannot determine this size during Print/Fax preview, nor during the print format's formatInitScript, nor in your application's on-screen views.

The size of the print format is affected by many factors that can change before the print job begins. Factors include, but are not limited to, the printer driver, the printer/fax settings, and whether a fax cover page is selected in the Fax routing slip. (The least intuitive of these variables is the fax cover page, which also controls the fax header strip at the top of the page -- affecting the height of the printable area.)

A common question is whether the print format formatInitScript can accurately determine the page height. This special format method was designed to allow time-intensive code to execute before the print job begins. For instance, fax timeouts might be less likely if some data were processed before fax connection. However, there is no supported API to find the actual final printable area that you will have when the system opens the print format view and sends the viewSetupFormScript message. Although you may be tempted to access undocumented slots which contain information about printer and page settings, this is both unsupported and results in unreliable bounds. (For instance, the undocumented fax cover page information affects the printable area but it's not stored in the printer nor page size structures.)

On a related note, there are user configurations slots called paperSize and paperSizes. You cannot use these to reliably determine the printable area, nor can you create new paperSizes. See the Newton Programmer's Reference for more details.

You could hard-code a specific size of "main view" within your print format, but you do so at the risk of view clipping or other cosmetic problems if the actual printable area is too small in either dimension. For instance, you could determine a "lowest common denominator" page size for many printer/fax combinations, and then center a view of that size within the print format. You may waste some vertical/horizontal space if the page is larger and you still risk clipping the view if the printed page is smaller than expected. If you took this approach, you might consider registering multiple print formats that contained different page size/layout assumptions. We do not recommend hard-coding a specific page size, but it is appropriate for printing official forms whose size and design must be copied excactly.

We strongly recommend that most applications assume nothing about page size before printing occurs. During printing, get the page size by calling :LocalBox() in the print format viewSetupFormScript, viewSetupChildrenScript, or viewSetupDoneScript. (Or, use the print format pageHeight and pageWidth slots in viewSetupChildrenScript or later.) Also, add new child views with appropriate center/full/right/relative justification to take advantage of varying page sizes. This will allow your application to work with any paper size, in any printer, and in any locale.


CHANGED: Not All Drawing Modes Work with a PostScript Printer (7/16/97)

Q: It seems that not all drawing modes work with printing. Is that true?

A: Yes, at least this is true for PostScript printers. PostScript behaves like layers of paint: you can not go back and change something. Anything that uses an invert mode will not work. Specifically, modeXOR and modeNot will not work.

If you want to get the effect of white text on a black/filled background, use bit clear mode (modeBic) for drawing the text.

This does not affect non-PostScript print drivers, for instance, Apple StyleWriter printers and Fax.