6 Replies Latest reply on Sep 13, 2018 9:19 AM by Steven Moore

# How to center text on Card?

I am having trouble center aligning text on a card for a Zebra ZXP Series 3 using the Card Printing SDK.

I found in one of your examples codes how to center a barcode for the Card. But how can I center text for a card?

For example, for a barcode its:

// Barcode Drawing---------------------------------------------------

int rotation = 0; // origin lower left and no rotation

int barcodeType = 0; // Code 39

int barcodeWidthRatio = 2; // narrow bar = 2 dots, wide bar = 5 dots

int barcodeMultiplier = 2; // {2..9}

int barcodeHeight = 75; // 75 dots

int textUnder = 1; // true

string barcodeData = "123456789";

//To calculate the full length of a Code 39 bar code:

//L = [(C+2) (3R + 7) - 1] X Where

//L = Length of bar code

//C = Number of characters

//R = Ratio of wide-to-narrow bars

//X = Number of dots times 0.0033 inches per dot (0.08847 mm per dot); for the 5:2 ratio, X = Dots times 2

//See ZXP3 SDK Manual for the forumulas used to calcuate the length of other barcode types.

// Calculate the length of the barcode

int C = barcodeData.Length;

double R = 5.0 / 2.0;

int X = 2;

int length = (int)((C + 2) * (3 * R + 7) - 1) * X;

int startX = (int)Math.Floor((CARD_WIDTH - length) / 2.0); //Center barcode horizontally

int startY = (int)Math.Floor(((CARD_HEIGHT - barcodeHeight) / 2.0) + barcodeHeight); //Center barcode vertically

// Sends Barcode data to the Monochrome Buffer

if (DrawBarcode(startX, startY, rotation, barcodeType, barcodeWidthRatio, barcodeMultiplier, barcodeHeight, textUnder, _asciiEncoder.GetBytes(barcodeData), out errValue) == 0)

{

msg = "Printing DrawBarcode Error: " + errValue.ToString();

return;

}

But how and where can i find the formula for centering a label / text on a card??? It says it's in the manual but it isn't can someone please provide this formula?

• ###### Re: How to center text on Card?

As of right now, I am having to manually pad the text left and right in C# to try and get it to appear “centered” on the card. I have different font sizes on the card so It’s really hard when I don’t know the formula on how to center the text on the card. If I could just get the formula, the generic formula to center any text on the card – that would fix my issue! I am only printing on the front side of the card and it is just text.

Right now I am using this to pad my text with spaces left and right. It's sketchy and it appears to look centered in some cases but there may be cases where it isn't. I of course can't sit here and test the 3 billion different name combinations I may be putting on the card.

public string SetTextAlignmentToCenter(string textToCenterAlign, int lengthOfLine)

{

// # of Characters you can put per line on the Badge. Badge is Landscape Orientation

return centeredText;

}

1 of 1 people found this helpful
• ###### Re: How to center text on Card?

I stopped using the graphics methods used in the sdk for this reason. I extracted the .net graphics object that the zebra graphics sdk uses to print to a card. I use the following routine to get access to it.

internal static System.Drawing.Graphics GetGraphicsObject(ref ZMTGraphics.ZMotifGraphics g)

{

System.Reflection.FieldInfo dynField = g.GetType().GetField("helper", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);

object gg = dynField.GetValue(null);

return (System.Drawing.Graphics)gg.GetType().GetField("graphics").GetValue(gg);

}

The reason I came up with this methods was because I needed to measure a string to be able to shrink to fit and the sdk doesn't provide a public method to do it.

If I were printing on the landscape on a black panel then I'd do

int datalen;

byte[] bmpFrontMonoKPanels;

ZMTGraphics.ZMotifGraphics g = new ZMTGraphics.ZMotifGraphics();

System.Drawing.Drawing2D.GraphicsState gfxstate;

g.ClearGraphics();

g.InitGraphics(0, 0, ZMTGraphics.ZMotifGraphics.ImageOrientationEnum.Landscape, ZMTGraphics.ZMotifGraphics.RibbonTypeEnum.MonoK);

gfx = GetGraphicsObject(ref g);

gfxstate = gfx.Save();

<use the .net system.drawing.graphics gfx object to do my printing>

gfx.Restore(gfxstate);

bmpFrontMonoKPanels = g.CreateBitmap(out dataLen);

g.ClearGraphics();

You just need to use the standard methods for drawing objects i.e. exactly the same as when printing to the old printer object. So finally to draw centred text, create a rectangle that's as big as the region you want the text to appear in, then use the gfx.drawstring overload that has the system.drawing.stringformat and use that to centre the text. No need to pad the string or calculate anything, unless it's too big to fit.

1 of 1 people found this helpful
• ###### Re: How to center text on Card?

Unfortunately I do not have the ZMTGraphics. I am using the ZXP 3 not the ZXP 7

I only have:

ZBRGraphics.cs

ZBRPrinter.cs

There still has to be a formula to calculate how to horizontally center the text on a card. They have a formula to calculate centering a bar code above in my OP - so  I just need them to provide me the one for the text

• ###### Re: How to center text on Card?

Yep, sorry though you'd switched to the driverless sdk not the older one as the driverless zxp3 uses the same graphics library as the 7.

Have a look at the ZBRGDIDrawTextRectEx function, as it provides an alignment parameter. Similar to what I said for the 7, create a rectangle that covers the area you want the text to appear and then pass it's position, size and text alignment along with the text and font. Notes on the routine at on page 148 of the sdk manual.

1 of 1 people found this helpful
• ###### Re: How to center text on Card?

After hours of fighting with the text alignment I finally got a response from Zebra. You have to use the DrawTextEx() method and pass it in the alignment parameter

[DllImport("ZBRGraphics.dll", EntryPoint = "ZBRGDIDrawTextEx", CharSet = CharSet.Auto,

SetLastError = true)]

static extern int ZBRGDIDrawTextEx(int x, int y, int angle, int alignment, byte[] text, byte[] font, int fontSize, int fontStyle, int color, out int err);

public int DrawTextEx(int x, int y, int angle, int alignment, byte[] text, byte[] font, int fontSize, int fontStyle, int color, out int err)

{

return ZBRGDIDrawTextEx(x, y, angle, alignment, text, font, fontSize, fontStyle, color, out err);

}

How to use it (from the "SDK Manual"):

int x = 0;

int y = 0;

int angle = 0; //0 degrees rotation (no rotation)

int alignment = 4; //center justified

string TextToPrint = "Printed Text";

byte[] text = null;

string FontToUse = "Arial";

byte[] font = null;

int fontSise = 12;

int fontStyle = 1; //bold

int color = 0x0FF0000; //black

int err = 0;

int result = 0;

//use the function:

System.Text.ASCIIEncoding ascii = new System.Text.ASCIIEncoding();

text = ascii.GetBytes(TextToPrint);

font = ascii.GetBytes(FontToUse);

result = ZBRGDIDrawTextEx(x, y, angle, alignment, text, font, fontSize,fontStyle, color, out err);

1 of 1 people found this helpful
• ###### Re: How to center text on Card?

This is a total hack, and I am not sure it is accurate, but printing is basically centered on a vertical card using this calculation:

printVal is the text to print.  The Y coordinate is fixed.  X is variable.

// center name

// 2.11667 is mm/letter for Ariel 6 pt.

// 12 is dots per mm

// 2 splits it in half for the offset

//15.66 is estimated dots per letter at Ariel 8 pt

if (param == "name")

{

int m_length = (int)Math.Round((((printVal.Length) * 15.66) / 2), MidpointRounding.AwayFromZero);

int m_xcor = paramVal.XCor - m_length;

//Draw a Text

//retValue = graphics.DrawText(m_xcor, paramVal.YCor, ASCIIEncoding.ASCII.GetBytes(printVal),

//         ASCIIEncoding.ASCII.GetBytes(paramVal.Font), paramVal.FontSize, lookup[paramVal.FontStyle].Single(),

//         Convert.ToInt32(paramVal.FontColor, 16), out errValue);

retValue = graphics.DrawText(m_xcor, paramVal.YCor, ASCIIEncoding.Default.GetBytes(printVal),

ASCIIEncoding.ASCII.GetBytes(paramVal.Font), paramVal.FontSize, lookup[paramVal.FontStyle].Single(),

Convert.ToInt32(paramVal.FontColor, 16), out errValue);

}