/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2008 - 2009, Geomatys * * 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; * version 2.1 of the License. * * 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. */ package org.geotoolkit.display2d.style; import java.awt.AlphaComposite; import java.awt.Paint; import java.awt.RenderingHints; import org.geotoolkit.display2d.GO2Utilities; import org.geotoolkit.display2d.style.renderer.SymbolizerRendererService; import org.opengis.filter.expression.Expression; import org.opengis.style.Displacement; import org.opengis.style.Fill; import org.opengis.style.PolygonSymbolizer; import org.opengis.style.Stroke; /** * * @author Johann Sorel (Geomatys) * @module */ public class CachedPolygonSymbolizer extends CachedSymbolizer<PolygonSymbolizer>{ //cached values private float[] cachedDisps = null; private float cachedDispX = Float.NaN; private float cachedDispY = Float.NaN; private float cachedOffset = Float.NaN; private final CachedStroke cacheStroke; private final CachedFill cacheFill; public CachedPolygonSymbolizer(final PolygonSymbolizer poly, final SymbolizerRendererService<PolygonSymbolizer,? extends CachedSymbolizer<PolygonSymbolizer>> renderer){ super(poly,renderer); final Stroke str = poly.getStroke(); if(str == null){ cacheStroke = null; }else{ cacheStroke = CachedStroke.cache(poly.getStroke()); } final Fill fill = poly.getFill(); if(fill == null){ cacheFill = null; }else{ cacheFill = CachedFill.cache(poly.getFill()); } } /** * {@inheritDoc } */ @Override protected void evaluate() { if(!isNotEvaluated) return; //call this first seens more evaluation may clear the cache evaluateOffset(); evaluateDisplacement(); if(cacheStroke != null){ cacheStroke.getRequieredAttributsName(requieredAttributs); } if(cacheFill != null){ cacheFill.getRequieredAttributsName(requieredAttributs); } if(requieredAttributs.isEmpty()) requieredAttributs = EMPTY_ATTRIBUTS; isNotEvaluated = false; } private void evaluateOffset(){ final Expression offset = styleElement.getPerpendicularOffset(); if(GO2Utilities.isStatic(offset)){ cachedOffset = GO2Utilities.evaluate(offset, null, Float.class, 0f); }else{ GO2Utilities.getRequieredAttributsName(offset,requieredAttributs); } } private void evaluateDisplacement(){ Displacement disp = styleElement.getDisplacement(); if(disp != null){ final Expression dispX = disp.getDisplacementX(); final Expression dispY = disp.getDisplacementY(); if(GO2Utilities.isStatic(dispX)){ cachedDispX = GO2Utilities.evaluate(dispX, null, Float.class, 0f); }else{ GO2Utilities.getRequieredAttributsName(dispX,requieredAttributs); } if(GO2Utilities.isStatic(dispY)){ cachedDispY = GO2Utilities.evaluate(dispY, null, Float.class, 0f); }else{ GO2Utilities.getRequieredAttributsName(dispY,requieredAttributs); } if(!Float.isNaN(cachedDispX) && !Float.isNaN(cachedDispY)){ cachedDisps = new float[]{cachedDispX,cachedDispY}; } }else{ //we can a disp X and Y of 0 cachedDispX = 0f; cachedDispY = 0f; cachedDisps = new float[]{0,0}; } } public CachedStroke getCachedStroke(){ return cacheStroke; } public boolean isMosaic(){ return (cacheFill != null && cacheFill.isMosaic()) || (cacheStroke instanceof CachedStrokeSimple && ((CachedStrokeSimple)cacheStroke).isMosaicPaint() ); } public boolean isStrokeVisible(final Object candidate){ return cacheStroke != null && cacheStroke.isVisible(candidate); } public boolean isFillVisible(final Object candidate){ return cacheFill != null && cacheFill.isVisible(candidate); } public AlphaComposite getJ2DFillComposite(final Object candidate){ return cacheFill.getJ2DComposite(candidate); } public Paint getJ2DFillPaint(final Object candidate, final int x, final int y, final float coeff, final RenderingHints hints){ return cacheFill.getJ2DPaint(candidate, x,y, coeff,hints); } /** * @return a float value of this style offset */ public float getOffset(final Object candidate, final float coeff){ evaluate(); if(Float.isNaN(cachedOffset)){ //if offset is null it means it is dynamic final Expression offset = styleElement.getPerpendicularOffset(); return GO2Utilities.evaluate(offset, null, Float.class, 0f); } return cachedOffset*coeff; } /** * @return an Array of 2 floats always in display unit. */ public float[] getDisplacement(final Object candidate){ evaluate(); if(cachedDisps != null){ return cachedDisps; } final float[] disps = new float[2]; if(Float.isNaN(cachedDispX)){ //if dispX is Float.NaN it means it is dynamic final Expression dispX = styleElement.getDisplacement().getDisplacementX(); disps[0] = GO2Utilities.evaluate(dispX, null, Float.class, 0f); } else { disps[0] = cachedDispX; } if(Float.isNaN(cachedDispY)){ //if dispY is Float.NaN it means it is dynamic final Expression dispY = styleElement.getDisplacement().getDisplacementY(); disps[1] = GO2Utilities.evaluate(dispY, null, Float.class, 0f); } else { disps[1] = cachedDispY; } return disps; } /** * {@inheritDoc } */ @Override public boolean isVisible(final Object candidate){ return (cacheStroke == null || cacheStroke.isVisible(candidate)) || (cacheFill == null || cacheFill.isVisible(candidate)); } /** * {@inheritDoc } */ @Override public boolean isStatic(){ return (cacheStroke == null || cacheStroke.isStatic()) && (cacheFill == null || cacheFill.isStatic()); } /** * {@inheritDoc } */ @Override public VisibilityState isStaticVisible(){ VisibilityState v1 = (cacheStroke==null)?VisibilityState.UNVISIBLE : cacheStroke.isStaticVisible(); VisibilityState v2 = (cacheFill==null)?VisibilityState.UNVISIBLE : cacheFill.isStaticVisible(); if(v1 == VisibilityState.UNVISIBLE && v2 == VisibilityState.UNVISIBLE) return VisibilityState.UNVISIBLE ; else if(v1 == VisibilityState.DYNAMIC || v2 == VisibilityState.DYNAMIC) return VisibilityState.DYNAMIC ; else return VisibilityState.VISIBLE ; } /** * {@inheritDoc } */ @Override public float getMargin(final Object candidate, final float coeff) { if(cacheStroke == null){ return 0f; }else{ return cacheStroke.getMargin(candidate,coeff); } } }