123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798 |
- /*
- * 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;
- }
-
- }
|