Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm currently working on a software for an graphic display, so I recreated it in TikZ for documentation purposes:

image of the display

I currently use this to set individual pixels on the display:

\setpixel{x}{y}

Where x and y are coordinates between 0 and 132/64.

The real display is separated into 8 pages, each 8 pixels high, and a byte sent to the display is displayed as a column. See this image for details.

Since I don't want to always calculate the individual pixels, I'd like the LaTeX variant to behave like the real display, that is, I want some command like

\dispbyte{0x01}
\dispbyte{0x03}
\dispbyte{0x07}
\dispbyte{0x0F}
\dispbyte{0x1F}
\dispbyte{0x3F}
\dispbyte{0x7F}
\dispbyte{0xFF}

(this would create one of the triangles above) I have an idea how I'd implement counting of the current column and page switching and all that -- shouldn't be hard with some counters after all -- but I just can't find out how to parse the hexadecimal values and then iterate over every bit inside them.

I've found fmtcount and binhex.tex, but they only display a LaTeX counter in another format, and I can't understand their code at all.

The finished source code (display.sty) and some examples are now available at http://cmpl.cc/downloads/disp/

share|improve this question
    
That sounds fascinating. Do you intent to publish the source to the pixel -> TikZ conversion? –  Alexander Apr 25 '13 at 21:13
    
@Alexander I will release the complete source code in a few weeks, when the project I'm writing the documentation for is finished. –  The Compiler Apr 26 '13 at 7:37
2  
It is not absolutely clear to me what you want, hence I write this as a comment: Take a look at the bitset package by Heiko Oberdiek. It provides the abstraction of bitsets of various lenght, which can be initialized from a hex value by \bitsetSetHex. Individual bits can be tested (\bitsetGet) or all set lists transformed into a comma-separated list (\bitsetGetSetBitList) to be then iterated with, e.g., \foreach. –  Daniel Apr 26 '13 at 10:07
1  
Note also this related question. –  Daniel Apr 26 '13 at 10:09
    
@TheCompiler: For \foreach you just have to expand it first, e.g., with \edef. I have now posted this as an answer. –  Daniel Apr 26 '13 at 14:53

5 Answers 5

up vote 6 down vote accepted

The following is less impressive than the other answers from the visual point of view (Mark, I like yours!), but addresses the actual question of the OP: Bit-wise iteration over hexadecimal values, which becomes fairly easy when using the bitset package by Heiko Oberdiek:

\documentclass{article}
\usepackage{bitset}
\usepackage{pgf,pgffor}

\begin{document}

  \bitsetSetHex{mybitset}{AA}
  % use \bitsetGetSetBitList
  % expand first
  \edef\mybits{\bitsetGetSetBitList{mybitset}}
  \noindent
  \foreach \bit in \mybits {%
    Bit \bit{} is set! \\ 
  }

  % just itereate all bits
  \noindent
  \foreach \i in {0,...,7} {%
    Bit \i: \bitsetGet{mybitset}{\i} \\
  }

\end{document}

enter image description here

share|improve this answer
    
That was by far the most easy to use way. Took me like 5 minutes to implement what I wanted based on that. Thanks! –  The Compiler Apr 27 '13 at 1:24

Not sure this is robust, it only works within the limited numerical range of PGFMath, and clearly I've gone for something a bit more over-the-top than the requirements.

EDIT: following Daniels example of the bitset package the code has been updated to be a bit more like that.

\documentclass[border=5pt]{standalone}
\usepackage{tikz}

\newcount\bitcount
\tikzset{
    zeros/.style={
        draw=black,
        insert path={
            (-\nbit-1/2, -1/2) rectangle ++(1,1)
        }
    },
    ones/.style={
        draw=black,
        fill=gray,
        insert path={
            (-\nbit-1/2, -1/2) rectangle ++(1,1)
        }
    },
    max bits/.store in=\maxbits,
    max bits=0
}

\newcommand\dispbyte[2][]{%
    \begingroup%
        \tikzset{#1}%
        \pgfmathsetcount\bitcount{#2}%
        \pgfmathparse{int(\maxbits)}\let\maxbits=\pgfmathresult%
        \pgfmathloop%
        \ifnum\bitcount>0\relax%
            \ifodd\bitcount%
                \expandafter\def\csname bit\pgfmathcounter\endcsname{1}%
            \else%
                \expandafter\let\csname 
                bit\pgfmathcounter\endcsname=\relax%
            \fi%
            \divide\bitcount by2\relax%
        \repeatpgfmathloop%
        \pgfmathparse{int(\maxbits>\pgfmathcounter?\maxbits+1:\pgfmathcounter+1)}%
        \let\nbits=\pgfmathresult%
        \pgfmathloop%
        \ifnum\pgfmathcounter=\nbits\relax%
        \else%
            \let\nbit=\pgfmathcounter%
            \expandafter\ifx\csname bit\pgfmathcounter\endcsname\relax%
                \path [zeros];
            \else%
                \path [ones];
            \fi%
        \repeatpgfmathloop%
    \endgroup%
}

\begin{document}


\begin{tikzpicture}[x=10pt, y=10pt]

\foreach \d [count=\c from 0, evaluate={\x=floor(\c/8)*8; \y=-mod(\c,8);}] 
in 
{%
    0x7f,0x49,0x08,0x08,0x08,0x08,0x08,0x1c, 
    0x00,0x00,0x08,0x00,0x18,0x08,0x08,0x1c,
    0x08,0x08,0x10,0x12,0x14,0x28,0x24,0x22,
    0x7f,0x02,0x04,0x08,0x08,0x10,0x20,0x7f}{
    \dispbyte[max bits=8,shift={(\x,\y)}]{\d}
}

\foreach \d [count=\c from 0, evaluate={\x=floor(\c/8)*8; \y=-mod(\c,8);}] 
in 
{%
    0x7f,0x49,0x08,0x08,0x08,0x08,0x08,0x1c, 
    0x00,0x00,0x08,0x00,0x18,0x08,0x08,0x1c,
    0x08,0x08,0x10,0x12,0x14,0x28,0x24,0x22,
    0x7f,0x02,0x04,0x08,0x08,0x10,0x20,0x7f}{
    \dispbyte[zeros/.style={},
        ones/.style={
            fill=gray,
            insert path={
                (-\nbit-3/8, -3/8) rectangle ++(0.75,0.75)
            }
        },shift={(\x,\y-9)}]{\d}
}

\foreach \d [count=\c from 0, evaluate={\x=floor(\c/8)*8; \y=-mod(\c,8);}] 
in 
{%
    0x7f,0x49,0x08,0x08,0x08,0x08,0x08,0x1c, 
    0x00,0x00,0x08,0x00,0x18,0x08,0x08,0x1c,
    0x08,0x08,0x10,0x12,0x14,0x28,0x24,0x22,
    0x7f,0x02,0x04,0x08,0x08,0x10,0x20,0x7f}{
    \dispbyte[max bits=8,
        zeros/.style={ 
            fill=black,
            insert path={ 
                (-\nbit, 0) circle [radius=0.5]
            }
        },
        ones/.style={
            fill=orange,
            insert path={ 
                (-\nbit, 0) circle [radius=0.5]
            }
        },shift={(\x,\y-18)}]{\d}
}

\end{tikzpicture}
\end{document}

enter image description here

share|improve this answer

You can use LaTeX3 that has a function for converting integers to binary. Instead of \fbox use your preferred macro.

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\dispbyte}{m}
 {
  \compiler_dispbyte:n { #1 }
 }

\tl_new:N \l_compiler_bits_tl
\tl_new:N \l_compiler_byte_tl
\cs_new_protected:Npn \compiler_dispbyte:n #1
 {
  % we need to remove the 0x
  \tl_set:Nn \l_compiler_byte_tl { #1 }
  \tl_remove_once:Nn \l_compiler_byte_tl { 0x }
  % convert the number to a string of bits
  \tl_set:Nx \l_compiler_bits_tl
   { \int_to_binary:n { "\l_compiler_byte_tl } }
  % loop through the list of bits
  \tl_map_inline:Nn \l_compiler_bits_tl
   { \fbox{ ##1 } }
 }
\ExplSyntaxOff

\begin{document}
\dispbyte{0x01}

\dispbyte{0x03}

\dispbyte{0x07}

\dispbyte{0x0F}

\dispbyte{0x11}

\dispbyte{0x13}

\dispbyte{0x17}

\dispbyte{0x1F}
\end{document}

If you need the bits in reverse order, just add

  \tl_set:Nx \l_compiler_bits_tl
   { \tl_reverse:V \l_compiler_bits_tl }

before the \tl_map_inline:Nn line.

enter image description here

share|improve this answer

I didn't get exactly what you want to do but pgfmath already understands Hex syntax.

\documentclass{article}
\usepackage{tikz}

\begin{document}
\pgfmathparse{bin(0x1F)}
\pgfmathresult

\pgfmathparse{bin(0X1F)}
\pgfmathresult

\end{document}

Both leads to 11111

share|improve this answer

enter image description here

This loops over the binary digits from the hex, for testing it just prints them out (in reverse order to keep the code simple)

\documentclass{article}

\makeatletter
\def\dispbyte#1{\@displaybyte#1\relax}
\def\@displaybyte#1x#2\relax{\count@\string"#2\relax
\loop
  \fbox{\ifodd\count@ 1\else0\fi}%
\divide\count@\tw@
\ifnum\count@>\z@
\repeat}
\makeatother

\begin{document}

\dispbyte{0x17}

\end{document}
share|improve this answer
    
It can't:-) Do you have a non standard format making " active even if babel is notloaded? –  David Carlisle Apr 25 '13 at 21:01
    
add \tracingall before \dispbyte and post the log (or email it me: google my name for my gmail account) –  David Carlisle Apr 25 '13 at 21:03
    
I didn't try it yet, but two things come to mind by looking at it: 1) how would I use that with babel? Wouldn't " be active as well then? 2) shouldn't the second \makeatletter be a \makeatother? –  The Compiler Apr 26 '13 at 5:42
1  
@TheCompiler you can use \string" to be safe if " is active and yes the second make... is a typo (although it doesn't really matter, I'll fix both:-) –  David Carlisle Apr 26 '13 at 6:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.