PDFsharp & MigraDoc Foundation

PDFsharp - A .NET library for processing PDF & MigraDoc Foundation - Creating documents on the fly
It is currently Tue Jul 16, 2024 10:23 am

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules



Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: EAN13 Barcode class
PostPosted: Wed Jan 26, 2011 9:29 pm 
Offline

Joined: Wed Jan 26, 2011 9:21 pm
Posts: 2
I wrote a EAN13 barcode class that should be able to render correct EAN13 codes.

It's the first version and I didn't had the time to test a lot of barcodes yet... Any feedback is welcome, and of course you can use it in your own projects!

Good luck

Code:
#region PDFsharp - A .NET library for processing PDF
//
// Authors:
//   Sven Rymenants (mailto:sven.rymenants@gmail.com)
//
// http://www.pdfsharp.com
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#endregion

using System;
using System.Diagnostics;
using PdfSharp.Drawing;

namespace PdfSharp.Drawing.BarCodes
{
    /// <summary>
    /// Implementation of the EAN13 bar code.
    /// </summary>
    public class EAN13 : BarCode
    {
        private XRect m_leftBlock = new XRect();
        private XRect m_rightBlock = new XRect();

        /// <summary>
        /// Initializes a new instance of EAN13.
        /// </summary>
        public EAN13()
        : base("", XSize.Empty, CodeDirection.LeftToRight)
        {
        }

        /// <summary>
        /// Initializes a new instance of EAN13.
        /// </summary>
        public EAN13(string code)
        : base(code, XSize.Empty, CodeDirection.LeftToRight)
        {
        }

        /// <summary>
        /// Initializes a new instance of EAN13.
        /// </summary>
        public EAN13(string code, XSize size)
        : base(code, size, CodeDirection.LeftToRight)
        {
        }

        static bool[] Quite = new bool[] { false, false, false, false, false, false, false, false, false };
        static bool[] Leading = new bool[] { true, false, true };
        static bool[] Separator = new bool[] { false, true, false, true, false };

        static bool[][] OddLeftLines = new bool[][]
        {
             new bool[] { false, false, false, true, true, false, true },
             new bool[] { false, false, true, true, false, false, true },
             new bool[] { false, false, true, false, false, true, true },
             new bool[] { false, true, true, true, true, false, true },
             new bool[] { false, true, false, false, false, true, true },
             new bool[] { false, true, true, false, false, false, true },
             new bool[] { false, true, false, true, true, true, true },
             new bool[] { false, true, true, true, false, true, true },
             new bool[] { false, true, true, false, true, true, true },
             new bool[] { false, false, false, true, false, true, true }
         };

         static bool[][] EvenLeftLines = new bool[][]
         {
              new bool[] { false, true, false, false, true, true, true },
              new bool[] { false, true, true, false, false, true, true },
              new bool[] { false, false, true, true, false, true, true },
              new bool[] { false, true, false, false, false, false, true },
              new bool[] { false, false, true, true, true, false, true },
              new bool[] { false, true, true, true, false, false, true },
              new bool[] { false, false, false, false, true, false, true },
              new bool[] { false, false, true, false, false, false, true },
              new bool[] { false, false, false, true, false, false, true },
              new bool[] { false, false, true, false, true, true, true }
         };

        static bool[][] RightLines = new bool[][]
         {
              new bool[] { true, true, true, false, false, true, false},
              new bool[] { true, true, false, false, true, true, false},
              new bool[] { true, true, false, true, true, false, false},
              new bool[] { true, false, false, false, false, true, false},
              new bool[] { true, false, true, true, true, false, false},
              new bool[] { true, false, false, true, true, true, false},
              new bool[] { true, false, true, false, false, false, false},
              new bool[] { true, false, false, false, true, false, false},
              new bool[] { true, false, false, true, false, false, false},
              new bool[] { true, true, true, false, true, false, false}
         };
         
        /// <summary>
        /// Renders the bar code.
        /// </summary>
        protected internal override void Render(XGraphics gfx, XBrush brush, XFont font, XPoint position)
        {
            XGraphicsState state = gfx.Save();

            BarCodeRenderInfo info = new BarCodeRenderInfo(gfx, brush, font, position);
            InitRendering(info);
            info.CurrPosInString = 0;
            info.CurrPos = position - CodeBase.CalcDistance(AnchorType.TopLeft, this.anchor, this.size);

            //   EAN13 Barcode should be a total of 113 modules wide.
            int numberOfBars = 12; // The length - country code
            numberOfBars *= 7; // Each character has 7 bars
            numberOfBars += 2 * (Quite.Length + Leading.Length);
            numberOfBars += Separator.Length;
            info.ThinBarWidth = ((double)this.Size.Width / (double)numberOfBars);

            RenderStart(info);

            m_leftBlock.x = info.CurrPos.x + info.ThinBarWidth / 2;
            RenderLeft(info);
            m_leftBlock.Width = info.CurrPos.x - m_leftBlock.x;

            RenderSeparator(info);

            m_rightBlock.x = info.CurrPos.x;
            RenderRight(info);
            m_rightBlock.Width = info.CurrPos.x - m_rightBlock.x - info.ThinBarWidth / 2;

            RenderStop(info);

            if (this.TextLocation == TextLocation.BelowEmbedded)
                RenderText(info);

            gfx.Restore(state);
        }

        private void RenderStart(BarCodeRenderInfo info)
        {
            RenderValue(info, Quite);
            RenderValue(info, Leading);
        }

        private void RenderLeft(BarCodeRenderInfo info)
        {
            int country = (int)(this.text[0] - '0');
            string text = this.text.Substring(1, 6);

            switch(country)
            {
                case 0:
                    foreach (char ch in text)
                        RenderDigit(info, ch, OddLeftLines);
                    break;

                case 1:
                    RenderDigit(info, text[0], OddLeftLines);
                    RenderDigit(info, text[1], OddLeftLines);
                    RenderDigit(info, text[2], EvenLeftLines);
                    RenderDigit(info, text[3], OddLeftLines);
                    RenderDigit(info, text[4], EvenLeftLines);
                    RenderDigit(info, text[5], EvenLeftLines);
                    break;

                case 2:
                    RenderDigit(info, text[0], OddLeftLines);
                    RenderDigit(info, text[1], OddLeftLines);
                    RenderDigit(info, text[2], EvenLeftLines);
                    RenderDigit(info, text[3], EvenLeftLines);
                    RenderDigit(info, text[4], OddLeftLines);
                    RenderDigit(info, text[5], EvenLeftLines);
                    break;

                case 3:
                    RenderDigit(info, text[0], OddLeftLines);
                    RenderDigit(info, text[1], OddLeftLines);
                    RenderDigit(info, text[2], EvenLeftLines);
                    RenderDigit(info, text[3], EvenLeftLines);
                    RenderDigit(info, text[4], EvenLeftLines);
                    RenderDigit(info, text[5], OddLeftLines);
                    break;

                case 4:
                    RenderDigit(info, text[0], OddLeftLines);
                    RenderDigit(info, text[1], EvenLeftLines);
                    RenderDigit(info, text[2], OddLeftLines);
                    RenderDigit(info, text[3], OddLeftLines);
                    RenderDigit(info, text[4], EvenLeftLines);
                    RenderDigit(info, text[5], EvenLeftLines);
                    break;

                case 5:
                    RenderDigit(info, text[0], OddLeftLines);
                    RenderDigit(info, text[1], EvenLeftLines);
                    RenderDigit(info, text[2], EvenLeftLines);
                    RenderDigit(info, text[3], OddLeftLines);
                    RenderDigit(info, text[4], OddLeftLines);
                    RenderDigit(info, text[5], EvenLeftLines);
                    break;

                case 6:
                    RenderDigit(info, text[0], OddLeftLines);
                    RenderDigit(info, text[1], EvenLeftLines);
                    RenderDigit(info, text[2], EvenLeftLines);
                    RenderDigit(info, text[3], EvenLeftLines);
                    RenderDigit(info, text[4], OddLeftLines);
                    RenderDigit(info, text[5], OddLeftLines);
                    break;

                case 7:
                    RenderDigit(info, text[0], OddLeftLines);
                    RenderDigit(info, text[1], EvenLeftLines);
                    RenderDigit(info, text[2], OddLeftLines);
                    RenderDigit(info, text[3], EvenLeftLines);
                    RenderDigit(info, text[4], OddLeftLines);
                    RenderDigit(info, text[5], EvenLeftLines);
                    break;

                case 8:
                    RenderDigit(info, text[0], OddLeftLines);
                    RenderDigit(info, text[1], EvenLeftLines);
                    RenderDigit(info, text[2], OddLeftLines);
                    RenderDigit(info, text[3], EvenLeftLines);
                    RenderDigit(info, text[4], EvenLeftLines);
                    RenderDigit(info, text[5], OddLeftLines);
                    break;

                case 9:
                    RenderDigit(info, text[0], OddLeftLines);
                    RenderDigit(info, text[1], EvenLeftLines);
                    RenderDigit(info, text[2], EvenLeftLines);
                    RenderDigit(info, text[3], OddLeftLines);
                    RenderDigit(info, text[4], EvenLeftLines);
                    RenderDigit(info, text[5], OddLeftLines);
                    break;
            }
        }

        private void RenderDigit(BarCodeRenderInfo info, char digit, bool[][] lines)
        {
            int index = digit - '0';
            RenderValue(info, lines[index]);
        }

        private void RenderSeparator(BarCodeRenderInfo info)
        {
            RenderValue(info, Separator);
        }

        private void RenderRight(BarCodeRenderInfo info)
        {
            string text = this.text.Substring(7);

            if (this.text.Length == 12)
                text += CalculateChecksumDigit(this.text);

            foreach (char ch in text)
                RenderDigit(info, ch, RightLines);
        }

        private void RenderStop(BarCodeRenderInfo info)
        {
            RenderValue(info, Leading);
            RenderValue(info, Quite);
        }

        private void RenderValue(BarCodeRenderInfo info, bool[] value)
        {
            foreach(bool bar in value)
            {
                if (bar)
                {
                    XRect rect = new XRect(info.CurrPos.X, info.CurrPos.Y, info.ThinBarWidth, Size.Height);
                    info.Gfx.DrawRectangle(info.Brush, rect);
                }
                info.CurrPos.X += info.ThinBarWidth;
            }
        }

        private void RenderText(BarCodeRenderInfo info)
        {
            if (info.Font == null)
                info.Font = new XFont("Courier New", Size.Height / 4);
            XPoint center = info.Position + CodeBase.CalcDistance(this.anchor, AnchorType.TopLeft, this.size);
            XSize textSize = info.Gfx.MeasureString(this.text, info.Font);

            double height = textSize.height;
            double y = info.Position.y + Size.Height - textSize.height;

            m_leftBlock.Height = height;
            m_leftBlock.y = y;

            m_rightBlock.Height = height;
            m_rightBlock.y = y;

            XPoint pos = new XPoint(info.Position.x, y);
            info.Gfx.DrawString(this.text.Substring(0, 1), info.Font, info.Brush, new XRect(pos, Size), XStringFormats.TopLeft);

            info.Gfx.DrawRectangle(XBrushes.White, m_leftBlock);
            info.Gfx.DrawString(this.text.Substring(1, 6), info.Font, info.Brush, m_leftBlock, XStringFormats.TopCenter);

            info.Gfx.DrawRectangle(XBrushes.White, m_rightBlock);

            string text = this.text.Substring(7);
            if (this.text.Length == 12)
                text += CalculateChecksumDigit(this.text);

            info.Gfx.DrawString(text, info.Font, info.Brush, m_rightBlock, XStringFormats.TopCenter);
        }

        private string CalculateChecksumDigit(string text)
        {
            bool odd = false;
            int sum = 0;
            foreach (char ch in text)
            {
                sum += (ch - '0') * (odd ? 3 : 1);
                odd = !odd;
            }
            int result = (10 - (sum % 10)) % 10;
            return result.ToString();
        }

        /// <summary>Validates the text string to be coded</summary>
        /// <param name="text">String - The text string to be coded</param>
        protected override void CheckCode(string text)
        {
            if (text == null) throw new ArgumentNullException("Parameter text (string) can not be null");
            if (text.Length != 12) throw new ArgumentException("Parameter text (string) can not have more or less than 12 characters");
        }
    }
}


Top
 Profile  
Reply with quote  
 Post subject: Re: EAN13 Barcode class
PostPosted: Thu Oct 20, 2011 4:41 pm 
Offline

Joined: Thu Oct 20, 2011 4:33 pm
Posts: 3
This is great but i cant seem to get my program to compile when i include your EAN class
I'm a bit of a novice

namespace SCJohnson.Spt.Reports
{
public class PdfBSReport_SMart
{
public class EAN13 : BarCode
{
<your code>
}
}
}

I receive the following error when i build:
PdfSharp.Drawing.BarCodes.BarCodeRenderInfo' is inaccessible due to its protection level

Any help would be much appreciated.


Top
 Profile  
Reply with quote  
 Post subject: Re: EAN13 Barcode class
PostPosted: Thu Oct 20, 2011 9:46 pm 
Offline

Joined: Wed Jan 26, 2011 9:21 pm
Posts: 2
You need to place it in the PdfSharp\PdfSharp.Drawing.BarCodes directory of the project itself.
And compile the dll again.


Top
 Profile  
Reply with quote  
 Post subject: Re: EAN13 Barcode class
PostPosted: Fri Oct 21, 2011 3:04 pm 
Offline

Joined: Thu Oct 20, 2011 4:33 pm
Posts: 3
sven, I'm sorry I really appreciate your help with this. I'm very anxious to give this a try.

When you say place it in the pdfsharp\pdfsharp.drawings.Barcodes directory...what is "it" and how do i place it in the directory.
I mentioned that I am a novice at this so please don't assume anything is obvious to me.
Can you be very specific and elementary at explaining how to get this to work. I'd like to give it a try. Thanks so much for your patience.

I have a program that currently generates a barcode using the Code3of9Standard format.

Here is the call to GenBarCode:
GenBarCode(page, 425, 140, W3, H3, "012345678901");

Here is the routine that generates the barcode
public void GenBarCode (PdfPage in_page, int in_x_start, int in_y_start, double in_width, double in_height, string BarCode_In)
{
for ( int i=0; i < this.Document.Pages.Count; i++ )
{
PdfPage page = this.Document.Pages[i];
using (XGraphics gfx = XGraphics.FromPdfPage(in_page))
{
double width = in_width;
double height = in_height;

width *= ConversionRatio;
height *= ConversionRatio;

PdfSharp.Drawing.BarCodes.Code3of9Standard BarCode_O = new PdfSharp.Drawing.BarCodes.Code3of9Standard();

BarCode_O.TextLocation = new PdfSharp.Drawing.BarCodes.TextLocation();
BarCode_O.Text = BarCode_In;
BarCode_O.StartChar = Convert.ToChar("*");
BarCode_O.EndChar = Convert.ToChar("*");
BarCode_O.Direction = PdfSharp.Drawing.BarCodes.CodeDirection.LeftToRight;
XFont fontBARCODE = new XFont("Arial", 14, XFontStyle.Regular);
XSize BARCODE_SIZE = new XSize(new XPoint(width, height));
BarCode_O.Size = BARCODE_SIZE;

gfx.DrawBarCode(BarCode_O, XBrushes.Black, fontBARCODE, new XPoint(Convert.ToDouble(in_x_start), Convert.ToDouble(in_y_start)));

// Define a rotation transformation at the center of the page
gfx.TranslateTransform(page.Width / 2, page.Height / 2);
gfx.RotateTransform(-Math.Atan(page.Height / page.Width) * 180 / Math.PI);
gfx.TranslateTransform(-page.Width / 2, -page.Height / 2);
}
}
}

What changes do I make to get the barcode to be in EAN format? UPC-A would be most preferrable.


Top
 Profile  
Reply with quote  
 Post subject: Re: EAN13 Barcode class
PostPosted: Mon Oct 24, 2011 5:30 pm 
Offline

Joined: Mon Oct 17, 2011 8:55 am
Posts: 2
I've got the same compilation error:

PdfSharp.Drawing.BarCodes.EAN13.Render(PdfSharp.Drawing.XGraphics, PdfSharp.Drawing.XBrush, PdfSharp.Drawing.XFont, PdfSharp.Drawing.XPoint)': cannot change access modifiers when overriding 'protected' inherited member 'PdfSharp.Drawing.BarCodes.BarCode.Render(PdfSharp.Drawing.XGraphics, PdfSharp.Drawing.XBrush, PdfSharp.Drawing.XFont, PdfSharp.Drawing.XPoint)

What can I do to fix it?

Thanks


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 46 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Privacy Policy, Data Protection Declaration, Impressum
Powered by phpBB® Forum Software © phpBB Group