cEthar
cEthar

Reputation: 29

flutter zpl center text

I'm using Flutter to print data on a thermal printer by sending Zebra Programming Language (ZPL) code. I want to center-align text within the label, but I keep having trouble calculating the correct starting X position for centering. The text is always off-center, even though I'm trying to calculate its width.

The way I'm approaching this is to:

Estimate the width of the text using an average character width based on the font size. Calculate the starting X position for the text to center it, by subtracting half of the text width from the center of the label. Despite this logic, the text still appears off-center, especially when using Arabic text or other non-Latin fonts. I'm not sure if my estimation method is flawed, or if there's a better way to do this in ZPL.

String generateZplLabel({
  required String firstTextLine,
  required String secondTextLine,
  required String barcodeValue,
  required int fontSize,
}) {
  // Set label width and height in dots (assuming 203 dpi for a 6x4 cm label)
  int labelWidthDots = 480; // 6 cm width in dots
  int labelHeightDots = 320; // 4 cm height in dots

  // Function to estimate width per character in dots based on font size
  int estimateCharWidth(int fontSize) {
    return (fontSize / 2).round(); // Rough estimate: character width is about half the font size
  }

  // Function to estimate total text width
  int estimateTextWidth(String text, int fontSize) {
    int charWidth = estimateCharWidth(fontSize);
    return text.length * charWidth;
  }

  // Calculate the center X position for the label
  int centerX = labelWidthDots ~/ 2;

  // Estimate width of the first text line and calculate its X position
  int firstTextWidth = estimateTextWidth(firstTextLine, fontSize);
  int firstTextX = centerX - (firstTextWidth ~/ 2);

  // Estimate width of the second text line and calculate its X position
  int secondTextWidth = estimateTextWidth(secondTextLine, fontSize);
  int secondTextX = centerX - (secondTextWidth ~/ 2);

  // Set barcode X position manually to align it better (previously observed as ideal)
  int barcodeX = 20;

  // Generate the ZPL data with dynamic values
  return '''
^XA                                  // Start of label format
^PW$labelWidthDots                   // Set label width to 480 dots (6 cm)
^LL$labelHeightDots                  // Set label length to 320 dots (4 cm)
^CI28                                // Use character set 28 (Unicode)

// First Line of Text - Centered Manually for Arabic
^FT$firstTextX,80                    // Set field origin for first line (centered manually based on estimated text width)
^A@N,$fontSize,$fontSize,E:TT0003M_.FNT // Set font size dynamically using the provided value
^FD$firstTextLine^FS                 // Field data for dynamic first line

// Second Line of Text - Centered Manually
^FT$secondTextX,140                  // Set field origin for second line (centered manually based on estimated text width)
^A@N,$fontSize,$fontSize,E:TT0003M_.FNT // Set font size dynamically using the provided value
^FD$secondTextLine^FS                // Field data for dynamic second line

// Barcode Section - Manually Adjusted for Centering
^BY3,2,100                           // Set barcode parameters: Module width = 3, Height = 100 dots
^FT$barcodeX,260                     // Set field origin for barcode manually to X=20
^BCN,100,Y,N                         // Code 128 Barcode: No rotation, height=100 dots, with human-readable text below
^FD$barcodeValue^FS                  // Field data for dynamic barcode value

^XZ                                  // End of label format
''';
}

Upvotes: 0

Views: 48

Answers (1)

EdHayes3
EdHayes3

Reputation: 1954

Use the Field Block ^FB Command; Parameter D is the justification, here set to C for center

^FT250,600^A0B,28,28^FB600,1,0,C^FH\^FDTEXT_TO_REPLACE^FS

Upvotes: 1

Related Questions