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?

Joshua Preston
As of right now, I am having

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

            string centeredText = textToCenterAlign.PadLeft(((lengthOfLine - textToCenterAlign.Length) / 2) + textToCenterAlign.Length).PadRight(lengthOfLine);

            return centeredText;

        }

Vote: 
Vote up!
Vote down!

Points: 1

You voted ‘up’


Stephen Troup
I stopped using the graphics

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.

Vote: 
Vote up!
Vote down!

Points: 1

You voted ‘up’


Joshua Preston
Unfortunately I do not have

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

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Stephen Troup
Yep, sorry though you'd

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.

Vote: 
Vote up!
Vote down!

Points: 1

You voted ‘up’


Joshua Preston
After hours of fighting with

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);

Vote: 
Vote up!
Vote down!

Points: 1

You voted ‘up’


Steven Moore
This is a total hack, and I

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);

}

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Log in to post comments