15 Enhanced Special-Handling in 32-bit Edition
(First available in 4.0L.)
We have modified and enhanced the rendering calls to the
special() function of 32-bit special-handler DLL's.
While in WIN16 applications one can pass file stream pointers to DLL's, in
WIN32 this is not always possible.
Thus the ``f'' parameter (a FILE * pointer)
which DVIGDI32.EXE provides to special() handler functions
is modified as follows: this pointer will be NULL unless the '134special
text is lengthy (currently, ``lengthy'' means ³ 1024 characters), in
which case the pointer will be (on auction and rendering calls)
a memory-mapped pointer for the underlying DVI file.
That is, the handler function may use the pointer plus an offset between
offset to offset+total_len-1 to access the full text of a
lengthy '134special.
15.1 Accessing Memory-Mapped Special-Texts
Note also the following cautions:
- To make pointer of proper type, your handler must first cast the
pointer f (which has type ``FILE *'') to type ``LPVOID''.
-
This pointer value points to
the beginning of the DVI file, so you must add an offset of offset
to (LPVOID)f to point to the start of the '134special text.
-
The memory-mapped text is not
null-terminated, as is the case for the parameter text.
Handlers must take care to access the text from
(LPVOID)f+offset to (LPVOID)f+offset+total_len-1 only,
and must not rely on a null character termination for parsing.
-
DVIGDI32.EXE passes this memory-mapped pointer only for lengthy
'134special's. Typical '134special's are shorter than 1023 characters and will result
in (LPVOID)f being NULL.
This avoids the overhead of memory-mapping unless necessitated by the
rendering of a lengthy '134special.
-
The pointer is a read-only pointer.
Attempting to write to a pointed-to location will result in a WIN32 virtual
memory exception.
-
Liquidation calls now always send a NULL f.
Formerly this happened to be a valid FILE * stream pointer for the
DVI file.
-
Virtual fonts can themselves contain '134special's, and (unless lengthy) such
'134special's are indistinguishable to the handler.
In the case of a lengthy virtual font '134special,
DVIGDI32.EXE will not memory-map the underlying virtual font
file (that is, (LPVOID)f will always be NULL).
That is, a lengthy
'134special in a virtual font will result in a NULL value for f
although text_len<total_len. This makes lengthy '134special's in virtual fonts
accessible only in their first 1023 characters via the text parameter.
The path and name in such cases refers to the DVI file,
not the virtual font file, and thus is no help in locating the '134special text.
-
Special handlers must not retain pointers to data or (in WIN16) file streams
between calls.
These pointers are temporary and will become invalid if, for example, the
underlying DVI file is reformatted by another process.
-
There is a slight possibility of a race condition should
the underlying DVI file change (such as being reformatted
by another application from the .tex file) while a special handler
is rendering the text of a '134special.
Memory-mapping tends to insulate the text from such races, although there is
a slight possibility of a mixture of old and new text appearing in the same
special region if the total text was longer than a WIN32 virtual memory
page (for example, 4 KB in Windows 95).
Handlers should therefore strive to handle garbaged texts gracefully, since
an incomplete rendering in such circumstances is of no consequence.
This avoids the need for a complex (and non-TEX-standard)
file-locking and synchronization mechanism
between the TEX formatter and previewer processes.
-
On liquidation and closing calls the pointer ``f'' is now always
NULL.
15.2 Messages from special handlers
Formerly, '134special handlers have been prohibited from displaying message
boxes because they are called inside a previewer WM_PAINT.
One disadvantage to this limitation is that debugging handlers
is very difficult, since handlers cannot display debugging information
interactively.
A new feature in this release allows '134special handlers to pass texts to the
previewer for display in a message window.
The handler should #include the header file regmsg.h, and
then can send informational texts for display to the previewer via a message
to the document window with a statement similar to this:
| if (hWnd) SendMessage(hWnd,IPRINTF_MESSAGE,0, |
| (LPARAM)"spcolr: Hello"); |
where hWnd is the window handle passed to the special() function
in the '134special handler (that is, the second parameter to special).
(In WIN16 compilations, you will need to follow the cast to (LPARAM) with
a cast to (char far *) in small-model code.)
The previewer will display the string addressed by the LPARAM parameter.
Take care not to generate such messages on every rendering pass, since this
can result in numerous messages.