5

Is there a satisfactory way to use the current fonts' arrow tips in TikZ diagrams? I'm using LuaLatex with fontspec and unicode-math packages to select STIX Two fonts, and the arrow tips look very different from the ones used in TikZ diagrams.

Google-ing leads me to believe that there is no 'supported' way to do this (yet), but maybe someone here has something that mostly works?

3
  • 1
    The way I've done things like this is by making a tikz arrow head. It's pretty annoying though -- I do this by zooming way in on the character and taking a screenshot, guessing Bezier curves that closely approximate the arrow head, and then following the instructions for defining tikz arrow heads on pages 1015--1024 of the tikz manual. Oct 18, 2017 at 18:11
  • 1
    I was afraid that this was going to be the only solution. Since you wrote "things like this," I assume you have not done this for STIX arrow heads? I'm still hoping someone already did this and is willing to share :-)
    – 1k5
    Oct 18, 2017 at 19:11
  • 2
    @egreg's Answer half answers my question. Most of my diagrams are actually in tikz-cd, however some are in pure TikZ. Is there a simple way to do those \draw[->] (0,0) -- (1,1) tips too?
    – 1k5
    Oct 19, 2017 at 13:49

2 Answers 2

6

Use arrow style=math font (section 2.2 in the manual of tikz-cd):

\documentclass{article}
\usepackage{amsmath}
\usepackage{unicode-math}
\usepackage{tikz-cd}

\setmainfont{STIX Two Text}
\setmathfont{STIX Two Math}

\tikzcdset{arrow style=math font}

\begin{document}

\[
a\to b \qquad
\begin{tikzcd}
a \arrow[r] \arrow[dr] & b \arrow[d] \\
& c
\end{tikzcd}
\]

\end{document}

enter image description here

2
  • 1
    Thanks! I'm a little embarrassed that I didn't find this myself. At first glance, this method seems to work for some arrows and not (or not quite right) for others. For example: (1) In some of my diagrams arrows to the right have the STIX tip, while arrows to the left have the default TikZ tips. (2) Dotted lines have a short solid part near both ends now. (3) Some two-headed arrows don't work, others do. (4) Left-right arrows don't seem to work. --- I'll have a closer look tomorrow. I think I can make this work well enough for my purpose.
    – 1k5
    Oct 18, 2017 at 22:37
  • 1
    Some more remarks: It seems that default arrows as well as arrows specified by name work (e.g. \ar[r], \ar[d,two heads], \ar[l,hookrightarrow].) What doesn't work is e.g. \ar[r,->], \ar[r,->>], or \ar[u,<->], and by doesn't work I mean these will still use default TikZ arrow tips. The issue with dotted lines remains.
    – 1k5
    Oct 19, 2017 at 13:27
6

This answer may be a little late for your intended application, but I happen to have recreated the STIX Two Math arrowhead in TikZ. You're free to use it if you still need it.

Instead of staring at a screenshot of the original arrowheads and guessing the positions of control points, I opened STIX2Math.otf in FontForge and looked up their exact coordinates. (By which actually I mean that I exported these arrows to .eps files and used those instead.) They should therefore match the original arrowheads nearly exactly.

I don't think there is much to explain, so I'll just paste the code below:

\documentclass{article}

%% Font setup:
\usepackage{ifluatex,ifxetex}
\ifluatex  %% lualatex
  \usepackage{fontspec,unicode-math}
  \setmainfont{STIX Two Text}
  \setmathfont{STIX Two Math}
\else
  \ifxetex %% xelatex
  \usepackage{fontspec,unicode-math}
    \setmainfont{STIX2Text-Regular.otf}[
      BoldFont       = STIX2Text-Bold.otf,
      ItalicFont     = STIX2Text-Italic.otf,
      BoldItalicFont = STIX2Text-BoldItalic.otf  ]
    \setmathfont{STIX2Math.otf}
  \else    %% (pdf)latex, presumably
    \usepackage{stix2}
  \fi
\fi

\usepackage{tikz}

%% Arrow declaration:
\makeatletter
\pgfdeclarearrow{
  name = stix,
  parameters = {\ifpgfarrowharpoon h\fi},
  setup code = {
    \ifpgfarrowharpoon
      \pgfutil@tempdima=\dimexpr\pgflinewidth/68
      \pgfarrowssettipend{247\pgfutil@tempdima}
      \pgfarrowssetlineend{\pgfutil@tempdima}
      \pgfarrowssetbackend{-81\pgfutil@tempdima}
      \pgfarrowshullpoint{-81\pgfutil@tempdima}{224\pgfutil@tempdima}
      \pgfarrowshullpoint{-58\pgfutil@tempdima}{247\pgfutil@tempdima}
      \pgfarrowshullpoint{247\pgfutil@tempdima}{-34\pgfutil@tempdima}
      \pgfarrowshullpoint{0pt}{-34\pgfutil@tempdima}
    \else\ifpgfarrowreversed
      \pgfutil@tempdima=\dimexpr\pgflinewidth/68
      \pgfarrowssettipend{0pt}
      \pgfarrowssetlineend{-\pgfutil@tempdima}
      \pgfarrowssetbackend{-208\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-208\pgfutil@tempdima}{181\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-188\pgfutil@tempdima}{201\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{0pt}{34\pgfutil@tempdima}
    \else\ifdim\pgfinnerlinewidth>\z@
      \pgfutil@tempdima=\dimexpr\pgflinewidth/272
      \pgfarrowssettipend{324\pgfutil@tempdima}
      \pgfarrowssetlineend{\pgfutil@tempdima}
      \pgfarrowssetbackend{-73\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-73\pgfutil@tempdima}{285\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-51\pgfutil@tempdima}{305\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{324\pgfutil@tempdima}{5\pgfutil@tempdima}
    \else
      \pgfutil@tempdima=\dimexpr\pgflinewidth/68
      \pgfarrowssettipend{192\pgfutil@tempdima}
      \pgfarrowssetlineend{\pgfutil@tempdima}
      \pgfarrowssetbackend{-72\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-72\pgfutil@tempdima}{181\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-51\pgfutil@tempdima}{201\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-192\pgfutil@tempdima}{5\pgfutil@tempdima}
    \fi\fi\fi
  },
  drawing code = {
    \ifpgfarrowharpoon %% harpoon
      \pgftransformscale{\pgflinewidth/68}
      \pgfpathmoveto{\pgfpoint{0}{34}}
      \pgfpathcurveto{\pgfpoint{40}{34}}{\pgfpoint{44}{50}}{\pgfpoint{44}{66}}
      \pgfpathcurveto{\pgfpoint{44}{94}}{\pgfpoint{-22}{156}}{\pgfpoint{-81}{224}}
      \pgfpathlineto{\pgfpoint{-58}{247}}
      \pgfpathcurveto{\pgfpoint{44}{147}}{\pgfpoint{117}{66}}{\pgfpoint{247}{-30}}
      \pgfpathlineto{\pgfpoint{247}{-34}}
      \pgfpathlineto{\pgfpoint{0}{-34}}
      \pgfpathclose
      \pgfusepathqfill
    \else\ifpgfarrowreversed %% reversed arrowhead
      \pgftransformscale{\pgflinewidth/68}
      \pgfpathmoveto{\pgfpoint{0}{34}}
      \pgfpathcurveto{\pgfpoint{-73}{78}}{\pgfpoint{-134}{138}}{\pgfpoint{-188}{201}}
      \pgfpathlineto{\pgfpoint{-208}{181}}
      \pgfpathcurveto{\pgfpoint{-185}{147}}{\pgfpoint{-152}{118}}{\pgfpoint{-124}{83}}
      \pgfpathcurveto{\pgfpoint{-111}{65}}{\pgfpoint{-95}{33}}{\pgfpoint{-95}{0}}
      \pgfpathcurveto{\pgfpoint{-95}{-33}}{\pgfpoint{-111}{-65}}{\pgfpoint{-124}{-83}}
      \pgfpathcurveto{\pgfpoint{-152}{-118}}{\pgfpoint{-185}{-147}}{\pgfpoint{-208}{-181}}
      \pgfpathlineto{\pgfpoint{-188}{-201}}
      \pgfpathcurveto{\pgfpoint{-134}{-138}}{\pgfpoint{-73}{-78}}{\pgfpoint{0}{-34}}
      \pgfpathclose
      \pgfusepathqfill
    \else\ifdim\pgfinnerlinewidth>\z@ %% double arrow
      \pgftransformscale{\pgflinewidth/272}
      \pgfpathmoveto{\pgfpoint{0}{136}}
      \pgfpathcurveto{\pgfpoint{18}{136}}{\pgfpoint{27}{151}}{\pgfpoint{27}{159}}
      \pgfpathcurveto{\pgfpoint{27}{175}}{\pgfpoint{20}{184}}{\pgfpoint{3}{202}}
      \pgfpathcurveto{\pgfpoint{-8}{213}}{\pgfpoint{-48}{256}}{\pgfpoint{-73}{285}}
      \pgfpathlineto{\pgfpoint{-51}{305}}
      \pgfpathcurveto{\pgfpoint{69}{187}}{\pgfpoint{198}{100}}{\pgfpoint{324}{5}}
      \pgfpathlineto{\pgfpoint{324}{-5}}
      \pgfpathcurveto{\pgfpoint{198}{-100}}{\pgfpoint{69}{-187}}{\pgfpoint{-51}{-305}}
      \pgfpathlineto{\pgfpoint{-73}{-285}}
      \pgfpathcurveto{\pgfpoint{-48}{-256}}{\pgfpoint{-8}{-213}}{\pgfpoint{3}{-202}}
      \pgfpathcurveto{\pgfpoint{20}{-184}}{\pgfpoint{27}{-175}}{\pgfpoint{27}{-159}}
      \pgfpathcurveto{\pgfpoint{27}{-151}}{\pgfpoint{18}{-136}}{\pgfpoint{0}{-136}}
      \pgftransformreset
      \pgfpathlineto{\pgfpoint{0}{-.5*\pgfinnerlinewidth}}
      \pgftransformxshift{208\pgflinewidth/272}
      \pgftransformscale{\pgfinnerlinewidth/136}
      \pgfpathlineto{\pgfpoint{-61}{-68}}
      \pgfpathcurveto{\pgfpoint{-27}{-49}}{\pgfpoint{0}{-24}}{\pgfpoint{0}{0}}
      \pgfpathcurveto{\pgfpoint{0}{24}}{\pgfpoint{-27}{49}}{\pgfpoint{-61}{68}}
      \pgftransformreset
      \pgfpathlineto{\pgfpoint{0}{.5*\pgfinnerlinewidth}}
      \pgfpathclose
      \pgfusepathqfill
    \else %% normal arrowhead
      \pgftransformscale{\pgflinewidth/68}
      \pgfpathmoveto{\pgfpoint{0}{34}}
      \pgfpathcurveto{\pgfpoint{18}{34}}{\pgfpoint{26}{44}}{\pgfpoint{26}{54}}
      \pgfpathcurveto{\pgfpoint{26}{63}}{\pgfpoint{21}{74}}{\pgfpoint{12}{83}}
      \pgfpathcurveto{\pgfpoint{-19}{115}}{\pgfpoint{-48}{148}}{\pgfpoint{-72}{181}}
      \pgfpathlineto{\pgfpoint{-51}{201}}
      \pgfpathcurveto{\pgfpoint{16}{123}}{\pgfpoint{94}{47}}{\pgfpoint{192}{5}}
      \pgfpathlineto{\pgfpoint{192}{-5}}
      \pgfpathcurveto{\pgfpoint{94}{-47}}{\pgfpoint{16}{-123}}{\pgfpoint{-51}{-201}}
      \pgfpathlineto{\pgfpoint{-72}{-181}}
      \pgfpathcurveto{\pgfpoint{-48}{-148}}{\pgfpoint{-19}{-115}}{\pgfpoint{12}{-83}}
      \pgfpathcurveto{\pgfpoint{21}{-74}}{\pgfpoint{26}{-63}}{\pgfpoint{26}{-54}}
      \pgfpathcurveto{\pgfpoint{26}{-44}}{\pgfpoint{18}{-34}}{\pgfpoint{0}{-34}}
      \pgfpathclose
      \pgfusepathqfill
    \fi\fi\fi
  }
}
\pgfdeclarearrow{
  name = stixhooks,
  parameters = {\ifpgfarrowharpoon h\fi},
  setup code = {
    \pgfutil@tempdima=\dimexpr\pgflinewidth/68
    \pgfarrowssettipend{184\pgfutil@tempdima}
    \pgfarrowssetlineend{\pgfutil@tempdima}
    \pgfarrowssetbackend{-79\pgfutil@tempdima}
    \pgfarrowsupperhullpoint{-79\pgfutil@tempdima}{307\pgfutil@tempdima}
    \pgfarrowsupperhullpoint{184\pgfutil@tempdima}{136\pgfutil@tempdima}
    \ifpgfarrowharpoon\pgfarrowshullpoint{0pt}{-34\pgfutil@tempdima}\fi
  },
  drawing code = {
    \pgftransformscale{\pgflinewidth/68}
    \ifpgfarrowharpoon\else %% double-sidded
      \pgfpathmoveto{\pgfpoint{0}{-34}}
      \pgfpathcurveto{\pgfpoint{61}{-34}}{\pgfpoint{117}{-68}}{\pgfpoint{117}{-135}}
      \pgfpathcurveto{\pgfpoint{117}{-197}}{\pgfpoint{79}{-239}}{\pgfpoint{18}{-239}}
      \pgfpathlineto{\pgfpoint{-79}{-239}}
      \pgfpathlineto{\pgfpoint{-79}{-307}}
      \pgfpathlineto{\pgfpoint{21}{-307}}
      \pgfpathcurveto{\pgfpoint{99}{-307}}{\pgfpoint{184}{-245}}{\pgfpoint{184}{-136}}
      \pgfpathcurveto{\pgfpoint{184}{-20}}{\pgfpoint{80}{34}}{\pgfpoint{0}{34}}
      \pgfpathclose
      \pgfusepathqfill
    \fi
    \pgfpathmoveto{\pgfpoint{0}{34}}
    \pgfpathcurveto{\pgfpoint{61}{34}}{\pgfpoint{117}{68}}{\pgfpoint{117}{135}}
    \pgfpathcurveto{\pgfpoint{117}{197}}{\pgfpoint{79}{239}}{\pgfpoint{18}{239}}
    \pgfpathlineto{\pgfpoint{-79}{239}}
    \pgfpathlineto{\pgfpoint{-79}{307}}
    \pgfpathlineto{\pgfpoint{21}{307}}
    \pgfpathcurveto{\pgfpoint{99}{307}}{\pgfpoint{184}{245}}{\pgfpoint{184}{136}}
    \pgfpathcurveto{\pgfpoint{184}{20}}{\pgfpoint{84}{-34}}{\pgfpoint{4}{-34}}
    \pgfpathclose
    \pgfusepathqfill
  }
}
\makeatother

%% For the Bar arrowhead stlye
\usetikzlibrary{arrows.meta}

%% STIX arrows have a line width of exactly 0.68em:
\tikzset{every picture/.style={line width=.068em}}

%% Set up arrowheads:
\tikzset{>=stix,
         |/.tip={Bar[width=.403em,line width=.052em]},
         lefthook/.tip={stixhooks[left]},
         righthook/.tip={stixhooks[right]},
         leftharpoon/.tip={>[left]},
         rightharpoon/.tip={>[right]}
}

%% For testing purposes:
%% This prints $#2$ and a Tikz arrow with head #3 of length #1
%% Then it prints the latter overlayed on the former
\newcommand*\stixtest[3][.805em]{%
  $#2$
  &
  $\vcenter{\hbox{$\tikz{
    \useasboundingbox (0,0) -- (#1,0);
    \draw[#3] (0,0) -- (#1,0);
  }$}}$
  &
  \ooalign{\hfil$#2$\hfil\cr\hfil
      $\vcenter{\hbox{$\tikz[transparency group,opacity=.5]{
        \useasboundingbox (0,0) -- (#1,0);
        \draw[#3,red] (0,0) -- (#1,0);
      }$}}$\hfil}
}

\begin{document}

\renewcommand\arraystretch{0} %% <- reduce space between rows
\begin{tabular}{c@{}c@{}c}
\stixtest[.805em]{\rightarrow}{->}
\\ %% \hskip below is necessary because \Rightarrow has uneven spacing
\stixtest[.826em]{\hskip.041em\Rightarrow}{->,double distance=2\pgflinewidth}
\\
\stixtest[.867em]{\rightharpoonup}{-leftharpoon}
\\
\stixtest[.805em]{\mapsto}{|->}
\\
\stixtest[.805em]{\rightarrowtail}{>->}
\\
\stixtest[.805em]{\hookrightarrow}{righthook->}
\end{tabular}

\end{document}

The table in the output, which I've inserted below, shows the arrows from the STIX Two Math font on the left and the corresponding TikZ arrow in the middle. In the rightmost column I've overlayed the latter on top of the former (in red, at 50% opacity).

Arrows!

A few notes

  • The arrows from the STIX Two Math font have a line width of exactly 0.068em (= 0.68pt at 10pt), which is why I included the line \tikzset{every picture/.style={line width=.068em}}. If you use a different line width, all arrowheads would be scaled accordingly.

  • To get the double arrow right you should use [->,double distance=2\pgflinewidth], as I've done above. Other distances also work, but they won't resemble the \Rightarrow glyph. (The minuscule lines at the ends of the double lines are rendering artefacts caused by the fact that TikZ draws double lines by drawing a white line on top of a thicker black line. They should not appear in print.)

  • I've had to make a separate stixhooks arrowhead style because the STIX Two \hookrightarrow glyph has a different hook than any that can be created using the Hooks arrowhead from the arrows.meta library.

  • Don't combine arrow styles: an arrowhead can either be doubled, harpooned or reversed, but these styles cannot currently be combined.

  • Since it is rather long, you may want to put (parts of) this preamble in a separate .tex file and \input it (or in a .sty file, so you can \usepackage it).

Demonstration

As a demonstration, I've defiled a nice diagram by modifying some of its arrows.

\documentclass{article}

%% Font setup:
\usepackage{ifluatex,ifxetex}
\ifluatex  %% lualatex
  \usepackage{fontspec,unicode-math}
  \setmainfont{STIX Two Text}
  \setmathfont{STIX Two Math}
\else
  \ifxetex %% xelatex
  \usepackage{fontspec,unicode-math}
    \setmainfont{STIX2Text-Regular.otf}[
      BoldFont       = STIX2Text-Bold.otf,
      ItalicFont     = STIX2Text-Italic.otf,
      BoldItalicFont = STIX2Text-BoldItalic.otf  ]
    \setmathfont{STIX2Math.otf}
  \else    %% (pdf)latex, presumably
    \usepackage{stix2}
  \fi
\fi

\usepackage{tikz}

%% Arrow declaration:
\makeatletter
\pgfdeclarearrow{
  name = stix,
  parameters = {\ifpgfarrowharpoon h\fi},
  setup code = {
    \ifpgfarrowharpoon
      \pgfutil@tempdima=\dimexpr\pgflinewidth/68
      \pgfarrowssettipend{247\pgfutil@tempdima}
      \pgfarrowssetlineend{\pgfutil@tempdima}
      \pgfarrowssetbackend{-81\pgfutil@tempdima}
      \pgfarrowshullpoint{-81\pgfutil@tempdima}{224\pgfutil@tempdima}
      \pgfarrowshullpoint{-58\pgfutil@tempdima}{247\pgfutil@tempdima}
      \pgfarrowshullpoint{247\pgfutil@tempdima}{-34\pgfutil@tempdima}
      \pgfarrowshullpoint{0pt}{-34\pgfutil@tempdima}
    \else\ifpgfarrowreversed
      \pgfutil@tempdima=\dimexpr\pgflinewidth/68
      \pgfarrowssettipend{0pt}
      \pgfarrowssetlineend{-\pgfutil@tempdima}
      \pgfarrowssetbackend{-208\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-208\pgfutil@tempdima}{181\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-188\pgfutil@tempdima}{201\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{0pt}{34\pgfutil@tempdima}
    \else\ifdim\pgfinnerlinewidth>\z@
      \pgfutil@tempdima=\dimexpr\pgflinewidth/272
      \pgfarrowssettipend{324\pgfutil@tempdima}
      \pgfarrowssetlineend{\pgfutil@tempdima}
      \pgfarrowssetbackend{-73\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-73\pgfutil@tempdima}{285\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-51\pgfutil@tempdima}{305\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{324\pgfutil@tempdima}{5\pgfutil@tempdima}
    \else
      \pgfutil@tempdima=\dimexpr\pgflinewidth/68
      \pgfarrowssettipend{192\pgfutil@tempdima}
      \pgfarrowssetlineend{\pgfutil@tempdima}
      \pgfarrowssetbackend{-72\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-72\pgfutil@tempdima}{181\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-51\pgfutil@tempdima}{201\pgfutil@tempdima}
      \pgfarrowsupperhullpoint{-192\pgfutil@tempdima}{5\pgfutil@tempdima}
    \fi\fi\fi
  },
  drawing code = {
    \ifpgfarrowharpoon %% harpoon
      \pgftransformscale{\pgflinewidth/68}
      \pgfpathmoveto{\pgfpoint{0}{34}}
      \pgfpathcurveto{\pgfpoint{40}{34}}{\pgfpoint{44}{50}}{\pgfpoint{44}{66}}
      \pgfpathcurveto{\pgfpoint{44}{94}}{\pgfpoint{-22}{156}}{\pgfpoint{-81}{224}}
      \pgfpathlineto{\pgfpoint{-58}{247}}
      \pgfpathcurveto{\pgfpoint{44}{147}}{\pgfpoint{117}{66}}{\pgfpoint{247}{-30}}
      \pgfpathlineto{\pgfpoint{247}{-34}}
      \pgfpathlineto{\pgfpoint{0}{-34}}
      \pgfpathclose
      \pgfusepathqfill
    \else\ifpgfarrowreversed %% reversed arrowhead
      \pgftransformscale{\pgflinewidth/68}
      \pgfpathmoveto{\pgfpoint{0}{34}}
      \pgfpathcurveto{\pgfpoint{-73}{78}}{\pgfpoint{-134}{138}}{\pgfpoint{-188}{201}}
      \pgfpathlineto{\pgfpoint{-208}{181}}
      \pgfpathcurveto{\pgfpoint{-185}{147}}{\pgfpoint{-152}{118}}{\pgfpoint{-124}{83}}
      \pgfpathcurveto{\pgfpoint{-111}{65}}{\pgfpoint{-95}{33}}{\pgfpoint{-95}{0}}
      \pgfpathcurveto{\pgfpoint{-95}{-33}}{\pgfpoint{-111}{-65}}{\pgfpoint{-124}{-83}}
      \pgfpathcurveto{\pgfpoint{-152}{-118}}{\pgfpoint{-185}{-147}}{\pgfpoint{-208}{-181}}
      \pgfpathlineto{\pgfpoint{-188}{-201}}
      \pgfpathcurveto{\pgfpoint{-134}{-138}}{\pgfpoint{-73}{-78}}{\pgfpoint{0}{-34}}
      \pgfpathclose
      \pgfusepathqfill
    \else\ifdim\pgfinnerlinewidth>\z@ %% double arrow
      \pgftransformscale{\pgflinewidth/272}
      \pgfpathmoveto{\pgfpoint{0}{136}}
      \pgfpathcurveto{\pgfpoint{18}{136}}{\pgfpoint{27}{151}}{\pgfpoint{27}{159}}
      \pgfpathcurveto{\pgfpoint{27}{175}}{\pgfpoint{20}{184}}{\pgfpoint{3}{202}}
      \pgfpathcurveto{\pgfpoint{-8}{213}}{\pgfpoint{-48}{256}}{\pgfpoint{-73}{285}}
      \pgfpathlineto{\pgfpoint{-51}{305}}
      \pgfpathcurveto{\pgfpoint{69}{187}}{\pgfpoint{198}{100}}{\pgfpoint{324}{5}}
      \pgfpathlineto{\pgfpoint{324}{-5}}
      \pgfpathcurveto{\pgfpoint{198}{-100}}{\pgfpoint{69}{-187}}{\pgfpoint{-51}{-305}}
      \pgfpathlineto{\pgfpoint{-73}{-285}}
      \pgfpathcurveto{\pgfpoint{-48}{-256}}{\pgfpoint{-8}{-213}}{\pgfpoint{3}{-202}}
      \pgfpathcurveto{\pgfpoint{20}{-184}}{\pgfpoint{27}{-175}}{\pgfpoint{27}{-159}}
      \pgfpathcurveto{\pgfpoint{27}{-151}}{\pgfpoint{18}{-136}}{\pgfpoint{0}{-136}}
      \pgftransformreset
      \pgfpathlineto{\pgfpoint{0}{-.5*\pgfinnerlinewidth}}
      \pgftransformxshift{208\pgflinewidth/272}
      \pgftransformscale{\pgfinnerlinewidth/136}
      \pgfpathlineto{\pgfpoint{-61}{-68}}
      \pgfpathcurveto{\pgfpoint{-27}{-49}}{\pgfpoint{0}{-24}}{\pgfpoint{0}{0}}
      \pgfpathcurveto{\pgfpoint{0}{24}}{\pgfpoint{-27}{49}}{\pgfpoint{-61}{68}}
      \pgftransformreset
      \pgfpathlineto{\pgfpoint{0}{.5*\pgfinnerlinewidth}}
      \pgfpathclose
      \pgfusepathqfill
    \else %% normal arrowhead
      \pgftransformscale{\pgflinewidth/68}
      \pgfpathmoveto{\pgfpoint{0}{34}}
      \pgfpathcurveto{\pgfpoint{18}{34}}{\pgfpoint{26}{44}}{\pgfpoint{26}{54}}
      \pgfpathcurveto{\pgfpoint{26}{63}}{\pgfpoint{21}{74}}{\pgfpoint{12}{83}}
      \pgfpathcurveto{\pgfpoint{-19}{115}}{\pgfpoint{-48}{148}}{\pgfpoint{-72}{181}}
      \pgfpathlineto{\pgfpoint{-51}{201}}
      \pgfpathcurveto{\pgfpoint{16}{123}}{\pgfpoint{94}{47}}{\pgfpoint{192}{5}}
      \pgfpathlineto{\pgfpoint{192}{-5}}
      \pgfpathcurveto{\pgfpoint{94}{-47}}{\pgfpoint{16}{-123}}{\pgfpoint{-51}{-201}}
      \pgfpathlineto{\pgfpoint{-72}{-181}}
      \pgfpathcurveto{\pgfpoint{-48}{-148}}{\pgfpoint{-19}{-115}}{\pgfpoint{12}{-83}}
      \pgfpathcurveto{\pgfpoint{21}{-74}}{\pgfpoint{26}{-63}}{\pgfpoint{26}{-54}}
      \pgfpathcurveto{\pgfpoint{26}{-44}}{\pgfpoint{18}{-34}}{\pgfpoint{0}{-34}}
      \pgfpathclose
      \pgfusepathqfill
    \fi\fi\fi
  }
}
\pgfdeclarearrow{
  name = stixhooks,
  parameters = {\ifpgfarrowharpoon h\fi},
  setup code = {
    \pgfutil@tempdima=\dimexpr\pgflinewidth/68
    \pgfarrowssettipend{184\pgfutil@tempdima}
    \pgfarrowssetlineend{\pgfutil@tempdima}
    \pgfarrowssetbackend{-79\pgfutil@tempdima}
    \pgfarrowsupperhullpoint{-79\pgfutil@tempdima}{307\pgfutil@tempdima}
    \pgfarrowsupperhullpoint{184\pgfutil@tempdima}{136\pgfutil@tempdima}
    \ifpgfarrowharpoon\pgfarrowshullpoint{0pt}{-34\pgfutil@tempdima}\fi
  },
  drawing code = {
    \pgftransformscale{\pgflinewidth/68}
    \ifpgfarrowharpoon\else %% double-sidded
      \pgfpathmoveto{\pgfpoint{0}{-34}}
      \pgfpathcurveto{\pgfpoint{61}{-34}}{\pgfpoint{117}{-68}}{\pgfpoint{117}{-135}}
      \pgfpathcurveto{\pgfpoint{117}{-197}}{\pgfpoint{79}{-239}}{\pgfpoint{18}{-239}}
      \pgfpathlineto{\pgfpoint{-79}{-239}}
      \pgfpathlineto{\pgfpoint{-79}{-307}}
      \pgfpathlineto{\pgfpoint{21}{-307}}
      \pgfpathcurveto{\pgfpoint{99}{-307}}{\pgfpoint{184}{-245}}{\pgfpoint{184}{-136}}
      \pgfpathcurveto{\pgfpoint{184}{-20}}{\pgfpoint{80}{34}}{\pgfpoint{0}{34}}
      \pgfpathclose
      \pgfusepathqfill
    \fi
    \pgfpathmoveto{\pgfpoint{0}{34}}
    \pgfpathcurveto{\pgfpoint{61}{34}}{\pgfpoint{117}{68}}{\pgfpoint{117}{135}}
    \pgfpathcurveto{\pgfpoint{117}{197}}{\pgfpoint{79}{239}}{\pgfpoint{18}{239}}
    \pgfpathlineto{\pgfpoint{-79}{239}}
    \pgfpathlineto{\pgfpoint{-79}{307}}
    \pgfpathlineto{\pgfpoint{21}{307}}
    \pgfpathcurveto{\pgfpoint{99}{307}}{\pgfpoint{184}{245}}{\pgfpoint{184}{136}}
    \pgfpathcurveto{\pgfpoint{184}{20}}{\pgfpoint{84}{-34}}{\pgfpoint{4}{-34}}
    \pgfpathclose
    \pgfusepathqfill
  }
}
\makeatother

%% For the Bar arrowhead stlye
\usetikzlibrary{arrows.meta}

%% STIX arrows have a line width of exactly 0.68em:
\tikzset{every picture/.style={line width=.068em}}

%% Set up arrowheads:
\tikzset{>=stix,
         |/.tip={Bar[width=.403em,line width=.052em]},
         lefthook/.tip={stixhooks[left]},
         righthook/.tip={stixhooks[right]},
         leftharpoon/.tip={>[left]},
         rightharpoon/.tip={>[right]}
}

%% For the diagram below:
\usetikzlibrary{matrix,positioning,}

\begin{document}

\[\begin{tikzpicture}
    \matrix (m) [matrix of math nodes,text height=1.4ex,text depth=0.15ex,column sep=2.5em,row sep=2.5em] {
      |(B)| B & |(C)| C \\
      |(D)| D & |(E)| E \\ };
    \node[above left=2.5em of B] (A) {$A$};
    \draw[->,dashed] (A) -- node[auto,inner sep=.2ex]{$\scriptstyle\exists!$} (B);
    \draw[righthook->>] (B) -- (C);
    \draw[->,double distance=2\pgflinewidth] (B) to (D);
    \draw[|->] (C) -- (E);
    \draw[>-leftharpoon] (D) -- (E);
    \draw[->,double distance=2\pgflinewidth] (A) to[out=0] (C);
    \draw[<->] (A) to[out=-90] (D);
\end{tikzpicture}\]

\end{document}

This diagram used to be nice


They don't actually match exactly because the stix2 arrows aren't precisely symmetric (and my arrowheads are). Quite a few (control) points on the top half of the STIX Two arrows are off by 0.001em (due to rounding errors?) relative to their counterparts on the bottom half, and a couple are off by quite a bit more (due to sloppiness?). Another reason why they might not match precisely is because fonts may be rendered slightly differently than anything drawn with TikZ.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .