<commit_before>/**
 * @author <NAME>
 *
 * Copyright (C) 2013 <NAME>, QZ Industries
 *
 * IMPORTANT: This software is dual-licensed
 *
 * LGPL 2.1 This is free software. This software and source code are released
 * under the "LGPL 2.1 License". A copy of this license should be distributed
 * with this software. http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * QZ INDUSTRIES SOURCE CODE LICENSE This software and source code *may* instead
 * be distributed under the "QZ Industries Source Code License", available by
 * request ONLY. If source code for this project is to be made proprietary for
 * an individual and/or a commercial entity, written permission via a copy of
 * the "QZ Industries Source Code License" must be obtained first. If you've
 * obtained a copy of the proprietary license, the terms and conditions of the
 * license apply only to the licensee identified in the agreement. Only THEN may
 * the LGPL 2.1 license be voided.
 *
 */
package qz;

import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;
import com.sun.pdfview.PDFRenderer;
import qz.common.LogIt;
import qz.printer.PaperFormat;
import qz.utils.SystemUtilities;

import javax.imageio.ImageIO;
import javax.print.PrintService;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.MediaSize;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.awt.image.ColorModel;
import java.awt.print.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Logger;
import java.util.Arrays;


/**
 *
 * @author <NAME>, <NAME>
 */
public class PrintPostScript implements Printable {

    public static final Logger log = Logger.getLogger(PrintPostScript.class.getName());

    private final AtomicReference<BufferedImage> bufferedImage = new AtomicReference<BufferedImage>(null);
    private final AtomicReference<ByteBuffer> bufferedPDF = new AtomicReference<ByteBuffer>(null);
    private final AtomicReference<PDFFile> pdfFile = new AtomicReference<PDFFile>(null);
    private final AtomicReference<PrintService> printServiceAtomicReference = new AtomicReference<PrintService>(null);
    private final AtomicReference<String> jobName = new AtomicReference<String>("jZebra 2D Printing");
    private final AtomicReference<Paper> paper = new AtomicReference<Paper>(null);
    private final AtomicReference<PaperFormat> paperSize = new AtomicReference<PaperFormat>(null);
    private final AtomicReference<Float> pixelsPerInch = new AtomicReference<Float>(null);
    private final AtomicReference<Integer> copies = new AtomicReference<Integer>(null);
    private final AtomicReference<Boolean> logPostScriptFeatures = new AtomicReference<Boolean>(false);
    public static final float DPI = 72f;
    //Never used, OK to delete?
    //public static final float MMPI = 280f;
    private String pdfClass;

    public PrintPostScript() {
    }
    
    /**
     * Rotates a buffered image by the specified angle in radians.
     * Note:  To rotate in degrees convert to radians first using:
     * <code>Math.toRadians(degree);</code>
     * @param image BufferedImage to rotate
     * @param angle in radians
     * @return Rotated image data
     */
    public static BufferedImage rotate(BufferedImage image, double angle) {
        LogIt.log("Rotating image " + angle);
        double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
        int w = image.getWidth(), h = image.getHeight();
        int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin);
        GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDefaultConfiguration();
        BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
        Graphics2D g = result.createGraphics();
        g.translate((neww-w)/2, (newh-h)/2);
        g.rotate(angle, w/2, h/2);
        g.drawRenderedImage(image, null);
        g.dispose();
        return result;
    }

    /**
     * Can be called directly
     *
     * @throws PrinterException
     */
    public void print() throws PrinterException {
        PrinterJob job = PrinterJob.getPrinterJob();

        int width;
        int height;
        
        if (this.paperSize.get() != null && this.paperSize.get().getRotation() > 0) {
            this.bufferedImage.set(rotate(this.bufferedImage.get(), Math.toRadians(this.paperSize.get().getRotation())));
            if (paperSize.get() != null) {
                // Readjust our paperSize after rotation
                 paperSize.get().setAutoSize(this.bufferedImage.get());
            }
        }

        if (this.bufferedImage.get() != null) {
            width = bufferedImage.get().getWidth();
            height = bufferedImage.get().getHeight();
        } else if (this.getPDFFile() != null) {
            width = (int) getPDFFile().getPage(1).getWidth();
            height = (int) getPDFFile().getPage(1).getHeight();
        } else {
            throw new PrinterException("Corrupt or missing file supplied.");
        }

        // Echo some supported attributes to the screen
        if (logPostScriptFeatures.get()) {
            logSupportedPrinterFeatures(job);
        }

        // Fixes 1" white border problem - May need tweaking
        HashPrintRequestAttributeSet attr = new HashPrintRequestAttributeSet();<commit_msg>A hack to fix 4x6 labels<commit_after>/**
 * @author <NAME>
 *
 * Copyright (C) 2013 <NAME>, QZ Industries
 *
 * IMPORTANT: This software is dual-licensed
 *
 * LGPL 2.1 This is free software. This software and source code are released
 * under the "LGPL 2.1 License". A copy of this license should be distributed
 * with this software. http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * QZ INDUSTRIES SOURCE CODE LICENSE This software and source code *may* instead
 * be distributed under the "QZ Industries Source Code License", available by
 * request ONLY. If source code for this project is to be made proprietary for
 * an individual and/or a commercial entity, written permission via a copy of
 * the "QZ Industries Source Code License" must be obtained first. If you've
 * obtained a copy of the proprietary license, the terms and conditions of the
 * license apply only to the licensee identified in the agreement. Only THEN may
 * the LGPL 2.1 license be voided.
 *
 */
package qz;

import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;
import com.sun.pdfview.PDFRenderer;
import qz.common.LogIt;
import qz.printer.PaperFormat;
import qz.utils.SystemUtilities;

import javax.imageio.ImageIO;
import javax.print.PrintService;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.awt.image.ColorModel;
import java.awt.print.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Logger;
import java.util.Arrays;


/**
 *
 * @author <NAME>, <NAME>
 */
public class PrintPostScript implements Printable {

    public static final Logger log = Logger.getLogger(PrintPostScript.class.getName());

    private final AtomicReference<BufferedImage> bufferedImage = new AtomicReference<BufferedImage>(null);
    private final AtomicReference<ByteBuffer> bufferedPDF = new AtomicReference<ByteBuffer>(null);
    private final AtomicReference<PDFFile> pdfFile = new AtomicReference<PDFFile>(null);
    private final AtomicReference<PrintService> printServiceAtomicReference = new AtomicReference<PrintService>(null);
    private final AtomicReference<String> jobName = new AtomicReference<String>("jZebra 2D Printing");
    private final AtomicReference<Paper> paper = new AtomicReference<Paper>(null);
    private final AtomicReference<PaperFormat> paperSize = new AtomicReference<PaperFormat>(null);
    private final AtomicReference<Float> pixelsPerInch = new AtomicReference<Float>(null);
    private final AtomicReference<Integer> copies = new AtomicReference<Integer>(null);
    private final AtomicReference<Boolean> logPostScriptFeatures = new AtomicReference<Boolean>(false);
    public static final float DPI = 72f;
    //Never used, OK to delete?
    //public static final float MMPI = 280f;
    private String pdfClass;

    public PrintPostScript() {
    }
    
    /**
     * Rotates a buffered image by the specified angle in radians.
     * Note:  To rotate in degrees convert to radians first using:
     * <code>Math.toRadians(degree);</code>
     * @param image BufferedImage to rotate
     * @param angle in radians
     * @return Rotated image data
     */
    public static BufferedImage rotate(BufferedImage image, double angle) {
        LogIt.log("Rotating image " + angle);
        double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
        int w = image.getWidth(), h = image.getHeight();
        int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin);
        GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDefaultConfiguration();
        BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
        Graphics2D g = result.createGraphics();
        g.translate((neww-w)/2, (newh-h)/2);
        g.rotate(angle, w/2, h/2);
        g.drawRenderedImage(image, null);
        g.dispose();
        return result;
    }

    /**
     * Can be called directly
     *
     * @throws PrinterException
     */
    public void print() throws PrinterException {
        PrinterJob job = PrinterJob.getPrinterJob();

        int width;
        int height;
        
        if (this.paperSize.get() != null && this.paperSize.get().getRotation() > 0) {
            this.bufferedImage.set(rotate(this.bufferedImage.get(), Math.toRadians(this.paperSize.get().getRotation())));
            if (paperSize.get() != null) {
                // Readjust our paperSize after rotation
                 paperSize.get().setAutoSize(this.bufferedImage.get());
            }
        }

        if (this.bufferedImage.get() != null) {
            width = bufferedImage.get().getWidth();
            height = bufferedImage.get().getHeight();
        } else if (this.getPDFFile() != null) {
            width = (int) getPDFFile().getPage(1).getWidth();
            height = (int) getPDFFile().getPage(1).getHeight();
        } else {
            throw new PrinterException("Corrupt or missing file supplied.");
        }

        // Echo some supported attributes to the screen
        if (logPostScriptFeatures.get()) {
            logSupportedPrinterFeatures(job);
        }

        // Fixes 1" white border problem - May need tweaking
        HashPrintRequestAttributeSet attr = new HashPrintRequestAttributeSet();
        
        // Fixes 4x6 labels on Mac OSX
        if (paperSize.get() != null && paperSize.get().getUnits() == MediaSize.INCH &&
                paperSize.get().getWidth() == 4 && paperSize.get().getHeight() == 6) {
            attr.add(MediaSizeName.JAPANESE_POSTCARD);
        }
{'fraction_non_alphanumeric': 0.10617644532256679, 'fraction_numerical': 0.005326002920711279, 'mean_word_length': 3.4622460712916827, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5367138', 'n_tokens_mistral': 3335, 'n_tokens_neox': 3187, 'n_words': 914}