OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Blame | Last modification | View Log | RSS feed

package org.openconcerto.modules.label.graphicspl;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.openconcerto.utils.ImageUtils;
import org.openconcerto.utils.StringUtils;

public class ZPLRenderer extends GPLRenderer {

    private StringBuilder sb = new StringBuilder();

    public ZPLRenderer() {
        sb.append("^XA\n^CI28\n");
    }

    @Override
    public void drawText(int x, int y, String text, int align, String fontName, int fontSize, Color color, int maxWidth, boolean wrap) {
        sb.append("^CF0,");
        sb.append(fontSize);
        //

        if (align == ALIGN_RIGHT) {
            sb.append("^FO");
            sb.append('0');
            sb.append(',');
            sb.append(y);
            sb.append("^FB");
            sb.append(x);
            sb.append(",9999,0");

            sb.append(",R,0");
        } else if (align == ALIGN_CENTER) {
            sb.append("^FO");
            sb.append('0');
            sb.append(',');
            sb.append(y);
            sb.append("^FB");
            sb.append(x * 2);
            sb.append(",9999,0");

            sb.append(",C,0");
        } else {
            sb.append("^FO");
            sb.append(x);
            sb.append(',');
            sb.append(y);

            //
            sb.append("^FB");
            sb.append(maxWidth);
            sb.append(",9999,0");

            sb.append(",L,0");
        }
        //

        sb.append("^FD");
        sb.append(text);
        if (align == ALIGN_CENTER) {
            sb.append("\\&");
        }

        sb.append("^FS\n");
    }

    @Override
    public void drawImage(int x, int y, int w, int h, BufferedImage img) {
        try {
            if (w != img.getWidth() || h != img.getHeight()) {
                img = ImageUtils.createQualityResizedImage(img, w, h);
            }

            final int bytesPerRow = (img.getWidth() + 7) / 8;
            int size = bytesPerRow * img.getHeight();
            byte[] data = getData(img);
            sb.append("^FO");
            sb.append(x);
            sb.append(",");
            sb.append(y);
            sb.append("^GFA");
            sb.append(",");
            sb.append(size);
            sb.append(",");
            sb.append(size);
            sb.append(",");
            sb.append(bytesPerRow);
            sb.append(",");
            sb.append(StringUtils.bytesToHexString(data));
            sb.append("^FS\n");
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }

    byte[] getData(BufferedImage img) throws IOException {

        ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
        int width = img.getWidth();

        int height = img.getHeight();
        // Lines
        for (int i = 0; i < height; i++) {
            int[] pixels = new int[width];
            img.getRGB(0, i, width, 1, pixels, 0, 4);
            final byte[] encodedLine = encodeLine(pixels);
            out.write(encodedLine);
        }
        return out.toByteArray();
    }

    private byte[] encodeLine(int[] pixels) throws IOException {
        final int bytesPerRow = (pixels.length + 7) / 8;
        byte[] bytesToEncode = new byte[bytesPerRow];
        int index = 0;
        for (int i = 0; i < bytesToEncode.length; i++) {
            int points = 0;
            for (int j = 0; j < 8; j++) {

                int c = 0;
                if (index < pixels.length) {
                    c = pixels[index];
                    int a = (c & 0xff000000) >> 24;
                    int r = (c & 0x00ff0000) >> 16;
                    int g = (c & 0x0000ff00) >> 8;
                    int b = c & 0x000000ff;
                    int grayScale = (int) (21.2671 * r + 71.5160 * g + 7.2169 * b);
                    boolean isBlack = grayScale < 12000;
                    points = points * 2;
                    if (isBlack && a < 0) {
                        points++;
                    }

                } else {
                    points = points * 2;
                }

                index++;
            }
            bytesToEncode[i] = (byte) points;

        }
        return bytesToEncode;
    }

    @Override
    public void fillRectangle(int x, int y, int w, int h, Color color) {
        sb.append("^FO");
        sb.append(x);
        sb.append(',');
        sb.append(y);

        sb.append("^GB");
        sb.append(w);
        sb.append(',');
        sb.append(h);
        sb.append(',');
        sb.append(Math.min(w, h));
        sb.append("^FS\n");

    }

    @Override
    public void drawRectangle(int x, int y, int w, int h, Color color, int lineWidth) {
        sb.append("^FO");
        sb.append(x);
        sb.append(',');
        sb.append(y);

        sb.append("^GB");
        sb.append(w);
        sb.append(',');
        sb.append(h);
        sb.append(',');
        sb.append(lineWidth);
        sb.append("^FS\n");
    }

    @Override
    public void drawBarcode(int x, int y, int h, int type, String code, int moduleWidth, int fontSize) {
        code = code.trim();
        sb.append("^FO");
        sb.append(x);
        sb.append(',');
        sb.append(y);
        sb.append("^CF0,");
        sb.append(fontSize);
        if (type == BARCODE_EAN13) {
            sb.append("^BY");
            sb.append(moduleWidth);

            sb.append("^BEN,");
            sb.append(h);
            sb.append(",Y,N");

        } else if (type == BARCODE_EAN8) {
            sb.append("^BY");
            sb.append(moduleWidth);

            sb.append("^B8N,");
            sb.append(h);
            sb.append(",Y,N");

        } else if (type == BARCODE_DATAMATRIX) {
            sb.append("^BXN,");
            sb.append(moduleWidth);
            sb.append(",200");
        } else if (type == BARCODE_CODE128) {
            sb.append("^BY");
            sb.append(moduleWidth - 1);
            sb.append("^BCN,");
            sb.append(h);
            sb.append(",Y,N,Y,D");

        } else if (type == BARCODE_CODE128_GS1) {
            sb.append("^BY");
            sb.append(moduleWidth - 1);
            sb.append("^BCN,");
            sb.append(h);
            sb.append(",Y,N,Y,N");

        }
        sb.append("^FD");
        sb.append(code);
        sb.append("^FS\n");
    }

    public String getZPL() {
        return sb.toString() + "\n^XZ";
    }

}