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 20108 days, 1 hours, 25 minutes ago.