[Tex/LaTex] producing embossed tactile graphics with Tikz for a student who is blind

accessibilitygraphicspdftikz-pgf

I work at disability services at a university and recently started working with a student who is blind in upper level computer theory, automaton, and programming classes.

I learned LaTeX about 3-4 weeks ago per the student's request so that the student could get the notes in that form and could learn to use it to produce automation graphics for homework. The student would now like to get tactile graphics printed of his figures so that he can get a better idea of what the LaTeX TikZ code means.

Imagine if all you could do to "see" a graphic for your class was to read the LaTeX code for it, and then you had to produce your own with only that knowledge, and some layman's verbal description of what it looks like.

I'm new to the office and in a lower level position so I don't have any background using the embossing equipment. There's a Tiger printer and an emprint according to the student. I'll be getting more info today, but I want to get something worked out for the student as soon as possible so I am posting my questions now.

Does anyone have experience using TikZ graphical output from LaTeX for printing on a Tiger embosser ? Or any experience providing accommodations for blind people using LaTeX ?

How could I make a graphic that is scaled properly so that when it converts to dots it will have good enough resolution to be understood ? The resolution for the embosser is 20 dots per inch. Is there any decoration package that could convert the lines of a graphic to dots of that resolution ?

Thank you so much for your help. This is all very new to me so forgive me if I say something incorrectly/that doesn't make sense.

Best Answer

Thank you all for your help and suggestions. Here is what I found which helped with my problem.

I had a braille font installed, but it was not the correct braille font for the printer I was using, ViewPlus Tiger Cub. After installing the Tiger Software Suite (TSS), many braille fonts were added as system fonts. I was told at work that I needed to use the Braille font Braille29 with a font size of 29 for it to print correctly on the Tiger. However, when I imported the picture of the generated PDF into Word, which makes a bitmap image that one can then paste into the TSS, it showed shadowing of the braille dots. One braille dot would show up as more than one dot and would thus be illegible.

This issue was solved by sending the PDF directly to the printer. It seems like an obvious and simple solution, but no one I worked with thought it would work. Eventually my student got in touch with the president of ViewPlus, John Gardener, and was told that the Tiger could print PDFs, and any other kind of image files, but it isn't usually done because they might not turn out well. With Latex and the correct font, however, it works very well.

By printing to a file, and then opening that file with the TSS one can check how it will turn out without a lot of wasted paper and time-an embossing printer is quite slow. If there are standard characters, like the right arrows, you can choose whether or not to emboss them as if they were a graphic by going to Printing Preferences-Tiger tab-and checking the box by "Emboss Standard Text." Sometimes keeping the graphic symbol is a good option to keep labels short when they have symbols that are two or more braille characters long. If the box is not checked then any standard characters will just be ignored and show up as a blank space.

This is a diagram that I have selected as an example. Thanks to code posted by Andrew Stacy I was able to increase the size of the arrow heads.

An automata state diagram with 9 states and braille labels. The transitions have enlarged arrow heads

This picture shows how the image would look when imported into Word to copy it to the TSS. The different shades designate different heights of dots. White is designated 0, black is 7, and blue is 8 and is what the TSS uses when it adds a braille label. 3 is as light as one should go for lines and borders. It can typically be detected as a different height from 5, and 5 can typically be resolved from 7. If you did a whole graphic in blue it would probably tear with use.

A dot printout of an automata state diagram. All braille characters show up wrongly as a straight line or have an extra dot immediately next to one or more dots in a label. The braille makes no sense.

This shows how it looked when printed directly from the Latex-generated PDF.

The same diagram as picture 2, but the braille is clear and legible.

The images above come from the following code. Note: the ASCII character we see as a quotation mark is an important braille symbol for indicating the end of a superscript and will not show up correctly if you have smart quotes enabled. You must either disable it or set it to Unicode for the symbol to show up correctly.

\documentclass{MWE}
\usepackage[paperheight=11in,paperwidth=8.5in, left=.5in, right=.25in, top=.25in,    bottom=.25in]{geometry}
\usepackage{fontspec}
\setmainfont{Braille29} %while working on the document I switch 
%back an forth between Braille29 and the font Braille29 ASCII, 
%which shows ASCII characters that are scaled to take up about 
%the same space as their braille counterpart
\usepackage{tikz}
\begin{document}
\usetikzlibrary{arrows,automata,positioning}
%the following code is from Andrew Stacy to allow the arrow 
%heads to be easily scaled up in size. Thanks Andrew!
\makeatletter
\pgfkeys{
  /pgf/scalable arrows/.code={
    \let\pgf@add@arrows@as@needed=\pgf@add@scalable@arrows@as@needed
    \let\pgf@shorten@path@as@needed=\pgf@shorten@path@as@needed@for@scalable
  },
  /pgf/arrow scale factor/.initial=1,
}

\def\pgf@add@scalable@arrows@as@needed{%
  \pgfkeysgetvalue{/pgf/arrow scale factor}{\pgf@temp}%
  \let\pgf@restorelw=\pgfutil@empty
  \ifx\pgf@temp\pgfutil@empty
  \else
  \edef\pgf@restorelw{\noexpand\pgfsetlinewidth{\the\pgflinewidth}}%
  \pgfsetlinewidth{\pgf@temp\pgflinewidth}%
  \fi
  \ifx\pgf@startarrow\pgfutil@empty%
  \else%
    \pgflowlevelobj%
      {\pgftransformarrow{\pgfpointsecondonpath}{\pgfpointfirstonpath}}
      {\pgf@startarrow}%
  \fi%
  \ifx\pgf@endarrow\pgfutil@empty%
  \else%
    \pgflowlevelobj%
      {\pgftransformarrow{\pgfpointsecondlastonpath}{\pgfpointlastonpath}}
      {\pgf@endarrow}%
  \fi%
      \pgf@restorelw%
}

\def\pgf@shorten@path@as@needed@for@scalable{%
  \pgfkeysgetvalue{/pgf/arrow scale factor}{\pgf@temp}%
  \let\pgf@restorelw=\pgfutil@empty
  \ifx\pgf@temp\pgfutil@empty
  \else
  \edef\pgf@restorelw{\noexpand\pgfsetlinewidth{\the\pgflinewidth}}%
  \pgfsetlinewidth{\pgf@temp\pgflinewidth}%
  \fi
  \pgfprocesspathextractpoints{\pgf@arrowpath}%
  \let\pgf@arrow@next=\pgf@shorten@now%
  \ifx\pgf@shorten@start\pgfutil@empty%
    \ifx\pgf@shorten@end\pgfutil@empty%
      \ifdim\pgf@shorten@end@additional=0pt\relax%
        \ifdim\pgf@shorten@start@additional=0pt\relax%
          \let\pgf@arrow@next=\relax%
        \fi%
      \fi%
    \fi%
  \fi%
  \pgf@arrow@next%
  \pgf@restorelw%
}

\makeatother

\fontsize{29pt}{29pt}% I only knew what the font size was supposed to be so I didn't know what to put for the other argument.  The braille still looks ok with both set to 29.

\vspace*{\fill}
\begin{center}
\rotatebox{90}{
\begin{tikzpicture}
[scalable arrows, arrow scale factor=4, >=angle 90, 
shorten >=6pt, % there needs to be enough space between the object 
%and the arrow so they're each recognized as separate things, and 
%the shape of the arrow head is clear.  If it gets too close it just 
%feels like a blob, which is better than nothing and certainly works 
%well enough when an arrow head is all it could be.
line width=1pt, % The embosser recognizes a line as small as 1pt and 
%usually makes it 1 dot thick.  
node distance=3.75cm, 
on grid, 
auto, 
accepting/.style={double distance=6pt, outer sep=4pt}]% this is super 
%important to make accepting states easily recognized.
    \node[state] (q1) {q1};
    \node (fig label) [above=3cm of q1, xshift=3cm] {fig \#3.10 p\#173};
    \node[state] (q8) [below left=5cm of q1, xshift=1.5cm] {q8};
    \node (position) [below=2cm of q8] {};
    \node (initial state arrow) [above left=3cm of q1] {};
    \draw[->] (initial state arrow) -- (q1.north west);
    \node[state, accepting] (q accept) [below=of q8] {qa};
    \node[state] (q6) [below=4.75cm of q accept] {q6};
    \node[state] (q2) [left=4cm of q8] {q2};
    \node[state] (q4) [below=of q2] {q4};
    \node[state] (q3) [right=7.75cm of position] {q3};
    \node[state] (q5) [below=of q3]{q5};
    \node[state] (q7) [right=16cm of q6] {q7};
    \path[->]
        (q1.south east) edge [out=0, in=90, distance=3.25cm] node [right=.05cm, very near end, yshift=-.5cm] {\#1$\rightarrow$;x,,R} (q3.north)
        (q1) edge node [right=.05cm, near end] {\#$\rightarrow$,R} (q8)
        edge [out=210, in=45] node [above =.75cm, near end] {\#0$\rightarrow$;x,,R} (q2)
        (q2) edge [out=-195, in=-225, loop, distance=1.5cm] node [above, xshift=-.05cm, near end] {\#0,1$\rightarrow$,R} (q2)
        edge node [left=.25cm, near end] {\#$\rightarrow$,R} (q4)
        (q4) edge [out=195, in=225, loop, distance=1.5cm] node [below, near end, xshift=-.75cm] {;x$\rightarrow$,R} (q4)
        edge [out=-90, in=140] node [left, very near end, yshift=-.5cm] {\#0$\rightarrow$;x,,L} (q6)
        (q6) edge [out=195, in=225, loop, distance=1.5cm] node [below right, at end, yshift=-.1cm, xshift=-.5cm] {\#0,1,;x$\rightarrow$,L} (q6)
        edge  node [below=-.15cm, near end, xshift=1cm] {\#$\rightarrow$,L} (q7)
        (q3) edge [loop right, distance=1.5cm] node [xshift=-.25cm] {\#0,1$\rightarrow$,R} (q3)
        edge node [right] {\#$\rightarrow$,R} (q5)
        (q5) edge [loop right, distance=1.5cm] node [xshift=-.25cm] {;x$\rightarrow$,R} (q5)
        (q5) edge [out=180, in=45] node [below=.25cm, xshift=.25cm] {\#1$\rightarrow$,L} (q6)
        (q7) edge [out=255, in=225, loop, distance=1.5cm] node [left, near end, yshift=-.25cm] {\#0,1$\rightarrow$,L} (q7)
        (q7.north) edge [out=90, in=0, distance=11.5cm] node [below left=-.5cm, near end, xshift=-2.75cm] {;x$\rightarrow$,R} (q1.north east)
        (q8) edge [loop right, distance=1.5cm] node [xshift=-.35cm] {;x$\rightarrow$,R} (q8)
        edge node [right=.2cm] {$\sqcup\rightarrow$,R} (q accept)
        ;
\end{tikzpicture}}
\end{center}
\end{document}

Certain stylistic choices are important for the graphic to be readable.

  • An arrowhead in braille is typically represented with a right angle and needs to be scaled up to be "visible" in the tactile sense
  • The reader typically scans from left to right with the tip of the finger. Thus labels that are above a line/object are harder to notice than labels that are below or to the left/right. For the same reason don't put things very far apart, since the reader may not realize that there are additional parts and miss them.
  • It is better to put labels near the beginning or end of long things, not in the middle. The only way sighted readers know where the middle of something is is by seeing the beginning and end simultaneously. As a blind reader scans along a line he/she doesn't know when or where it will end and won't know when to veer off the line to find a label. If you don't know what the person prefers just pick one convention that makes sense and stick to it as much as possible.

Here is an edited version of the previous figure that employs the above tips more rigorously.

same diagram as 2 and 3 but with labels generally near the arrow heads, and positioned below, or to the right or left

Related Question