Package com.sun.pdfview.pattern

Source Code of com.sun.pdfview.pattern.ShaderType2$Type2PaintContext

/*
* Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

package com.sun.pdfview.pattern;

import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.IOException;

import com.sun.pdfview.PDFObject;
import com.sun.pdfview.PDFPaint;
import com.sun.pdfview.PDFParseException;
import com.sun.pdfview.colorspace.PDFColorSpace;
import com.sun.pdfview.function.PDFFunction;

/**
* A shader that performs axial shader based on a function.
*/
public class ShaderType2 extends PDFShader {
    /** the start of the axis */
    private Point2D axisStart;
   
    /** the end of the axis */
    private Point2D axisEnd;
   
    /** the domain minimum */
    private float minT = 0f;
   
    /** the domain maximum */
    private float maxT = 1f;
   
    /** whether to extend the start of the axis */
    private boolean extendStart = false;
   
    /** whether to extend the end of the axis */
    private boolean extendEnd = false;
   
    /** functions, as an array of either 1 or n functions */
    private PDFFunction[] functions;
    
    /** Creates a new instance of ShaderType2 */
    public ShaderType2() {
        super(2);
    }
   
    /**
     * Parse the shader-specific data
     */
    @Override
  public void parse(PDFObject shaderObj) throws IOException
    {
        // read the axis coordinates (required)
        PDFObject coordsObj = shaderObj.getDictRef("Coords");
        if (coordsObj == null) {
            throw new PDFParseException("No coordinates found!");
        }
        PDFObject[] coords = coordsObj.getArray();
        Point2D start = new Point2D.Float(coords[0].getFloatValue(),
                                          coords[1].getFloatValue());
        Point2D end   = new Point2D.Float(coords[2].getFloatValue(),
                                          coords[3].getFloatValue());
        setAxisStart(start);
        setAxisEnd(end);
       
        // read the domain (optional)
        PDFObject domainObj = shaderObj.getDictRef("Domain");
        if (domainObj != null) {
            PDFObject[] domain = domainObj.getArray();
            setMinT(domain[0].getFloatValue());
            setMaxT(domain[1].getFloatValue());
        }
       
        // read the functions (required)
        PDFObject functionObj = shaderObj.getDictRef("Function");
        if (functionObj == null) {
            throw new PDFParseException("No function defined for shader!");
        }
        PDFObject[] functionArray = functionObj.getArray();
        PDFFunction[] functions = new PDFFunction[functionArray.length];
        for (int i = 0; i < functions.length; i++) {
            functions[i] = PDFFunction.getFunction(functionArray[i]);
        }
        setFunctions(functions);
       
        // read the extend array (optional)
        PDFObject extendObj = shaderObj.getDictRef("Extend");
        if (extendObj != null) {
            PDFObject[] extendArray = extendObj.getArray();
            setExtendStart(extendArray[0].getBooleanValue());
            setExtendEnd(extendArray[1].getBooleanValue());
        }
       
    }
   
    /**
     * Create a paint that paints this pattern
     */
    @Override
  public PDFPaint getPaint() {
        return PDFPaint.getPaint(new Type2Paint());
    }
   
    /**
     * Get the start of the axis
     */
    public Point2D getAxisStart() {
        return this.axisStart;
    }
   
    /**
     * Set the start of the axis
     */
    protected void setAxisStart(Point2D axisStart) {
        this.axisStart = axisStart;
    }
   
    /**
     * Get the end of the axis
     */
    public Point2D getAxisEnd() {
        return this.axisEnd;
    }
   
    /**
     * Set the start of the axis
     */
    protected void setAxisEnd(Point2D axisEnd) {
        this.axisEnd = axisEnd;
    }
   
    /**
     * Get the domain minimum
     */
    public float getMinT() {
        return this.minT;
    }
   
    /**
     * Set the domain minimum
     */
    protected void setMinT(float minT) {
        this.minT = minT;
    }
   
    /**
     * Get the domain maximum
     */
    public float getMaxT() {
        return this.maxT;
    }
   
    /**
     * Set the domain maximum
     */
    protected void setMaxT(float maxT) {
        this.maxT = maxT;
    }
   
    /**
     * Get whether to extend the start of the axis
     */
    public boolean getExtendStart() {
        return this.extendStart;
    }
   
    /**
     * Set whether to extend the start of the axis
     */
    protected void setExtendStart(boolean extendStart) {
        this.extendStart = extendStart;
    }
   
    /**
     * Get whether to extend the end of the axis
     */
    public boolean getExtendEnd() {
        return this.extendEnd;
    }
   
    /**
     * Set whether to extend the end of the axis
     */
    protected void setExtendEnd(boolean extendEnd) {
        this.extendEnd = extendEnd;
    }
   
    /**
     * Get the functions associated with this shader
     */
    public PDFFunction[] getFunctions() {
        return this.functions;
    }
   
    /**
     * Set the functions associated with this shader
     */
    protected void setFunctions(PDFFunction[] functions) {
        this.functions = functions;
    }
   
    /**
     * A subclass of paint that uses this shader to generate a paint
     */
    class Type2Paint implements Paint {
        public Type2Paint() {
        }
       
        /** create a paint context */
        @Override
    public PaintContext createContext(ColorModel cm,
                                          Rectangle deviceBounds,
                                          Rectangle2D userBounds,
                                          AffineTransform xform,
                                          RenderingHints hints)
        {
            ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
            ColorModel model = new ComponentColorModel(cs,
                                                       true,
                                                       false,
                                                       Transparency.TRANSLUCENT,
                                                       DataBuffer.TYPE_BYTE);
           
            Point2D devStart = xform.transform(getAxisStart(), null);
            Point2D devEnd = xform.transform(getAxisEnd(), null);
         
            return new Type2PaintContext(model, devStart, devEnd);
        }
               
        @Override
    public int getTransparency() {
            return Transparency.TRANSLUCENT;
        }
    }
   
    /**
     * A simple paint context that uses an existing raster in device
     * space to generate pixels
     */
    class Type2PaintContext implements PaintContext {
        /** the color model */
        private ColorModel colorModel;
       
        /** the start of the axis */
        private Point2D start;
       
        /** the end of the axis */
        private Point2D end;
       
       
        private float dt1t0;
        private double dx1x0, dy1y0, sqdx1x0psqdy1y0;
       
        /**
         * Create a paint context
         */
        Type2PaintContext(ColorModel colorModel, Point2D start, Point2D end) {
            this.colorModel = colorModel;
            this.start = start;
            this.end = end;
           
            //pre calculate some often used values
            dt1t0 = getMaxT() - getMinT();
            dx1x0 = end.getX() - start.getX();
            dy1y0 = end.getY() - start.getY();
            sqdx1x0psqdy1y0 = dx1x0*dx1x0 + dy1y0*dy1y0;
        }
       
        @Override
    public void dispose() {
            this.colorModel = null;
        }
       
        @Override
    public ColorModel getColorModel() {
            return this.colorModel;
        }
       
        @Override
        public Raster getRaster(int x, int y, int w, int h) {
          ColorSpace cs = getColorModel().getColorSpace();
            PDFColorSpace shadeCSpace = getColorSpace();


          PDFFunction functions[] = getFunctions();
          int numComponents = cs.getNumComponents();

          float x0 = (float) this.start.getX();
          float y0 = (float) this.start.getY();

          float[] inputs = new float[1];
            float[] outputs = new float[shadeCSpace.getNumComponents()];
            float[] outputRBG = new float[numComponents];

          // all the data, plus alpha channel
          int[] data = new int[w * h * (numComponents + 1)];

          // for each device coordinate
          for (int j = 0; j < h; j++) {
            for (int i = 0; i < w; i += 1) {
              boolean render = true;
              // find t for that user coordinate
              float xp = getXPrime(i + x, j + y, x0, y0);
              float t = 0;
              if (xp >= 0 && xp <= 1) t = getMinT() + (dt1t0 * xp);
              else if (xp < 0 && extendStart) t = getMinT();
              else if (xp > 1 && extendEnd) t = getMaxT();
              else render = false;

              if (render) {
                // calculate the pixel values at t
                inputs[0] = t;
                if (functions.length == 1) {
                  functions[0].calculate(inputs, 0, outputs, 0);
                } else {
                  for (int c = 0; c < functions.length; c++) {
                    functions[c].calculate(inputs, 0, outputs, c);
                  }
                }
                if (functions[0].getNumOutputs() != numComponents) {
                  //CMYK
                  outputRBG = shadeCSpace.getColorSpace().toRGB(outputs);
                }
                else outputRBG = outputs;

                int base = (j * w + i) * (numComponents + 1);
                for (int c = 0; c < numComponents; c++) {
                  data[base + c] = (int) (outputRBG[c] * 255);
                }
                data[base + numComponents] = 255;
              }
            }
          }

            WritableRaster raster =
                getColorModel().createCompatibleWritableRaster(w, h);
            raster.setPixels(0, 0, w, h, data);
         
            Raster child = raster.createTranslatedChild(x, y);
            return child;
        }
       
        /**
         * x' = (x1 - x0) * (x - x0) + (y1 - y0) * (y - y0)
         *      -------------------------------------------
         *               (x1 - x0)^2 + (y1 - y0)^2
         */
        private float getXPrime(float x, float y, float x0, float y0) {
          
            double tp = ((dx1x0* (x - x0)) + (dy1y0 * (y - y0))) / sqdx1x0psqdy1y0;
       
            return (float) tp;
        }
       
        /**
         * t = t0 + (t1 - t0) x x'
         */
        private float getT(float xp) {
         
            if (xp < 0) {
                return getMinT();
            } else if (xp > 1) {
                return getMaxT();
            } else {
                return getMinT() + (dt1t0 * xp);
            }
        }
    }
}
TOP

Related Classes of com.sun.pdfview.pattern.ShaderType2$Type2PaintContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.