I'm trying to get my head around some code that uses bit shifting to unpack vector coordinates for HPGL font 'draw + move' instructions. I am using a programming calculator to try to work through the code but I am not getting it.
Description of the data format and the function I am working with is below. The lines I am wrestling with are these two:
x = (double) (c >> 4) - 1.0; /* Bits 4,5,6 --> value 0..7 */
y = (double) (c & 0x0f) - 4.0; /* Bits 0-3 --> value 0..f */
To work the problem, according to the data format spec, an input of
324 should result in x == 5, y ==4;
what I get:
(for x) 324 >> 4 is 20; then subtract 1 == 19
then
(for y) 20 AND 15 == 4; then subtract 4 == 0
I have this ass backwards somehow, yes?
Data format:
** A font or character set is an array of strings. Each character
** corresponds to one of these strings, which is addressed by its ASCII code.
**
** A character is a (NULL-terminated) string of bytes. Each byte
** codes for a draw or move action according to the code below:
**
** Bit: 7 6 5 4 3 2 1 0
** p x x x y y y y
**
** p: Plot flag. If set, "draw to" new point, else "move to" it.
** xxx: 3-bit unsigned integer (0...7). X coordinate of new point.
** yyyy: 4-bit unsigned integer (0..15). Y coordinate of new point.
**
** The baseline is y = 4 instead of y = 0, so characters with parts
** below it can be drawn properly without a need for sign bits.
** Function "code_to_ucoord()" transforms these coordinates into
** actual user coordinates.
**
** Example: code for character 'L': "\032\224\324" translates to:
** moveto(1,10); drawto(1,4); drawto(5,4);
Function:
static void
code_to_ucoord (char c, HPGL_Pt *pp)
/**
** Converts internal one-byte code (in c) for a character vector
** into HP-GL coordinates (pointed to by pp)
**/
{
double x,y;
/*
* RS6000 bug fix:
* outer braces of casts removed, costing 2 double ops
* My guess: "char" is unsigned on RS6000
*/
x = (double) (c >> 4) - 1.0; /* Bits 4,5,6 --> value 0..7 */
y = (double) (c & 0x0f) - 4.0; /* Bits 0-3 --> value 0..f */
[color=#ff0000]
// NOTE: the stuff below is not important to my question[/color]
pp->x = tp->Txx * x + tp->Txy * y + tp->refpoint.x + tp->offset.x;
pp->y = tp->Tyx * x + tp->Tyy * y + tp->refpoint.y + tp->offset.y;
}