Search code examples
.netitextitext7datamatrix

Changing the size of a module in BarcodeDataMatrx crops the code image


I am adding a BarcodeDataMatrix to an existing pdf document. Since this document is automatically processed, the size of each module must be according to the speicification of the automation (that is higher than the default generated).

This can be done by using barcode.CreateFormX((Canvas)null, moduleSize, pdfDocument) where moduleSize is a number that influences the size of each point in the code.

The problem I am running into is: Whenever I set the moduleSize >1, the code is cropped, that is parts on top and the right are missing.

When I looked into the source I found this:

        public virtual Rectangle PlaceBarcode(PdfCanvas canvas, Color foreground, float moduleSide) {
        if (image == null) {
            return null;
        }
        if (foreground != null) {
            canvas.SetFillColor(foreground);
        }
        int w = width + 2 * ws;
        int h = height + 2 * ws;
        int stride = (w + 7) / 8;
        for (int k = 0; k < h; ++k) {
            int p = k * stride;
            for (int j = 0; j < w; ++j) {
                int b = image[p + j / 8] & 0xff;
                b <<= j % 8;
                if ((b & 0x80) != 0) {
                    canvas.Rectangle(j * moduleSide, (h - k - 1) * moduleSide, moduleSide, moduleSide);
                }
            }
        }
        canvas.Fill();
        return GetBarcodeSize();
    }

and

        public virtual PdfFormXObject CreateFormXObject(Color foreground, float moduleSide, PdfDocument document) {
        PdfFormXObject xObject = new PdfFormXObject((Rectangle)null);
        Rectangle rect = PlaceBarcode(new PdfCanvas(xObject, document), foreground, moduleSide);
        xObject.SetBBox(new PdfArray(rect));
        return xObject;
    }

So CreateFormX calls PlaceBarcode goes over each 'line' in the barcode and draws rectangles of modulSize [units]. It returns however a rectangle with the barcodesize in number of modules. So this means, that for every value of moduleSize > 1, the returned rect is too small. And after Placebarcode returns, CreateFormX does a SetBBox() with the returned rect, which in my opinion is for every moduleSize > 1 too small.

Now the question: Is my analysis wrong, and if so, how can I resolve my issues?

My approach to solve it for now is call PlaceBarcode directly and add the barcode more or lesss manually to the page.


Solution

  • This code works (instead of the call to CreateFormXObject:

            PdfFormXObject bcdObject = new PdfFormXObject((Rectangle)null);
            barcode.PlaceBarcode( new PdfCanvas( bcdObject, pdfDocument ), iText.Kernel.Colors.ColorConstants.BLACK, moduleSize);
            Rectangle r = new Rectangle( barcode.GetHeight() * moduleSize, barcode.GetWidth() * moduleSize );
            bcdObject.SetBBox(new PdfArray(r));
    

    If a I am not mistaken, the error is in the last line of PlaceBarcode():

     return GetBarcodeSize();
    

    should read

     return GetBarcodeSize(, modulSide, ModulSide );
    

    instead.