Jump to content
View in the app

A better way to browse. Learn more.

FMForums.com

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Featured Replies

Hey all, this time I created two functions that generate a BMP file with a code-128 barcode. It's more complicated, despite being shorter than the previous (EAN13), and it also has to generate a variable-length BMP file. There are some hacks, like the generation of a little-endian number for the BMP header, but overall it seems stable.

I tried uploading it to Brian Dunning's website but it didn't give me the link. I'll post it here, and if there are problems, please PM me.

 

/**
 * =====================================
 * BarcodeCode128B_BMP_380px ( string )
 *
 * PURPOSE:
 *		Generate a binary BMP file containing a Code-128 Type B barcode
 *
 * NOTE:
 *		Embed the contents in a container to see it. Valid for UP TO 20 CHARACTERS
 *
 * RETURNS:
 *		Binary BMP.
 *
 * PARAMETERS:
 *		string: The string to encode in Code-128
 *
 * DEPENDENCIES:
 * 		BarcodeCode128B_Raw
 *
 * RELEASE:
 * 		2017-06-15
 *
 * VERSION:	1.0
 * 
 * AUTHOR: 	© 2017 Mc128k - http://www.mc128k.com
 * =====================================
 */

Let ( [
	~binary=BarcodeCode128B_Raw(string);
	~size=Length(~binary) * 4 // size increased by (4 pixels wide) * (11 chars) * n = 44
	] ; 

	Let ( [
			_foreground_color = Substitute ( "1111" ; "1" ; "AAAA" ) ;  // set to black
			_background_color = Substitute ( "1111" ; "1" ; "////" ) ; // white
			_base =Base64Encode ( HexDecode ( 
				// BMP header
				"42 4D " &

				// File size (fake)
				"10 27 00 00 00 00 00 00 36 00 00 00 28 00 00 00 " &

				// Image size (bad solution but effective, creating little-endian values with functions is hard)
				// MAXIMUM 20 CHARACTERS
				Case ( 
					~size=220 ; "DC 00 00 00"; 
					~size=264 ; "08 01 00 00"; 
					~size=308 ; "34 01 00 00"; 
					~size=352 ; "60 01 00 00"; 
					~size=396 ; "8C 01 00 00"; 
					~size=440 ; "B8 01 00 00"; 
					~size=484 ; "E4 01 00 00"; 
					~size=528 ; "10 02 00 00"; 
					~size=572 ; "3C 02 00 00"; 
					~size=616 ; "68 02 00 00"; 
					~size=660 ; "94 02 00 00"; 
								
					~size=704 ; "C0 02 00 00"; 
					~size=748 ; "EC 02 00 00"; 
					~size=792 ; "18 03 00 00"; 
					~size=836 ; "44 03 00 00"; 
					~size=880 ; "70 03 00 00"; 
					~size=924 ; "9C 03 00 00"; 
					~size=968 ; "C8 03 00 00"; 
					~size=1012 ; "F4 03 00 00"; 
					~size=1056 ; "20 04 00 00"; 
					~size=1100 ; "4C 04 00 00"; 
					~size=1144 ; "78 04 00 00"; 
				) & " " &

				// Other BMP stuff
				"01 00 00 00 01 00 18 00 00 00 00 00 76 04 00 00 12 0B 00 00 12 0B 00 00 00 00 00 00 00 00 00 00"
				
				; "barcode.bmp" )) // Base64, Hex
				;
			_map = Substitute ( ~binary ; "0" ; _background_color );
			_map = Substitute ( _map; "1" ; _foreground_color );
			_map = _map & "////"
		] ; 
			If ( ~size > 1144  ; "error" ; Base64Decode ( _base & _map ; "barcode.bmp" ) )
		)
)
/**
 * =====================================
 * BarcodeCode128B_Raw ( input )
 *
 * PURPOSE:
 *		Generates the binary number for the Code-128 Type B barcode
 *
 * RETURNS:
 *		A binary number representing the barcode
 *
 * PARAMETERS:
 *		input: the string to encode
 *
 * DEPENDENCIES:
 * 		ForEach, Repeat
 *
 * RELEASE:
 * 		2017-06-15
 *
 * REFERENCES:
 *		https://en.wikipedia.org/wiki/Code_128
 *
 * VERSION:	1.0
 * 
 * AUTHOR: 	© 2017 Mc128k - http://www.mc128k.com
 * =====================================
 */

Let ( [
	~code=Filter ( input ; "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~" );

/**
 * Behold, all 108 symbols of Code-128. Use GetValue() to pick the desired one.
 *
 * Bar weights are specified by the number of black or white consecutive bars
 * For example a weight of "212222" means that the code will be "11011001100"
 * where the first "2" means that there will be two "1" bits, and the next
 * "1" will tell that there will be one "0" bit
 * 
 * Type B, keep +1 as it allows C-style array numbers, 32 shifts the ASCII value to the array position
 */

$code128_sym="212222¶222122¶222221¶121223¶121322¶131222¶122213¶122312¶132212¶221213¶221312¶231212¶112232¶122132¶122231¶113222¶123122¶123221¶223211¶221132¶221231¶213212¶223112¶312131¶311222¶321122¶321221¶312212¶322112¶322211¶212123¶212321¶232121¶111323¶131123¶131321¶112313¶132113¶132311¶211313¶231113¶231311¶112133¶112331¶132131¶113123¶113321¶133121¶313121¶211331¶231131¶213113¶213311¶213131¶311123¶311321¶331121¶312113¶312311¶332111¶314111¶221411¶431111¶111224¶111422¶121124¶121421¶141122¶141221¶112214¶112412¶122114¶122411¶142112¶142211¶241211¶221114¶413111¶241112¶134111¶111242¶121142¶121241¶114212¶124112¶124211¶411212¶421112¶421211¶212141¶214121¶412121¶111143¶111341¶131141¶114113¶114311¶411113¶411311¶113141¶114131¶311141¶411131¶211412¶211214¶211232¶2331112¶"

];

/**
 * Zones:
 * 
 * Quiet zone
 * Start symbol
 * Encoded data
 * Check symbol
 * Stop symbol & final bar
 * Quiet zone
 */ 

// Quiet zone (10x)
"0000000000" &

// Start symbol
Substitute ( ForEach ( StringToList ( GetValue ( $code128_sym ; 104 +1) ) ; "If ( Mod ( $~i ; 2 ) = 1 ; Repeat ( \"1\" ; ~n ) ; Repeat ( \"0\" ; ~n ) ) " ) ; "¶" ; Null ) &

// Encoded data - Substitute string with symbols, symbols with binary. Evaluation hell incoming
Evaluate (Substitute ( 
	ForEach ( 
		// substitute rows with calculations that return binary code. Should look like this:
		// Substitute ( ForEach ( StringToList ( "311321" ) ; "If ( Mod ( $~i ; 2 ) = 1 ; Repeat ( \"1\" ; ~n ) ; Repeat ( \"0\" ; ~n ) ) " ) ; "¶" ; Null )
		ForEach ( StringToList ( ~code ) ; "GetValue ( $code128_sym ; code ( ~n ) +1 -32 )" ); // "abc" -> 121124¶121421¶141122
		"
			\"Substitute ( ForEach ( StringToList ( \\\"\" 
			& ~n & 
			\"\\\" ) ; \\\"If ( Mod ( $~i ; 2 ) = 1 ; Repeat ( \\\\\\\"1\\\\\\\" ; ~n ) ; Repeat ( \\\\\\\"0\\\\\\\" ; ~n ) ) \\\" ) ; \\\"\\\¶\\\" ; Null )\"
		"
	)
; "¶" ; " & ")) &

// Checksum
Let ( 
	~checksum = Evaluate( "Mod(104+" & Substitute ( ForEach ( StringToList ( ~code ) ; "(Code ( ~n ) - 32) * $~i" ) ; "¶" ; "+") & "; 103)");
	Substitute ( ForEach ( StringToList ( GetValue ( $code128_sym ; ~checksum +1) ) ; "If ( Mod ( $~i ; 2 ) = 1 ; Repeat ( \"1\" ; ~n ) ; Repeat ( \"0\" ; ~n ) ) " ) ; "¶" ; Null )
) &

// Stop symbol
Substitute ( ForEach ( StringToList ( GetValue ( $code128_sym ; 106 +1) ) ; "If ( Mod ( $~i ; 2 ) = 1 ; Repeat ( \"1\" ; ~n ) ; Repeat ( \"0\" ; ~n ) ) " ) ; "¶" ; Null ) &

// Quiet zone (10x)
"0000000000"

 ) // End Let
/**
 * =====================================
 * Repeat ( text ; times )
 *
 * PURPOSE:
 *		Just repeat a string many times
 *
 * RETURNS:
 *		A string
 *
 * PARAMETERS:
 *		text: The text to be repeated
 *		times: How many times to repeat it
 *
 * RELEASE:
 * 		2017-06-11
 *
 * VERSION:	1.0
 * 
 * AUTHOR: 	© 2017 Mc128k
 * =====================================
 */

If (times > 0 ;
text & If ( times > 1 ;  Repeat ( text ; times - 1) ; "") ; "" )
/**
 * =====================================
 * ForEach ( valueList ; expression )
 *
 * PURPOSE:
 *		ForEach repeatedly applies a calculation to each value in a ¶-delimited
 *		list. For each value in valueList, evaluates expression, substituting
 *		the value for each "~n" in expression. Expressions may also reference
 *		the value index (line number) being evaluated with "$~i". This is
 *		analogous to Map functionality in functional programming languages.
 *
 * NOTE:
 *		This is the recursive version of this function. It is slower, but
 *		capable of processing larger lists.
 *
 * RETURNS:
 *		A ¶-delimited list of the results of evaluating expression on valueList.
 *
 * EXAMPLE:
 *		ForEach (
 *			List ( "1 One" ; "2 Two" ; "3 Three"  );
 *			"Left ( ~n ; 1 ) + $~i"
 *		)	// = "2¶4¶6"
 *
 * PARAMETERS:
 *		valueList: A ¶-delimited list of inputs to expression
 *		expression: A calculation to evaluate
 *
 * DEPENDENCIES: none
 *
 * RELEASE:	2012-01-06
 *
 * REFERENCES:
 *		http://en.wikipedia.org/wiki/Map_(higher-order_function)
 * =====================================
 */

Case (
	/* Step 0, initialize routine */
	not $~map.step;
		Let ( [
			$~map.valueCount = ValueCount ( valueList );
			$~map.step = 1
		];
			ForEach ( valueList ; expression )
		);

	/* Step 1, evaluate expression */
	$~map.step = 1;
		Let ( [
			$~i = $~i + 1;
			~value =
				Evaluate (
					"Let ( ~n = "
					& Quote ( GetValue ( valueList ; $~i ) )
					& " ; "
					& expression
					& " )"
				);
			$~map.resultList =
				If ( $~i > 1 ; $~map.resultList & ¶ )
				& ~value;
			$~map.step =
				If ( $~i < $~map.valueCount;
					$~map.step;
					/* Else */ $~map.step + 1
				)
		];
			ForEach ( valueList ; expression )
		);

	/* Step 2, clean-up and return result */
	$~map.step = 2;
		Let ( [
			~resultList = $~map.resultList;

			// Purge variables
			$~i = "";
			$~map.resultList = "";
			$~map.step = "";
			$~map.valueCount = ""
		];
			~resultList
		)
)
/**
 * =====================================
 * Null
 *
 * PURPOSE:
 *		Mark in a readable way an empty string (for parameters and stuff)
 *
 * RETURNS:
 *		""
 *
 * EXAMPLE:
 *		If ( PatternCount ( Table::fieldName ; Tab & Tab ) ≥ 1;
 * 			"Awesome use of indentation!";
 * 			Null
 * 		);
 *
 * RELEASE:
 * 		2017-06-11
 *
 * REFERENCES:
 *		http://filemakerstandards.org/pages/viewpage.action?pageId=557129
 *
 * VERSION:	1.0
 * 
 * AUTHOR: 	© 2017 Mc128k
 * =====================================
 */

""

 

Code128B.fmp12

Nice, but what's the benefit of using this over a Code 128 Barcode font? Using a font seems much simpler? I've had good results with fonts such as these: http://www.dafont.com/code-128.font

  • Author

There are multiple reasons for that.

  1. You don't need a font, this simplifies the deployment
  2. It works on iOS
  3. It works on FMS and WebDirect
  4. I don't know exactly, but I believe that the font is unable to calculate the checksum
  5. It works on containers, so it's more flexible and it can be scaled easily
  6. It works on all layouts, it doesn't need a specific layout object, like a custom text field, just a container
  7. It's cooler this way ;)
  • 2 years later...
On 6/15/2017 at 4:58 PM, Mc128k said:

There are multiple reasons for that.

  1. You don't need a font, this simplifies the deployment
  2. It works on iOS
  3. It works on FMS and WebDirect
  4. I don't know exactly, but I believe that the font is unable to calculate the checksum
  5. It works on containers, so it's more flexible and it can be scaled easily
  6. It works on all layouts, it doesn't need a specific layout object, like a custom text field, just a container
  7. It's cooler this way ;)

super

Create an account or sign in to comment

Important Information

By using this site, you agree to our Terms of Use.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.