/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2001 - 2013 Object Refinery Ltd, Pentaho Corporation and Contributors.. All rights reserved. */ package org.pentaho.reporting.engine.classic.core.modules.output.table.base; import org.pentaho.reporting.engine.classic.core.ReportAttributeMap; import org.pentaho.reporting.engine.classic.core.layout.model.BorderCorner; import org.pentaho.reporting.engine.classic.core.layout.model.BorderEdge; import org.pentaho.reporting.engine.classic.core.metadata.ElementType; import org.pentaho.reporting.libraries.xmlns.common.AttributeMap; import java.awt.Color; import java.util.ArrayList; public class CellBackground { private ReportAttributeMap<Object> attributes; private ArrayList<Color> collectedColors; private Color backgroundColor; private ArrayList<String> anchors; private BorderEdge top; private BorderEdge left; private BorderEdge bottom; private BorderEdge right; private BorderCorner topLeft; private BorderCorner topRight; private BorderCorner bottomLeft; private BorderCorner bottomRight; private boolean origin; private ElementType elementType; private transient Integer hashCode; private static final String[] EMPTY_ANCHORS = new String[ 0 ]; public CellBackground() { this.top = BorderEdge.EMPTY; this.left = BorderEdge.EMPTY; this.bottom = BorderEdge.EMPTY; this.right = BorderEdge.EMPTY; this.attributes = new ReportAttributeMap<Object>(); this.topLeft = new BorderCorner( 0, 0 ); this.topRight = new BorderCorner( 0, 0 ); this.bottomLeft = new BorderCorner( 0, 0 ); this.bottomRight = new BorderCorner( 0, 0 ); } public boolean isOrigin() { return origin; } public void setOrigin( final boolean origin ) { this.origin = origin; this.hashCode = null; } public void addAttributes( final ReportAttributeMap<Object> attrs ) { if ( attrs == null ) { throw new NullPointerException(); } for ( final AttributeMap.DualKey key : attrs.keySet() ) { final String namespace = key.namespace; final String name = key.name; final Object value = attrs.getAttribute( namespace, name ); if ( value != null ) { this.attributes.setAttribute( namespace, name, value ); } } this.hashCode = null; } public ReportAttributeMap<Object> getAttributes() { return attributes; } public void addBackground( final Color color ) { if ( color == null ) { return; } if ( color.getAlpha() == 0 ) { // fully transparent .. return; } // common special case: Only one background color defined .. if ( backgroundColor == null ) { backgroundColor = color; this.hashCode = null; return; } if ( color.getAlpha() == 255 ) { // fully opaque, so backgroundColor = color; if ( collectedColors != null ) { collectedColors.clear(); } this.hashCode = null; return; } if ( collectedColors == null ) { collectedColors = new ArrayList<Color>(); } if ( collectedColors.isEmpty() ) { collectedColors.add( backgroundColor ); } collectedColors.add( color ); this.hashCode = null; } public Color getBackgroundColor() { if ( backgroundColor != null && backgroundColor.getAlpha() == 255 ) { return backgroundColor; } if ( collectedColors == null ) { return backgroundColor; } if ( collectedColors.isEmpty() == false ) { Color retval = null; final int colorCount = collectedColors.size(); for ( int i = 0; i < colorCount; i++ ) { final Color c = collectedColors.get( i ); if ( retval == null ) { retval = c; } else { retval = addColor( retval, c ); } } return retval; } return backgroundColor; } /** * Adds two colors, the result is the mixed color of the base color and the paint color. * * @param base the base color * @param paint the overlay color * @return the merged colors. */ private static Color addColor( final Color base, final Color paint ) { if ( paint.getAlpha() == 255 ) { return paint; } if ( paint.getAlpha() == 0 ) { return base; } final double baseAlpha = ( base.getAlpha() / 255.0 ); final double paintAlpha = ( paint.getAlpha() / 255.0 ); final double effectiveAlpha = 1.0 - baseAlpha * paintAlpha; final double deltaAlpha = 1.0 - effectiveAlpha; final int red = (int) ( base.getRed() * deltaAlpha + paint.getRed() * effectiveAlpha ); final int green = (int) ( base.getGreen() * deltaAlpha + paint.getGreen() * effectiveAlpha ); final int blue = (int) ( base.getBlue() * deltaAlpha + paint.getBlue() * effectiveAlpha ); return new Color( red, green, blue, (int) ( effectiveAlpha * 255.0 ) ); } public BorderEdge getTop() { return top; } public void setTop( final BorderEdge top ) { if ( top == null ) { throw new NullPointerException(); } this.top = top; this.hashCode = null; } public BorderEdge getLeft() { return left; } public void setLeft( final BorderEdge left ) { if ( left == null ) { throw new NullPointerException(); } this.left = left; this.hashCode = null; } public BorderEdge getBottom() { return bottom; } public void setBottom( final BorderEdge edge ) { if ( edge == null ) { throw new NullPointerException(); } this.bottom = edge; this.hashCode = null; } public BorderEdge getRight() { return right; } public void setRight( final BorderEdge edge ) { if ( edge == null ) { throw new NullPointerException(); } this.right = edge; this.hashCode = null; } public void setTopLeft( final BorderCorner topLeft ) { if ( topLeft == null ) { throw new NullPointerException(); } this.topLeft = topLeft; this.hashCode = null; } public void setTopRight( final BorderCorner topRight ) { if ( topRight == null ) { throw new NullPointerException(); } this.topRight = topRight; this.hashCode = null; } public void setBottomLeft( final BorderCorner bottomLeft ) { if ( bottomLeft == null ) { throw new NullPointerException(); } this.bottomLeft = bottomLeft; this.hashCode = null; } public void setBottomRight( final BorderCorner bottomRight ) { if ( bottomRight == null ) { throw new NullPointerException(); } this.bottomRight = bottomRight; this.hashCode = null; } public BorderCorner getTopLeft() { return topLeft; } public BorderCorner getTopRight() { return topRight; } public BorderCorner getBottomLeft() { return bottomLeft; } public BorderCorner getBottomRight() { return bottomRight; } public void addAnchor( final String anchor ) { if ( anchor == null ) { return; } if ( anchors == null ) { anchors = new ArrayList<String>(); } anchors.add( anchor ); this.hashCode = null; } public String[] getAnchors() { if ( anchors == null ) { return EMPTY_ANCHORS; } return anchors.toArray( new String[ anchors.size() ] ); } public void addElementType( final ElementType type ) { if ( type == null ) { throw new NullPointerException(); } this.elementType = type; this.hashCode = null; } public ElementType getElementType() { return elementType; } public boolean equals( final Object o ) { if ( this == o ) { return true; } if ( o == null || getClass() != o.getClass() ) { return false; } final CellBackground that = (CellBackground) o; if ( origin != that.origin ) { return false; } if ( anchors != null ? !anchors.equals( that.anchors ) : that.anchors != null ) { return false; } if ( attributes != null ? !attributes.equals( that.attributes ) : that.attributes != null ) { return false; } if ( backgroundColor != null ? !backgroundColor.equals( that.backgroundColor ) : that.backgroundColor != null ) { return false; } if ( bottom != null ? !bottom.equals( that.bottom ) : that.bottom != null ) { return false; } if ( bottomLeft != null ? !bottomLeft.equals( that.bottomLeft ) : that.bottomLeft != null ) { return false; } if ( bottomRight != null ? !bottomRight.equals( that.bottomRight ) : that.bottomRight != null ) { return false; } if ( collectedColors != null ? !collectedColors.equals( that.collectedColors ) : that.collectedColors != null ) { return false; } if ( elementType != null ? !elementType.equals( that.elementType ) : that.elementType != null ) { return false; } if ( left != null ? !left.equals( that.left ) : that.left != null ) { return false; } if ( right != null ? !right.equals( that.right ) : that.right != null ) { return false; } if ( top != null ? !top.equals( that.top ) : that.top != null ) { return false; } if ( topLeft != null ? !topLeft.equals( that.topLeft ) : that.topLeft != null ) { return false; } if ( topRight != null ? !topRight.equals( that.topRight ) : that.topRight != null ) { return false; } return true; } public int hashCode() { if ( hashCode == null ) { int result = attributes != null ? attributes.hashCode() : 0; result = 31 * result + ( collectedColors != null ? collectedColors.hashCode() : 0 ); result = 31 * result + ( backgroundColor != null ? backgroundColor.hashCode() : 0 ); result = 31 * result + ( anchors != null ? anchors.hashCode() : 0 ); result = 31 * result + ( top != null ? top.hashCode() : 0 ); result = 31 * result + ( left != null ? left.hashCode() : 0 ); result = 31 * result + ( bottom != null ? bottom.hashCode() : 0 ); result = 31 * result + ( right != null ? right.hashCode() : 0 ); result = 31 * result + ( topLeft != null ? topLeft.hashCode() : 0 ); result = 31 * result + ( topRight != null ? topRight.hashCode() : 0 ); result = 31 * result + ( bottomLeft != null ? bottomLeft.hashCode() : 0 ); result = 31 * result + ( bottomRight != null ? bottomRight.hashCode() : 0 ); result = 31 * result + ( origin ? 1 : 0 ); result = 31 * result + ( elementType != null ? elementType.hashCode() : 0 ); hashCode = result; } return hashCode; } }