| /* |
| * 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. |
| */ |
| |
| /* $Id$ */ |
| |
| package org.apache.fop.pdf; |
| |
| // Java... |
| import java.util.List; |
| |
| /** |
| * class representing a PDF Function. |
| * |
| * PDF Functions represent parameterized mathematical formulas and |
| * sampled representations with |
| * arbitrary resolution. Functions are used in two areas: device-dependent |
| * rasterization information for halftoning and transfer |
| * functions, and color specification for smooth shading (a PDF 1.3 feature). |
| * |
| * All PDF Functions have a FunctionType (0,2,3, or 4), a Domain, and a Range. |
| */ |
| public class PDFFunction extends PDFObject { |
| // Guts common to all function types |
| |
| /** |
| * Required: The Type of function (0,2,3,4) default is 0. |
| */ |
| protected int functionType = 0; // Default |
| |
| /** |
| * Required: 2 * m Array of Double numbers which are possible inputs to the function |
| */ |
| protected List domain = null; |
| |
| /** |
| * Required: 2 * n Array of Double numbers which are possible outputs to the function |
| */ |
| protected List range = null; |
| |
| /* ********************TYPE 0***************************** */ |
| // FunctionType 0 specific function guts |
| |
| /** |
| * Required: Array containing the Integer size of the Domain and Range, respectively. |
| * Note: This is really more like two seperate integers, sizeDomain, and sizeRange, |
| * but since they're expressed as an array in PDF, my implementation reflects that. |
| */ |
| protected List size = null; |
| |
| /** |
| * Required for Type 0: Number of Bits used to represent each sample value. |
| * Limited to 1,2,4,8,12,16,24, or 32 |
| */ |
| protected int bitsPerSample = 1; |
| |
| /** |
| * Optional for Type 0: order of interpolation between samples. |
| * Limited to linear (1) or cubic (3). Default is 1 |
| */ |
| protected int order = 1; |
| |
| /** |
| * Optional for Type 0: A 2 * m array of Doubles which provides a |
| * linear mapping of input values to the domain. |
| * |
| * Required for Type 3: A 2 * k array of Doubles that, taken |
| * in pairs, map each subset of the domain defined by Domain |
| * and the Bounds array to the domain of the corresponding function. |
| * Should be two values per function, usually (0,1), |
| * as in [0 1 0 1] for 2 functions. |
| */ |
| protected List encode = null; |
| |
| /** |
| * Optional for Type 0: A 2 * n array of Doubles which provides |
| * a linear mapping of sample values to the range. Defaults to Range. |
| */ |
| protected List decode = null; |
| |
| /** |
| * Optional For Type 0: A stream of sample values |
| */ |
| |
| /** |
| * Required For Type 4: Postscript Calculator function |
| * composed of arithmetic, boolean, and stack operators + boolean constants |
| */ |
| protected StringBuffer functionDataStream = null; |
| |
| /** |
| * Required (possibly) For Type 0: A vector of Strings for the |
| * various filters to be used to decode the stream. |
| * These are how the string is compressed. Flate, LZW, etc. |
| */ |
| protected List filter = null; |
| /* *************************TYPE 2************************** */ |
| |
| /** |
| * Required For Type 2: An Array of n Doubles defining |
| * the function result when x=0. Default is [0]. |
| */ |
| protected List cZero = null; |
| |
| /** |
| * Required For Type 2: An Array of n Doubles defining |
| * the function result when x=1. Default is [1]. |
| */ |
| protected List cOne = null; |
| |
| /** |
| * Required for Type 2: The interpolation exponent. |
| * Each value x will return n results. |
| * Must be greater than 0. |
| */ |
| protected double interpolationExponentN = 1; |
| |
| /* *************************TYPE 3************************** */ |
| |
| /** |
| * Required for Type 3: An vector of PDFFunctions which |
| * form an array of k single input functions making up |
| * the stitching function. |
| */ |
| protected List functions = null; |
| |
| /** |
| * Optional for Type 3: An array of (k-1) Doubles that, |
| * in combination with Domain, define the intervals to which |
| * each function from the Functions array apply. Bounds |
| * elements must be in order of increasing magnitude, |
| * and each value must be within the value of Domain. |
| * k is the number of functions. |
| * If you pass null, it will output (1/k) in an array of k-1 elements. |
| * This makes each function responsible for an equal amount of the stitching function. |
| * It makes the gradient even. |
| */ |
| protected List bounds = null; |
| // See encode above, as it's also part of Type 3 Functions. |
| |
| /* *************************TYPE 4************************** */ |
| // See 'data' above. |
| |
| /** |
| * create an complete Function object of Type 0, A Sampled function. |
| * |
| * Use null for an optional object parameter if you choose not to use it. |
| * For optional int parameters, pass the default. |
| * |
| * @param theDomain List objects of Double objects. |
| * This is the domain of the function. |
| * See page 264 of the PDF 1.3 Spec. |
| * @param theRange List objects of Double objects. |
| * This is the Range of the function. |
| * See page 264 of the PDF 1.3 Spec. |
| * @param theSize A List object of Integer objects. |
| * This is the number of samples in each input dimension. |
| * I can't imagine there being more or less than two input dimensions, |
| * so maybe this should be an array of length 2. |
| * |
| * See page 265 of the PDF 1.3 Spec. |
| * @param theBitsPerSample An int specifying the number of bits |
| used to represent each sample value. |
| * Limited to 1,2,4,8,12,16,24 or 32. |
| * See page 265 of the 1.3 PDF Spec. |
| * @param theOrder The order of interpolation between samples. Default is 1 (one). Limited |
| * to 1 (one) or 3, which means linear or cubic-spline interpolation. |
| * |
| * This attribute is optional. |
| * |
| * See page 265 in the PDF 1.3 spec. |
| * @param theEncode List objects of Double objects. |
| * This is the linear mapping of input values intop the domain |
| * of the function's sample table. Default is hard to represent in |
| * ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. |
| * This attribute is optional. |
| * |
| * See page 265 in the PDF 1.3 spec. |
| * @param theDecode List objects of Double objects. |
| * This is a linear mapping of sample values into the range. |
| * The default is just the range. |
| * |
| * This attribute is optional. |
| * Read about it on page 265 of the PDF 1.3 spec. |
| * @param theFunctionDataStream The sample values that specify |
| * the function are provided in a stream. |
| * |
| * This is optional, but is almost always used. |
| * |
| * Page 265 of the PDF 1.3 spec has more. |
| * @param theFilter This is a vector of String objects which are the various filters that |
| * have are to be applied to the stream to make sense of it. Order matters, |
| * so watch out. |
| * |
| * This is not documented in the Function section of the PDF 1.3 spec, |
| * it was deduced from samples that this is sometimes used, even if we may never |
| * use it in FOP. It is added for completeness sake. |
| * @param theFunctionType This is the type of function (0,2,3, or 4). |
| * It should be 0 as this is the constructor for sampled functions. |
| */ |
| public PDFFunction( // CSOK: ParameterNumber |
| int theFunctionType, List theDomain, |
| List theRange, List theSize, int theBitsPerSample, |
| int theOrder, List theEncode, List theDecode, |
| StringBuffer theFunctionDataStream, List theFilter) { |
| super(); |
| |
| this.functionType = 0; // dang well better be 0; |
| this.size = theSize; |
| this.bitsPerSample = theBitsPerSample; |
| this.order = theOrder; // int |
| this.encode = theEncode; // vector of int |
| this.decode = theDecode; // vector of int |
| this.functionDataStream = theFunctionDataStream; |
| this.filter = theFilter; // vector of Strings |
| |
| // the domain and range are actually two dimensional arrays. |
| // so if there's not an even number of items, bad stuff |
| // happens. |
| this.domain = theDomain; |
| this.range = theRange; |
| } |
| |
| /** |
| * create an complete Function object of Type 2, an Exponential Interpolation function. |
| * |
| * Use null for an optional object parameter if you choose not to use it. |
| * For optional int parameters, pass the default. |
| * |
| * @param theDomain List objects of Double objects. |
| * This is the domain of the function. |
| * See page 264 of the PDF 1.3 Spec. |
| * @param theRange List of Doubles that is the Range of the function. |
| * See page 264 of the PDF 1.3 Spec. |
| * @param theCZero This is a vector of Double objects which defines the function result |
| * when x=0. |
| * |
| * This attribute is optional. |
| * It's described on page 268 of the PDF 1.3 spec. |
| * @param theCOne This is a vector of Double objects which defines the function result |
| * when x=1. |
| * |
| * This attribute is optional. |
| * It's described on page 268 of the PDF 1.3 spec. |
| * @param theInterpolationExponentN This is the inerpolation exponent. |
| * |
| * This attribute is required. |
| * PDF Spec page 268 |
| * @param theFunctionType The type of the function, which should be 2. |
| */ |
| public PDFFunction(int theFunctionType, List theDomain, |
| List theRange, List theCZero, List theCOne, |
| double theInterpolationExponentN) { |
| super(); |
| |
| this.functionType = 2; // dang well better be 2; |
| |
| this.cZero = theCZero; |
| this.cOne = theCOne; |
| this.interpolationExponentN = theInterpolationExponentN; |
| |
| |
| this.domain = theDomain; |
| this.range = theRange; |
| |
| } |
| |
| /** |
| * create an complete Function object of Type 3, a Stitching function. |
| * |
| * Use null for an optional object parameter if you choose not to use it. |
| * For optional int parameters, pass the default. |
| * |
| * @param theDomain List objects of Double objects. |
| * This is the domain of the function. |
| * See page 264 of the PDF 1.3 Spec. |
| * @param theRange List objects of Double objects. |
| * This is the Range of the function. |
| * See page 264 of the PDF 1.3 Spec. |
| * @param theFunctions A List of the PDFFunction objects that the stitching function stitches. |
| * |
| * This attributed is required. |
| * It is described on page 269 of the PDF spec. |
| * @param theBounds This is a vector of Doubles representing the numbers that, |
| * in conjunction with Domain define the intervals to which each function from |
| * the 'functions' object applies. It must be in order of increasing magnitude, |
| * and each must be within Domain. |
| * |
| * It basically sets how much of the gradient each function handles. |
| * |
| * This attributed is required. |
| * It's described on page 269 of the PDF 1.3 spec. |
| * @param theEncode List objects of Double objects. |
| * This is the linear mapping of input values intop the domain |
| * of the function's sample table. Default is hard to represent in |
| * ascii, but basically [0 (Size0 1) 0 (Size1 1)...]. |
| * This attribute is required. |
| * |
| * See page 270 in the PDF 1.3 spec. |
| * @param theFunctionType This is the function type. It should be 3, |
| * for a stitching function. |
| */ |
| public PDFFunction(int theFunctionType, List theDomain, |
| List theRange, List theFunctions, |
| List theBounds, List theEncode) { |
| super(); |
| |
| this.functionType = 3; // dang well better be 3; |
| |
| this.functions = theFunctions; |
| this.bounds = theBounds; |
| this.encode = theEncode; |
| this.domain = theDomain; |
| this.range = theRange; |
| |
| } |
| |
| /** |
| * create an complete Function object of Type 4, a postscript calculator function. |
| * |
| * Use null for an optional object parameter if you choose not to use it. |
| * For optional int parameters, pass the default. |
| * |
| * @param theDomain List object of Double objects. |
| * This is the domain of the function. |
| * See page 264 of the PDF 1.3 Spec. |
| * @param theRange List object of Double objects. |
| * This is the Range of the function. |
| * See page 264 of the PDF 1.3 Spec. |
| * @param theFunctionDataStream This is a stream of arithmetic, |
| * boolean, and stack operators and boolean constants. |
| * I end up enclosing it in the '{' and '}' braces for you, so don't do it |
| * yourself. |
| * |
| * This attribute is required. |
| * It's described on page 269 of the PDF 1.3 spec. |
| * @param theFunctionType The type of function which should be 4, as this is |
| * a Postscript calculator function |
| */ |
| public PDFFunction(int theFunctionType, List theDomain, |
| List theRange, StringBuffer theFunctionDataStream) { |
| super(); |
| |
| this.functionType = 4; // dang well better be 4; |
| this.functionDataStream = theFunctionDataStream; |
| |
| this.domain = theDomain; |
| |
| this.range = theRange; |
| |
| } |
| |
| |
| /** |
| * represent as PDF. Whatever the FunctionType is, the correct |
| * representation spits out. The sets of required and optional |
| * attributes are different for each type, but if a required |
| * attribute's object was constructed as null, then no error |
| * is raised. Instead, the malformed PDF that was requested |
| * by the construction is dutifully output. |
| * This policy should be reviewed. |
| * |
| * @return the PDF string. |
| */ |
| public byte[] toPDF() { // CSOK: MethodLength |
| int vectorSize = 0; |
| int numberOfFunctions = 0; |
| int tempInt = 0; |
| StringBuffer p = new StringBuffer(256); |
| p.append("<< \n/FunctionType " + this.functionType + " \n"); |
| |
| // FunctionType 0 |
| if (this.functionType == 0) { |
| if (this.domain != null) { |
| // DOMAIN |
| p.append("/Domain [ "); |
| vectorSize = this.domain.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt)) |
| + " "); |
| } |
| |
| p.append("] \n"); |
| } else { |
| p.append("/Domain [ 0 1 ] \n"); |
| } |
| |
| // SIZE |
| if (this.size != null) { |
| p.append("/Size [ "); |
| vectorSize = this.size.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.size.get(tempInt)) |
| + " "); |
| } |
| p.append("] \n"); |
| } |
| // ENCODE |
| if (this.encode != null) { |
| p.append("/Encode [ "); |
| vectorSize = this.encode.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.encode.get(tempInt)) |
| + " "); |
| } |
| p.append("] \n"); |
| } else { |
| p.append("/Encode [ "); |
| vectorSize = this.functions.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append("0 1 "); |
| } |
| p.append("] \n"); |
| |
| } |
| |
| // BITSPERSAMPLE |
| p.append("/BitsPerSample " + this.bitsPerSample); |
| |
| // ORDER (optional) |
| if (this.order == 1 || this.order == 3) { |
| p.append(" \n/Order " + this.order + " \n"); |
| } |
| |
| // RANGE |
| if (this.range != null) { |
| p.append("/Range [ "); |
| vectorSize = this.range.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt)) |
| + " "); |
| } |
| |
| p.append("] \n"); |
| } |
| |
| // DECODE |
| if (this.decode != null) { |
| p.append("/Decode [ "); |
| vectorSize = this.decode.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.decode.get(tempInt)) |
| + " "); |
| } |
| |
| p.append("] \n"); |
| } |
| |
| // LENGTH |
| if (this.functionDataStream != null) { |
| p.append("/Length " + (this.functionDataStream.length() + 1) |
| + " \n"); |
| } |
| |
| // FILTER? |
| if (this.filter != null) { // if there's a filter |
| vectorSize = this.filter.size(); |
| p.append("/Filter "); |
| if (vectorSize == 1) { |
| p.append("/" + ((String)this.filter.get(0)) |
| + " \n"); |
| } else { |
| p.append("[ "); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append("/" + ((String)this.filter.get(0)) |
| + " "); |
| } |
| p.append("] \n"); |
| } |
| } |
| p.append(">>"); |
| |
| // stream representing the function |
| if (this.functionDataStream != null) { |
| p.append("\nstream\n" + this.functionDataStream |
| + "\nendstream"); |
| } |
| |
| // end of if FunctionType 0 |
| |
| } else if (this.functionType == 2) { |
| // DOMAIN |
| if (this.domain != null) { |
| p.append("/Domain [ "); |
| vectorSize = this.domain.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt)) |
| + " "); |
| } |
| |
| p.append("] \n"); |
| } else { |
| p.append("/Domain [ 0 1 ] \n"); |
| } |
| |
| |
| // RANGE |
| if (this.range != null) { |
| p.append("/Range [ "); |
| vectorSize = this.range.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt)) |
| + " "); |
| } |
| |
| p.append("] \n"); |
| } |
| |
| // FunctionType, C0, C1, N are required in PDF |
| |
| // C0 |
| if (this.cZero != null) { |
| p.append("/C0 [ "); |
| vectorSize = this.cZero.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.cZero.get(tempInt)) |
| + " "); |
| } |
| p.append("] \n"); |
| } |
| |
| // C1 |
| if (this.cOne != null) { |
| p.append("/C1 [ "); |
| vectorSize = this.cOne.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.cOne.get(tempInt)) |
| + " "); |
| } |
| p.append("] \n"); |
| } |
| |
| // N: The interpolation Exponent |
| p.append("/N " |
| + PDFNumber.doubleOut(new Double(this.interpolationExponentN)) |
| + " \n"); |
| |
| p.append(">>"); |
| |
| } else if (this.functionType |
| == 3) { // fix this up when my eyes uncross |
| // DOMAIN |
| if (this.domain != null) { |
| p.append("/Domain [ "); |
| vectorSize = this.domain.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt)) |
| + " "); |
| } |
| p.append("] \n"); |
| } else { |
| p.append("/Domain [ 0 1 ] \n"); |
| } |
| |
| // RANGE |
| if (this.range != null) { |
| p.append("/Range [ "); |
| vectorSize = this.range.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt)) |
| + " "); |
| } |
| |
| p.append("] \n"); |
| } |
| |
| // FUNCTIONS |
| if (this.functions != null) { |
| p.append("/Functions [ "); |
| numberOfFunctions = this.functions.size(); |
| for (tempInt = 0; tempInt < numberOfFunctions; tempInt++) { |
| p.append(((PDFFunction)this.functions.get(tempInt)).referencePDF() |
| + " "); |
| |
| } |
| p.append("] \n"); |
| } |
| |
| |
| // ENCODE |
| if (this.encode != null) { |
| p.append("/Encode [ "); |
| vectorSize = this.encode.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.encode.get(tempInt)) |
| + " "); |
| } |
| |
| p.append("] \n"); |
| } else { |
| p.append("/Encode [ "); |
| vectorSize = this.functions.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append("0 1 "); |
| } |
| p.append("] \n"); |
| |
| } |
| |
| |
| // BOUNDS, required, but can be empty |
| p.append("/Bounds [ "); |
| if (this.bounds != null) { |
| |
| vectorSize = this.bounds.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.bounds.get(tempInt)) |
| + " "); |
| } |
| |
| } else { |
| if (this.functions != null) { |
| // if there are n functions, |
| // there must be n-1 bounds. |
| // so let each function handle an equal portion |
| // of the whole. e.g. if there are 4, then [ 0.25 0.25 0.25 ] |
| |
| String functionsFraction = PDFNumber.doubleOut(new Double(1.0 |
| / ((double)numberOfFunctions))); |
| |
| for (tempInt = 0; tempInt + 1 < numberOfFunctions; |
| tempInt++) { |
| |
| p.append(functionsFraction + " "); |
| } |
| functionsFraction = null; // clean reference. |
| |
| } |
| |
| } |
| p.append("]\n>>"); |
| } else if (this.functionType |
| == 4) { // fix this up when my eyes uncross |
| // DOMAIN |
| if (this.domain != null) { |
| p.append("/Domain [ "); |
| vectorSize = this.domain.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.domain.get(tempInt)) |
| + " "); |
| } |
| |
| p.append("] \n"); |
| } else { |
| p.append("/Domain [ 0 1 ] \n"); |
| } |
| |
| // RANGE |
| if (this.range != null) { |
| p.append("/Range [ "); |
| vectorSize = this.range.size(); |
| for (tempInt = 0; tempInt < vectorSize; tempInt++) { |
| p.append(PDFNumber.doubleOut((Double)this.range.get(tempInt)) |
| + " "); |
| } |
| |
| p.append("] \n"); |
| } |
| |
| // LENGTH |
| if (this.functionDataStream != null) { |
| p.append("/Length " + (this.functionDataStream.length() + 1) |
| + " \n"); |
| } |
| |
| p.append(">>"); |
| |
| // stream representing the function |
| if (this.functionDataStream != null) { |
| p.append("\nstream\n{ " + this.functionDataStream |
| + " }\nendstream"); |
| } |
| |
| |
| } |
| |
| return encode(p.toString()); |
| |
| } |
| |
| /** {@inheritDoc} */ |
| protected boolean contentEquals(PDFObject obj) { |
| if (obj == null) { |
| return false; |
| } |
| if (obj == this) { |
| return true; |
| } |
| if (!(obj instanceof PDFFunction)) { |
| return false; |
| } |
| PDFFunction func = (PDFFunction)obj; |
| if (functionType != func.functionType) { |
| return false; |
| } |
| if (bitsPerSample != func.bitsPerSample) { |
| return false; |
| } |
| if (order != func.order) { |
| return false; |
| } |
| if (interpolationExponentN != func.interpolationExponentN) { |
| return false; |
| } |
| if (domain != null) { |
| if (!domain.equals(func.domain)) { |
| return false; |
| } |
| } else if (func.domain != null) { |
| return false; |
| } |
| if (range != null) { |
| if (!range.equals(func.range)) { |
| return false; |
| } |
| } else if (func.range != null) { |
| return false; |
| } |
| if (size != null) { |
| if (!size.equals(func.size)) { |
| return false; |
| } |
| } else if (func.size != null) { |
| return false; |
| } |
| if (encode != null) { |
| if (!encode.equals(func.encode)) { |
| return false; |
| } |
| } else if (func.encode != null) { |
| return false; |
| } |
| if (decode != null) { |
| if (!decode.equals(func.decode)) { |
| return false; |
| } |
| } else if (func.decode != null) { |
| return false; |
| } |
| if (functionDataStream != null) { |
| if (!functionDataStream.equals(func.functionDataStream)) { |
| return false; |
| } |
| } else if (func.functionDataStream != null) { |
| return false; |
| } |
| if (filter != null) { |
| if (!filter.equals(func.filter)) { |
| return false; |
| } |
| } else if (func.filter != null) { |
| return false; |
| } |
| if (cZero != null) { |
| if (!cZero.equals(func.cZero)) { |
| return false; |
| } |
| } else if (func.cZero != null) { |
| return false; |
| } |
| if (cOne != null) { |
| if (!cOne.equals(func.cOne)) { |
| return false; |
| } |
| } else if (func.cOne != null) { |
| return false; |
| } |
| if (functions != null) { |
| if (!functions.equals(func.functions)) { |
| return false; |
| } |
| } else if (func.functions != null) { |
| return false; |
| } |
| if (bounds != null) { |
| if (!bounds.equals(func.bounds)) { |
| return false; |
| } |
| } else if (func.bounds != null) { |
| return false; |
| } |
| return true; |
| } |
| |
| } |