Package org.apache.pdfbox.pdmodel.graphics.shading

Source Code of org.apache.pdfbox.pdmodel.graphics.shading.Type5ShadingContext

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.pdfbox.pdmodel.graphics.shading;

import java.awt.geom.AffineTransform;
import java.awt.image.ColorModel;
import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSStream;
import org.apache.pdfbox.pdmodel.common.PDRange;
import org.apache.pdfbox.util.Matrix;

/**
*
* This represents the Paint of a type 5 (Gouraud triangle lattice) shading
* context.
*
* @author Tilman Hausherr
*/
public class Type5ShadingContext extends GouraudShadingContext
{
    private static final Log LOG = LogFactory.getLog(Type5ShadingContext.class);

    /**
     * Constructor creates an instance to be used for fill operations.
     *
     * @param shadingType5 the shading type to be used
     * @param colorModelValue the color model to be used
     * @param xform transformation for user to device space
     * @param ctm current transformation matrix
     * @param pageHeight height of the current page
     *
     * @throws IOException if something went wrong
     */
    public Type5ShadingContext(PDShadingType5 shadingType5, ColorModel colorModelValue,
            AffineTransform xform, Matrix ctm, int pageHeight) throws IOException
    {
        super(shadingType5, colorModelValue, xform, ctm, pageHeight);

        LOG.debug("Type5ShadingContext");

        bitsPerColorComponent = shadingType5.getBitsPerComponent();
        LOG.debug("bitsPerColorComponent: " + bitsPerColorComponent);
        bitsPerCoordinate = shadingType5.getBitsPerCoordinate();
        LOG.debug(Math.pow(2, bitsPerCoordinate) - 1);
        long maxSrcCoord = (int) Math.pow(2, bitsPerCoordinate) - 1;
        long maxSrcColor = (int) Math.pow(2, bitsPerColorComponent) - 1;
        LOG.debug("maxSrcCoord: " + maxSrcCoord);
        LOG.debug("maxSrcColor: " + maxSrcColor);

        COSDictionary cosDictionary = shadingType5.getCOSDictionary();
        COSStream cosStream = (COSStream) cosDictionary;

        //The Decode key specifies how
        //to decode coordinate and color component data into the ranges of values
        //appropriate for each. The ranges are specified as [xmin xmax ymin ymax c1,min,
        //c1,max,..., cn, min, cn,max].
        //
        // see p344
        COSArray decode = (COSArray) cosDictionary.getDictionaryObject(COSName.DECODE);
        LOG.debug("decode: " + decode);
        PDRange rangeX = shadingType5.getDecodeForParameter(0);
        PDRange rangeY = shadingType5.getDecodeForParameter(1);
        LOG.debug("rangeX: " + rangeX.getMin() + ", " + rangeX.getMax());
        LOG.debug("rangeY: " + rangeY.getMin() + ", " + rangeY.getMax());

        PDRange[] colRangeTab = new PDRange[numberOfColorComponents];
        for (int i = 0; i < numberOfColorComponents; ++i)
        {
            colRangeTab[i] = shadingType5.getDecodeForParameter(2 + i);
        }

        LOG.debug("bitsPerCoordinate: " + bitsPerCoordinate);

        // get background values if available
        COSArray bg = shadingType5.getBackground();
        if (bg != null)
        {
            background = bg.toFloatArray();
        }

        //TODO missing: BBox, AntiAlias (p. 305 in 1.7 spec)
       
        // p318:
        //  reading in sequence from higher-order to lower-order bit positions
        ImageInputStream mciis = new MemoryCacheImageInputStream(cosStream.getFilteredStream());

        int verticesPerRow = shadingType5.getVerticesPerRow(); //TODO check >=2
        LOG.debug("verticesPerRow" + verticesPerRow);

        try
        {
            ArrayList<Vertex> prevVertexRow = new ArrayList<Vertex>();
            while (true)
            {
                // read a vertex row
                ArrayList<Vertex> vertexList = new ArrayList<Vertex>();
                for (int row = 0; row < verticesPerRow; ++row)
                {
                    vertexList.add(readVertex(mciis, (byte) 0, maxSrcCoord, maxSrcColor, rangeX, rangeY, colRangeTab));
                }
                transformVertices(vertexList, ctm, xform, pageHeight);

                // create the triangles from two rows
                if (!prevVertexRow.isEmpty())
                {
                    for (int vj = 0; vj < vertexList.size() - 1; ++vj)
                    {
                        // p.192,194 pdf spec 1.7
                        Vertex vij = prevVertexRow.get(vj); // v i,j
                        Vertex vijplus1 = prevVertexRow.get(vj + 1); // v i,j+1
                        Vertex viplus1j = vertexList.get(vj); // v i+1,j
                        Vertex viplus1jplus1 = vertexList.get(vj + 1); // v i+1,j+1
                        GouraudTriangle g = new GouraudTriangle(vij.point, vij.color,
                                vijplus1.point, vijplus1.color,
                                viplus1j.point, viplus1j.color);
                        if (!g.isEmpty())
                        {
                            triangleList.add(g);
                        }
                        else
                        {
                            LOG.debug("triangle is empty!");
                        }
                        g = new GouraudTriangle(vijplus1.point, vijplus1.color,
                                viplus1j.point, viplus1j.color,
                                viplus1jplus1.point, viplus1jplus1.color);
                        if (!g.isEmpty())
                        {
                            triangleList.add(g);
                        }
                        else
                        {
                            LOG.debug("triangle is empty!");
                        }
                    }
                }
                prevVertexRow = vertexList;
            }
        }
        catch (EOFException ex)
        {
            LOG.debug("EOF");
        }

        mciis.close();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void dispose()
    {
        super.dispose();
    }

}
TOP

Related Classes of org.apache.pdfbox.pdmodel.graphics.shading.Type5ShadingContext

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.