user921: I'm looking for software that can take FEN and generate a high-quality diagram, in PDF, Postscript, Windows metafile, or something else that will look good at 1200x1200 dpi or better. I thought the various chess engines would do it, but their diagrams are all bitmaps (as far as I can tell) and look like garbage when resized arbitrarily. Also, their own publishing export can’t be edited in anything standard, AFAICT. I am willing to pay.

user315: A vector format would suit.
As you may know, a vector format represents graphic not as a bitmap but geometrically, as a mathematical description which can be rendered at any scale.
For web display, you can use the SVG format. Here are some chessmen in the SVG format. (If you follow the link, for each chessman, click through to "original file (SVG file)." Until you click through, all you will get is a bitmapped, PNG approximation to the SVG. You want the real SVG.)
For PDF display, TeX has several packages you can use. Here is a list. (This is convenient only if you are familiar with TeX or LaTeX; but the resultant diagrams are good. For example, see p. 4 of this PDF example in the Skak style. Moreover, I believe that p. 4 of this PDF example shows the Schwalbe-chess style, which you might prefer, though its documentation seems to be all in German. All these are open source, at any rate.)

user15049: My solution has been to use a chess font like Chess Merida or Chess Cases.
With such a font for example the start position is written like this:
1222222223
4tMvWlVmT5
4OoOoOoOo5
4 + + + +5
4+ + + + 5
4 + + + +5
4+ + + + 5
4pPpPpPpP5
4RnBqKbNr5
7888888889

And (assuming the line-height is set to the height of the font) it looks like this (Here using Chess Merida as font):

So I wrote this Python script which converts from fen to this format. Call this script (assuming you named it fen2diag.py) with python fen2diag.py "<the fen>" and it prints out the diagram string.
import sys


def fen2diag(fen, borders=False):
    """
    Convert a fen to a diagram string used by fonts like
    'Chess Merida' and 'Chess Cases'.
    
    fen:        The fen. For example the fen for the startposition is
                'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'.
    borders:    If the returned diagram string shall have borders.
    
    Returns the diagram string.
    """

    # We dont need anything except the piece positions.
    fen = fen[:fen.find(' ')]

    # Transposition table for the black pieces.
    # White pieces are the same in both formats.
    t = {'k': 'l', 'q': 'w', 'r': 't', 'b': 'v', 'n': 'm', 'p': 'o'}

    # If the current square is a white square or not.
    w = False

    def todiagletter(fenletter):
        """"
        Return the diagram letter corresponding to the letter in the fen.
        """

        nonlocal borders, w
        w = not w
        if fenletter == '/':
            # In the diagram font these are the characters for the diagram borders:
            # '1' upper left, '2' upper, '3' upper right,
            # '4' left, '5' right,
            # '7' bottom left, '8' bottom, '9' bottom right
            return '5\n4' if borders else '\n'
        else:
            # this code handles numbers in the fen, denoting empty squares.
            try:
                # this is a number between 1 and 8.
                n = int(fenletter)

                # This will be a string denoting empty squares.
                # Would be eg. ' + + + +' for an empty eight rank.
                spaces = []

                while n > 0:
                    # In the diagram font ' ' denotes a white square
                    # and '+' denotes a black square.
                    spaces.append(' ' if w else '+')

                    w = not w
                    n -= 1
                w = not w
                return ''.join(spaces)

            # this code handles piece letters in the fen.
            except ValueError:
                # a black piece
                if fenletter in t:
                    fenletter = t[fenletter]

                # In the diagram font lowercase letters denote
                # pieces on white squares and uppercase letters
                # denote pieces on black squares.
                return fenletter.lower() if w else fenletter.upper()

    diagram = ''.join(map(todiagletter, fen))
    if borders:
        return f'1222222223\n4{diagram}5\n7888888889'
    else:
        return diagram


if __name__ == '__main__':
    print(fen2diag(sys.argv[1], borders=True))

These Diagram fonts also support squares marked with dots or stars, another type of border, round border corners, numbers/letters on the left/bottom borders denoting the rows/columns. I have not included this in the script. Feel free to update my code.
Chessbase has also made a font family (starting with 'DiagramTT...') which supports even more stuff (like pieces turned by 180°) but this font maps things to different code points, also for black squares two letters are taken, one for the background and one for the piece.

user11345: As thb pointed out, you need vectors. I suggest you use a python-chess to generate SVG vector images.
Prerequisites:

Python 2.6+ or 3.3+
Python-chess:


Install form pypi using pip: pip install python-chess[uci,gaviota]


Creating a script
Since you might need to generate multiple SVGs, let's create a script.  So, you can use the script to generate multiple chess boards easily. The following is written in Python 3.x. Create a Python script, FENtoSVG.py for example. Insert the following code:
import chess, sys
from chess import svg
'''
This imports python-chess module and sys module. 
Python-chess will generate the boards while sys.argv will take 
arguments for your script.
'''
svgstomake = (list(sys.argv))[1:]
for svgs in svgstomake:
    board = chess.Board(svgs)
    nameoffile = svgs.replace("/", "")+".SVG"
    boardsvg = chess.svg.board(board = board)
    filetowriteto = open(nameoffile, "w")
    filetowriteto.write(boardsvg)
    filetowriteto.close()

If you are on linux, start script with #!/usr/bin/env python3.
Usage
Now, this is a very simple script if you know python but I want to keep it simple for those who don't code. To use the script, open CMD/Terminal where you saved the script. Then, use as follows:
./FENtoSVG.py "examplefen" "morefen"
Say I want two SVGs for the FEN "8/8/8/8/4N3/8/8/8 w - - 0 1" and "8/8/8/8/4Q3/8/8/8 w - - 0 1"
, I would enter:
./FENtoSVG.py "8/8/8/8/4N3/8/8/8 w - - 0 1" "8/8/8/8/4Q3/8/8/8 w - - 0 1"
This would create two files: 88884N3888 w - - 0 1.SVG and 88884Q3888 w - - 0 1.SVG
I suggest python-chess because of the customizations that can be easily made to the diagram using built-in functions. It is also well documented.     

921: <p>I'm looking for software that can take FEN and generate a <em>high-quality</em> diagram, in PDF, Postscript, Windows metafile, or something else that will look good at 1200x1200 dpi or better. I thought the various chess engines would do it, but their diagrams are all bitmaps (as far as I can tell) and look like garbage when resized arbitrarily. Also, their own publishing export can’t be edited in anything standard, AFAICT. I am willing to pay.</p>
 315: <p>A <em>vector format</em> would suit.</p>

<p>As you may know, a vector format represents graphic not as a bitmap but geometrically, as a mathematical description which can be rendered at any scale.</p>

<p>For web display, you can use the SVG format. <a href="https://commons.wikimedia.org/wiki/Template:SVG_chess_pieces" rel="nofollow">Here</a> are some chessmen in the SVG format. (If you follow the link, for each chessman, click through to "original file (SVG file)." Until you click through, all you will get is a bitmapped, PNG approximation to the SVG. You want the real SVG.)</p>

<p>For PDF display, TeX has several packages you can use. <a href="https://packages.debian.org/sid/tex/texlive-games" rel="nofollow">Here</a> is a list. (This is convenient only if you are familiar with TeX or LaTeX; but the resultant diagrams are good. For example, see p. 4 of <a href="http://wikitex.org/doc/skakdoc.pdf" rel="nofollow">this PDF example</a> in the Skak style. Moreover, I believe that p. 4 of <a href="http://www.accademiadelproblema.org/archivio/RIVISTE/Estero/HARMONIE-AKTIV/2014/h122.pdf" rel="nofollow">this PDF example</a> shows the Schwalbe-chess style, which you might prefer, though its documentation seems to be all in German. All these are open source, at any rate.)</p>
 15049: <p>My solution has been to use a chess font like <em>Chess Merida</em> or <em>Chess Cases</em>.</p>
<p>With such a font for example the start position is written like this:</p>
<pre><code>1222222223
4tMvWlVmT5
4OoOoOoOo5
4 + + + +5
4+ + + + 5
4 + + + +5
4+ + + + 5
4pPpPpPpP5
4RnBqKbNr5
7888888889
</code></pre>
<p>And (assuming the line-height is set to the height of the font) it looks like this (Here using <em>Chess Merida</em> as font):</p>
<p><a href="https://i.stack.imgur.com/JWVrq.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/JWVrq.png" alt="enter image description here" /></a></p>
<p>So I wrote this Python script which converts from fen to this format. Call this script (assuming you named it <em>fen2diag.py</em>) with <code>python fen2diag.py &quot;&lt;the fen&gt;&quot;</code> and it prints out the diagram string.</p>
<pre><code>import sys


def fen2diag(fen, borders=False):
    &quot;&quot;&quot;
    Convert a fen to a diagram string used by fonts like
    'Chess Merida' and 'Chess Cases'.
    
    fen:        The fen. For example the fen for the startposition is
                'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'.
    borders:    If the returned diagram string shall have borders.
    
    Returns the diagram string.
    &quot;&quot;&quot;

    # We dont need anything except the piece positions.
    fen = fen[:fen.find(' ')]

    # Transposition table for the black pieces.
    # White pieces are the same in both formats.
    t = {'k': 'l', 'q': 'w', 'r': 't', 'b': 'v', 'n': 'm', 'p': 'o'}

    # If the current square is a white square or not.
    w = False

    def todiagletter(fenletter):
        &quot;&quot;&quot;&quot;
        Return the diagram letter corresponding to the letter in the fen.
        &quot;&quot;&quot;

        nonlocal borders, w
        w = not w
        if fenletter == '/':
            # In the diagram font these are the characters for the diagram borders:
            # '1' upper left, '2' upper, '3' upper right,
            # '4' left, '5' right,
            # '7' bottom left, '8' bottom, '9' bottom right
            return '5\n4' if borders else '\n'
        else:
            # this code handles numbers in the fen, denoting empty squares.
            try:
                # this is a number between 1 and 8.
                n = int(fenletter)

                # This will be a string denoting empty squares.
                # Would be eg. ' + + + +' for an empty eight rank.
                spaces = []

                while n &gt; 0:
                    # In the diagram font ' ' denotes a white square
                    # and '+' denotes a black square.
                    spaces.append(' ' if w else '+')

                    w = not w
                    n -= 1
                w = not w
                return ''.join(spaces)

            # this code handles piece letters in the fen.
            except ValueError:
                # a black piece
                if fenletter in t:
                    fenletter = t[fenletter]

                # In the diagram font lowercase letters denote
                # pieces on white squares and uppercase letters
                # denote pieces on black squares.
                return fenletter.lower() if w else fenletter.upper()

    diagram = ''.join(map(todiagletter, fen))
    if borders:
        return f'1222222223\n4{diagram}5\n7888888889'
    else:
        return diagram


if __name__ == '__main__':
    print(fen2diag(sys.argv[1], borders=True))
</code></pre>
<p>These Diagram fonts also support squares marked with dots or stars, another type of border, round border corners, numbers/letters on the left/bottom borders denoting the rows/columns. I have not included this in the script. Feel free to update my code.</p>
<p>Chessbase has also made a font family (starting with 'DiagramTT...') which supports even more stuff (like pieces turned by 180°) but this font maps things to different code points, also for black squares two letters are taken, one for the background and one for the piece.</p>
 11345: <p>As thb pointed out, you need vectors. I suggest you use a python-chess to generate SVG vector images.</p>

<h2>Prerequisites:</h2>

<ol>
<li><a href="http://www.python.org" rel="noreferrer">Python</a> 2.6+ or 3.3+</li>
<li><a href="https://pypi.python.org/pypi/python-chess#installing" rel="noreferrer">Python-chess</a>:

<ul>
<li>Install form <a href="https://pypi.python.org/pypi/python-chess#installing" rel="noreferrer">pypi</a> using pip: <code>pip install python-chess[uci,gaviota]</code></li>
</ul></li>
</ol>

<h2>Creating a script</h2>

<p>Since you might need to generate multiple SVGs, let's create a script.  So, you can use the script to generate multiple chess boards easily. The following is written in Python 3.x. Create a Python script, FENtoSVG.py for example. Insert the following code:</p>

<pre><code>import chess, sys
from chess import svg
'''
This imports python-chess module and sys module. 
Python-chess will generate the boards while sys.argv will take 
arguments for your script.
'''
svgstomake = (list(sys.argv))[1:]
for svgs in svgstomake:
    board = chess.Board(svgs)
    nameoffile = svgs.replace("/", "")+".SVG"
    boardsvg = chess.svg.board(board = board)
    filetowriteto = open(nameoffile, "w")
    filetowriteto.write(boardsvg)
    filetowriteto.close()
</code></pre>

<p>If you are on linux, start script with <code>#!/usr/bin/env python3</code>.</p>

<h2>Usage</h2>

<p>Now, this is a very simple script if you know python but I want to keep it simple for those who don't code. To use the script, open CMD/Terminal where you saved the script. Then, use as follows:</p>

<p><code>./FENtoSVG.py "examplefen" "morefen"</code></p>

<p>Say I want two SVGs for the FEN <code>"8/8/8/8/4N3/8/8/8 w - - 0 1"</code> and <code>"8/8/8/8/4Q3/8/8/8 w - - 0 1"</code>
, I would enter:</p>

<p><code>./FENtoSVG.py "8/8/8/8/4N3/8/8/8 w - - 0 1" "8/8/8/8/4Q3/8/8/8 w - - 0 1"</code></p>

<p>This would create two files: <code>88884N3888 w - - 0 1.SVG</code> and <code>88884Q3888 w - - 0 1.SVG</code></p>

<p>I suggest python-chess because of the customizations that can be easily made to the diagram using built-in functions. It is also well documented.     </p>
