Просмотр исходного кода

Added Codabar support
- Added building instructions to README

Alan Tsui 2 лет назад
Родитель
Сommit
04eb96880b

+ 21 - 5
README.md

@@ -2,7 +2,7 @@
 	<h1 align="center">Barcode Generator</h1>  
   <p align="center">
 
-A barcode generator for the Flipper Zero that supports **UPC-A**, **EAN-8**, **EAN-13**, **Code-39**, and **Code-128**[1]
+A barcode generator for the Flipper Zero that supports **UPC-A**, **EAN-8**, **EAN-13**, **Code-39**, **Codabar**, and **Code-128**[1]
 </p>
 
 Note: Barcode save locations have been moved from `/barcodes` to `/apps_data/barcodes`
@@ -10,6 +10,7 @@ Note: Barcode save locations have been moved from `/barcodes` to `/apps_data/bar
 ## Table of Contents
 - [Table of Contents](#table-of-contents)
 - [Installing](#installing)
+- [Building](#building)
 - [Usage](#usage)
   - [Creating a barcode](#creating-a-barcode)
   - [Editing a barcode](#editing-a-barcode)
@@ -24,12 +25,21 @@ Note: Barcode save locations have been moved from `/barcodes` to `/apps_data/bar
 2) Extract/unzip the `.zip` file onto your computer
 3) Open qFlipper and go to the file manager
 4) Navigate to the `apps` folder
-5) Drag & Drop the `.fap` file into the `apps` folder
-6) Navigate back to the root folder and create the folder `apps_data`, if not already there
+5) Drag & drop the `.fap` file into the `apps` folder
+6) Navigate back to the root folder of the SD card and create the folder `apps_data`, if not already there
 7) Navigate into `apps_data` and create another folder called `barcode_data`
 8) Navigate into `barcode_data`
-9) Drag & Drop the encoding txts (`code39_encodings.txt` & `code128_encodings.txt`) into the `barcode_data` folder
-
+9) Drag & drop the encoding txts (`code39_encodings.txt`, `code128_encodings.txt` & `codabar_encodings.txt`) into the `barcode_data` folder
+
+## Building
+1) Clone the [flipperzero-firmware](https://github.com/flipperdevices/flipperzero-firmware) repository or a firmware of your choice
+2) Clone this repository and put it in the `applications_user` folder
+3) Build this app by using the command `./fbt Barcode_App`
+4) Copy the `.fap` from `build\f7-firmware-D\.extapps\Barcode_App.fap` to `apps\Misc` using the qFlipper app
+5) While still in the qFlipper app, navigate to the root folder of the SD card and create the folder `apps_data`, if not already there
+6) Navigate into `apps_data` and create another folder called `barcode_data`
+7) Navigate into `barcode_data`
+8) Drag & drop the encoding txts (`code39_encodings.txt`, `code128_encodings.txt` & `codabar_encodings.txt`) from the `encoding_tables` folder in this repository into the `barcode_data` folder
 
 ## Usage
 
@@ -39,6 +49,12 @@ Note: Barcode save locations have been moved from `/barcodes` to `/apps_data/bar
 3) Enter your filename and then your barcode data
 4) Click save
 
+**Note**: For Codabar barcodes, you must manually add the start and stop codes to the barcode data
+Start/Stop codes can be A, B, C, or D
+For example, if you wanted to represent `1234` as a barcode you will need to enter something like `A1234A`. (You can replace the letters A with either A, B, C, or D)
+
+![Codabar Data Example](screenshots/Codabar%20Data%20Example.png "Codabar Data Example")
+
 ### Editing a barcode
 1) To edit a barcode click on `Edit Barcode`
 2) Next select the barcode file you want to edit

+ 3 - 0
barcode_app.h

@@ -26,6 +26,9 @@
 //the folder where the encodings are located
 #define BARCODE_DATA_FILE_DIR_PATH EXT_PATH("apps_data/barcode_data")
 
+//the folder where the codabar encoding table is located
+#define CODABAR_DICT_FILE_PATH BARCODE_DATA_FILE_DIR_PATH "/codabar_encodings.txt"
+
 //the folder where the code 39 encoding table is located
 #define CODE39_DICT_FILE_PATH BARCODE_DATA_FILE_DIR_PATH "/code39_encodings.txt"
 

+ 12 - 0
barcode_utils.c

@@ -43,6 +43,14 @@ void init_types() {
     code_128->start_pos = 0;
     barcode_type_objs[CODE128] = code_128;
 
+    BarcodeTypeObj* codabar = malloc(sizeof(BarcodeTypeObj));
+    codabar->name = "Codabar";
+    codabar->type = CODABAR;
+    codabar->min_digits = 1;
+    codabar->max_digits = -1;
+    codabar->start_pos = 0;
+    barcode_type_objs[CODABAR] = codabar;
+
     BarcodeTypeObj* unknown = malloc(sizeof(BarcodeTypeObj));
     unknown->name = "Unknown";
     unknown->type = UNKNOWN;
@@ -74,6 +82,10 @@ BarcodeTypeObj* get_type(FuriString* type_string) {
     if(furi_string_cmp_str(type_string, "CODE-128") == 0) {
         return barcode_type_objs[CODE128];
     }
+    if(furi_string_cmp_str(type_string, "Codabar") == 0) {
+        return barcode_type_objs[CODABAR];
+    }
+
 
     return barcode_type_objs[UNKNOWN];
 }

+ 2 - 1
barcode_utils.h

@@ -3,7 +3,7 @@
 #include <furi.h>
 #include <furi_hal.h>
 
-#define NUMBER_OF_BARCODE_TYPES 6
+#define NUMBER_OF_BARCODE_TYPES 7
 
 typedef enum {
     WrongNumberOfDigits, //There is too many or too few digits in the barcode
@@ -22,6 +22,7 @@ typedef enum {
     EAN13,
     CODE39,
     CODE128,
+    CODABAR,
 
     UNKNOWN
 } BarcodeType;

+ 61 - 0
barcode_validator.c

@@ -13,6 +13,9 @@ void barcode_loader(BarcodeData* barcode_data) {
     case CODE128:
         code_128_loader(barcode_data);
         break;
+    case CODABAR:
+        codabar_loader(barcode_data);
+        break;
     case UNKNOWN:
         barcode_data->reason = UnsupportedType;
         barcode_data->valid = false;
@@ -36,6 +39,7 @@ int calculate_check_digit(BarcodeData* barcode_data) {
         break;
     case CODE39:
     case CODE128:
+    case CODABAR:
     case UNKNOWN:
     default:
         break;
@@ -337,6 +341,63 @@ void code_128_loader(BarcodeData* barcode_data) {
     flipper_format_free(ff);
     furi_record_close(RECORD_STORAGE);
 
+    furi_string_cat(barcode_data->correct_data, barcode_bits);
+    furi_string_free(barcode_bits);
+}
+
+void codabar_loader(BarcodeData* barcode_data){
+    int barcode_length = furi_string_size(barcode_data->raw_data);
+
+    int min_digits = barcode_data->type_obj->min_digits;
+
+    //check the length of the barcode, must contain atleast a character,
+    //this can have as many characters as it wants, it might not fit on the screen
+    if(barcode_length < min_digits) {
+        barcode_data->reason = WrongNumberOfDigits;
+        barcode_data->valid = false;
+        return;
+    }
+
+    FuriString* barcode_bits = furi_string_alloc();
+
+    barcode_length = furi_string_size(barcode_data->raw_data);
+
+    //Open Storage
+    Storage* storage = furi_record_open(RECORD_STORAGE);
+    FlipperFormat* ff = flipper_format_file_alloc(storage);
+
+    if(!flipper_format_file_open_existing(ff, CODABAR_DICT_FILE_PATH)) {
+        FURI_LOG_E(TAG, "Could not open file %s", CODABAR_DICT_FILE_PATH);
+        barcode_data->reason = MissingEncodingTable;
+        barcode_data->valid = false;
+    } else {
+        FuriString* char_bits = furi_string_alloc();
+        for(int i = 0; i < barcode_length; i++) {
+            char barcode_char = toupper(furi_string_get_char(barcode_data->raw_data, i));
+
+            //convert a char into a string so it used in flipper_format_read_string
+            char current_character[2];
+            snprintf(current_character, 2, "%c", barcode_char);
+
+            if(!flipper_format_read_string(ff, current_character, char_bits)) {
+                FURI_LOG_E(TAG, "Could not read \"%c\" string", barcode_char);
+                barcode_data->reason = InvalidCharacters;
+                barcode_data->valid = false;
+                break;
+            } else {
+                FURI_LOG_I(
+                    TAG, "\"%c\" string: %s", barcode_char, furi_string_get_cstr(char_bits));
+                furi_string_cat(barcode_bits, char_bits);
+            }
+            flipper_format_rewind(ff);
+        }
+        furi_string_free(char_bits);
+    }
+
+    //Close Storage
+    flipper_format_free(ff);
+    furi_record_close(RECORD_STORAGE);
+
     furi_string_cat(barcode_data->correct_data, barcode_bits);
     furi_string_free(barcode_bits);
 }

+ 1 - 0
barcode_validator.h

@@ -10,4 +10,5 @@ void ean_8_loader(BarcodeData* barcode_data);
 void ean_13_loader(BarcodeData* barcode_data);
 void code_39_loader(BarcodeData* barcode_data);
 void code_128_loader(BarcodeData* barcode_data);
+void codabar_loader(BarcodeData* barcode_data);
 void barcode_loader(BarcodeData* barcode_data);

+ 22 - 0
encoding_tables/codabar_encodings.txt

@@ -0,0 +1,22 @@
+# alternates between bars and spaces, always begins with bar
+# 0 for narrow, 1 for wide
+0: 0000011
+1: 0000110
+2: 0001001
+3: 1100000
+4: 0010010
+5: 1000010
+6: 0100001
+7: 0100100
+8: 0110000
+9: 1001000
+-: 0001100
+$: 0011000
+:: 1000101
+/: 1010001
+.: 1010100
++: 0010101
+A: 0011010
+B: 0101001
+C: 0001011
+D: 0001110

BIN
screenshots/Codabar Data Example.png


+ 65 - 0
views/barcode_view.c

@@ -322,6 +322,68 @@ static void draw_code_128(Canvas* canvas, BarcodeData* barcode_data) {
         canvas, 62, y + height + 8, AlignCenter, AlignBottom, furi_string_get_cstr(raw_data));
 }
 
+static void draw_codabar(Canvas* canvas, BarcodeData* barcode_data){
+    FuriString* raw_data = barcode_data->raw_data;
+    FuriString* barcode_digits = barcode_data->correct_data;
+    //BarcodeTypeObj* type_obj = barcode_data->type_obj;
+
+    int barcode_length = furi_string_size(barcode_digits);
+    int total_pixels = 0;
+
+    for(int i = 0; i < barcode_length; i++) {
+        //1 for wide, 0 for narrow
+        char wide_or_narrow = furi_string_get_char(barcode_digits, i);
+        int wn_digit = wide_or_narrow - '0'; //wide(1) or narrow(0) digit
+
+        if(wn_digit == 1) {
+            total_pixels += 3;
+        } else {
+            total_pixels += 1;
+        }
+        if((i + 1) % 7 == 0) {
+            total_pixels += 1;
+        }
+    }
+
+    int x = (128 - total_pixels) / 2;
+    int y = BARCODE_Y_START;
+    int width = 1;
+    int height = BARCODE_HEIGHT;
+    bool filled_in = true;
+
+    //set the canvas color to black to print the digit
+    canvas_set_color(canvas, ColorBlack);
+    // canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignCenter, error);
+    canvas_draw_str_aligned(
+        canvas, 62, y + height + 8, AlignCenter, AlignBottom, furi_string_get_cstr(raw_data));
+
+    for(int i = 0; i < barcode_length; i++) {
+        //1 for wide, 0 for narrow
+        char wide_or_narrow = furi_string_get_char(barcode_digits, i);
+        int wn_digit = wide_or_narrow - '0'; //wide(1) or narrow(0) digit
+
+        if(filled_in) {
+            if(wn_digit == 1) {
+                x = draw_bits(canvas, "111", x, y, width, height);
+            } else {
+                x = draw_bits(canvas, "1", x, y, width, height);
+            }
+            filled_in = false;
+        } else {
+            if(wn_digit == 1) {
+                x = draw_bits(canvas, "000", x, y, width, height);
+            } else {
+                x = draw_bits(canvas, "0", x, y, width, height);
+            }
+            filled_in = true;
+        }
+        if((i + 1) % 7 == 0) {
+            x = draw_bits(canvas, "0", x, y, width, height);
+            filled_in = true;
+        }
+    }
+}
+
 static void barcode_draw_callback(Canvas* canvas, void* ctx) {
     furi_assert(ctx);
     BarcodeModel* barcode_model = ctx;
@@ -346,6 +408,9 @@ static void barcode_draw_callback(Canvas* canvas, void* ctx) {
         case CODE128:
             draw_code_128(canvas, data);
             break;
+        case CODABAR:
+            draw_codabar(canvas, data);
+            break;
         case UNKNOWN:
         default:
             break;

+ 1 - 1
views/create_view.c

@@ -448,7 +448,7 @@ void save_barcode(CreateView* create_view_object) {
 
         flipper_format_write_string_cstr(ff, "Version", FILE_VERSION);
 
-        flipper_format_write_comment_cstr(ff, "Types - UPC-A, EAN-8, EAN-13, CODE-39, CODE-128");
+        flipper_format_write_comment_cstr(ff, "Types - UPC-A, EAN-8, EAN-13, CODE-39, CODE-128, Codabar");
 
         flipper_format_write_string_cstr(ff, "Type", barcode_type->name);