Posted to tcl by emiliano at Sun Mar 22 11:56:33 GMT 2020view pretty

The canvas postscript command is somewhat underdocumented.

FONTMAP

The -fontmap option maps a font used in a canvas, such as the one get by 
    $canvas itemconfigure $textitem -font
with a pair
    [list $fontname $size]

This can fail for several reasons:

* the provided value is not a list
* the list length is != 2
* the font name is the empty string
* the font name has an space in it
* the size is not a valid double
* the size is <= 0

All these conditions are tested in Tk_PostscriptFont(), file generic/tkCanvPs.c

The postscript font name *should* match one of the 35 postscript level 2 fonts
(note that the font slant and weight are encoded in the font name)

    AvantGarde-Book
    AvantGarde-BookOblique
    AvantGarde-Demi
    AvantGarde-DemiOblique
    Bookman-Demi
    Bookman-DemiItalic
    Bookman-Light
    Bookman-LightItalic
    Courier
    Courier-Bold
    Courier-BoldOblique
    Courier-Oblique
    Helvetica
    Helvetica-Bold
    Helvetica-BoldOblique
    Helvetica-Narrow
    Helvetica-Narrow-Bold
    Helvetica-Narrow-BoldOblique
    Helvetica-Narrow-Oblique
    Helvetica-Oblique
    NewCenturySchlbk-Bold
    NewCenturySchlbk-BoldItalic
    NewCenturySchlbk-Italic
    NewCenturySchlbk-Roman
    Palatino-Bold
    Palatino-BoldItalic
    Palatino-Italic
    Palatino-Roman
    Symbol
    Times-Bold
    Times-BoldItalic
    Times-Italic
    Times-Roman
    ZapfChancery-MediumItalic
    ZapfDingbats

If -fontmap is not provided, or a given font is not found in the fontmap, then
a font name is "guessed" (Tk_PostscriptFontName() in generic/tkFont.c) from
a subset of the above list.

Example of use:

    canvas .c
    pack .c
    set item [.c create text 200 100 -text "Hello\nWorld"]
    update idletasks
    # replace the default font for Courier 12 on postscript output
    set fmap([.c itemcget $item -font]) [list Courier 12]
    set ps [.c postscript -fontmap fmap]

The following will raise errors when postscript is generated (see above for a
list of error conditions)

    # not a  list
    set fmap([.c itemcget $item -font]) "{"
    # list of lenght != 2
    set fmap([.c itemcget $item -font]) [list Courier 12 Bold]
    # font name empty
    set fmap([.c itemcget $item -font]) [list {} 12]
    # font name with space
    set fmap([.c itemcget $item -font]) [list {Courier New} 12]
    # size not a double
    set fmap([.c itemcget $item -font]) [list Courier Foo]
    # size <= 0
    set fmap([.c itemcget $item -font]) [list Courier -12]

The error produced is

    % catch {.c postscript -fontmap fmap} error options
    % set error
    bad font map entry for "TkDefaultFont": "{"
    % dict get $options -errorcode
    TK CANVAS PS FONTMAP
    % dict get $options -errorinfo
    bad font map entry for "TkDefaultFont": "{"
        (generating Postscript for item 1)
        invoked from within
    ".c postscript -fontmap fmap"
    %

WARNING: You can specify a nonexistent font and it will be used without further
checking. This font map

    set fmap([.c itemcget $item -font]) [list NONEXISTENT 12]

will produce an output but it *may* give an error at print or display time
(ghostscript provide fallback fonts).

COLORMAP

The -colormap option is similar to the -fontmap, with the difference there is
absolutely no checking of the value provided. As the documentation says, it
should map one of the colors provided to the canvas items via the 
-{active|disabled}*outline or -{active|disabled}*fill options with the
corresponding postscript code to get a given color in the format
[format {%f %f %f setrgbcolor} $red $green $blue]. The three components red,
green and blue must be in the range 0.0 - 1.0

Example:

    canvas .c
    pack .c
    set item [.c create text 200 100 -text "Hello\nWorld" -fill blue]
    update idletasks
    # convert "blue" to "green3" on postscript output
    set rgb [lmap val [winfo rgb .c "green3"] {expr {$val/65535.0}}]
    set cmap([.c itemcget $item -fill]) \
        [format {%.3f %.3f %.3f setrgbcolor} {*}$rgb]
    set ps [.c postscript -colormap cmap]

WARNING: You can specify anything in the color map and it will be used without 
further checking. Any invalid postscript code will raise an error at print or
display time. The following map

    set cmap([.c itemcget $item -fill]) "watch me crash!"

will cause an error at runtime.

Last but not least, you can use the same array for both -fontmap and -colormap
as long as there's no name clashes between fonts and colors.
The only way to get such clashes is using named fonts with names that are also
valid colors (as accepted by Tk_GetColor())

    font create blue -size 12
    font create #ff443c -size 12