barcode.frink

Download or view barcode.frink in plain text format


/** Generates barcodes as Frink graphics.

    You can use this like:
    UPCA["000999420690"].show[]
*/


/** Generates a UPC-A label from a string of 11 or 12 digits.  If this has
    12 digits or more, it verifies that the last "check" digit is correct and
    corrects it (printing a warning) if it's incorrect.

    TODO:  Check for right number of digits otherwise

    arguments:
      [str, xdim, h]
     where
      str is a string of digits to encode (should be 11 or 12 chars long.)
      xdim is the width of the smallest bar (defaults to 0.33 mm per standard)
      h is the height of the normal bars (the start/end/middle bars will be
         5 xdim taller than this per spec.)

    returns:
       a graphics object
*/

UPCA[str, xdim=0.33 mm, h=25.9 mm] :=
{
   str = calculateCheckDigitUPCA[str]
   x = 0 xdim      // Make units of measure work out right
   g = new graphics
   g.font["Monospaced", h/8]
   g.antialiased[false]
   x = drawBarsUPCA[g, "000000000", x, xdim, h]      // Quiet zone left
   x = drawBarsUPCA[g, "101", x, xdim, h + 5 xdim]   // Start

   x = drawCharsUPCA[g, left[str, 6], x, xdim, h]    // Left 6 chars
   xl = x  // Used for aligning text characters
   x = drawBarsUPCA[g, "01010", x, xdim, h + 5 xdim] // Middle
   xr = x  // Used for aligning text characters
   x = drawCharsUPCA[g, right[str, 6], x, xdim, h, true] // Right 6 chars, reversed

   x = drawBarsUPCA[g, "101", x, xdim, h + 5 xdim]   // End
   x = drawBarsUPCA[g, "000000000", x, xdim, h]      // Quiet zone right

   // Draw text characters
   g.color[0,0,0]
   g.text[substrLen[str, 0, 1], 8 xdim, h, "right", "center"] // Left

   g.text[substrLen[str, 1, 5] + " ", xl, h - 2 xdim, "right", "top"] // Left 5
   g.text[" " + substrLen[str, 6, 5], xr, h - 2 xdim, "left", "top"] // Right 5

   g.text[substrLen[str, 11, 1], x - 8 xdim, h, "left", "center"] // Check digit
   return g
}

/** Draw a sequence of characters.   Returns the new x position. */
drawCharsUPCA[g is graphics, bits, x, xdim, h, reverse=false] :=
{
   CHAR:
   for c = charList[bits]
   {
      if c == "0"
         x = drawBarsUPCA[g, "0001101", x, xdim, h, reverse]
      if c == "1"
         x = drawBarsUPCA[g, "0011001", x, xdim, h, reverse]
      if c == "2"
         x = drawBarsUPCA[g, "0010011", x, xdim, h, reverse]
      if c == "3"
         x = drawBarsUPCA[g, "0111101", x, xdim, h, reverse]
      if c == "4"
         x = drawBarsUPCA[g, "0100011", x, xdim, h, reverse]
      if c == "5"
         x = drawBarsUPCA[g, "0110001", x, xdim, h, reverse]
      if c == "6"
         x = drawBarsUPCA[g, "0101111", x, xdim, h, reverse]
      if c == "7"
         x = drawBarsUPCA[g, "0111011", x, xdim, h, reverse]
      if c == "8"
         x = drawBarsUPCA[g, "0110111", x, xdim, h, reverse]
      if c == "9"
         x = drawBarsUPCA[g, "0001011", x, xdim, h, reverse]
   }

   return x
}  

/** Draws a sequence of bars.   Returns the new x position. */
drawBarsUPCA[g is graphics, bits, x, xdim, h, reverse=false] :=
{
   if isString[bits]
      bitArray = eval[charList[bits]]

   for b = bitArray
   {
      if reverse
         b = 1 - b
      if b == 0
         g.color[1,1,1]
      else
         g.color[0,0,0]

      g.fillRectSides[x, 0 h, x+xdim, h]
      x = x + xdim
   }

   return x
}

/** Calculates the check digit of the string, which should be 11 or 12 digits,
    and returns the string with the correct digit as the last character.
*/

calculateCheckDigitUPCA[str] :=
{
   c = eval[charList[str]]
   sum = (3 c@0 + c@1 + 3c@2 + c@3 + 3 c@4 + c@5 + 3c@6 + c@7 + 3 c@8 + c@9 + 3c@10) mod 10

   digit = toString[(10-sum) mod 10]
   ret = left[str, 11] + digit
   if length[str] > 11
      if digit != substrLen[str,11,1]
         println["Warning: $str had incorrect last check digit, should be $ret"]

   return ret      
}


Download or view barcode.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 20107 days, 23 hours, 25 minutes ago.