/*
* Geotoolkit - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2014, 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.renderer.style;
import java.awt.Font;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.List;
import java.util.Map;
import org.geotoolkit.display.PortrayalException;
/**
*
* @author Johann Sorel (Geomatys)
*/
public class TTFMarkFactory extends MarkFactory {
private static final String PROTOCOL_TTF = "ttf";
private static final String PROPERTY_CHAR = "char";
private static final FontRenderContext FONT_RENDER_CONTEXT = new FontRenderContext(
new AffineTransform(), false, false);
@Override
public Shape evaluateShape(String format, Object markRef, int markIndex) throws PortrayalException {
if(!(markRef instanceof String)) return null;
final String fontPath;
if(format!=null && PROTOCOL_TTF.equalsIgnoreCase(format)){
//direct glyph reference
fontPath = (String) markRef;
}else{
//expression type
final List<Object> parts = splitPath((String)markRef);
final String protocol = (String) parts.get(0);
if(PROTOCOL_TTF.equals(protocol) || PROTOCOL_TTF.equals(format)){
fontPath = (String)parts.get(1);
if(markIndex<=0){
//search in parameters
for(int i=2,n=parts.size();i<n;i++){
final Map.Entry entry = (Map.Entry) parts.get(2);
if(PROPERTY_CHAR.equalsIgnoreCase((String)entry.getKey())){
String v = (String) entry.getValue();
if(v.startsWith("U+") || v.startsWith("\\u")){
v = "0x" + v.substring(2);
}
markIndex = Integer.decode(v);
}
}
}
}else{
return null;
}
}
Font font = FontCache.getDefaultInsance().getFont(fontPath);
if (font == null) {
throw new PortrayalException("Unkown font "+fontPath);
}
final GlyphVector glyph = font.createGlyphVector(FONT_RENDER_CONTEXT,new String(new int[]{markIndex}, 0, 1));
final Shape shape = glyph.getOutline();
final Rectangle2D bounds = shape.getBounds2D();
final double scale = 1.0 / Math.max(bounds.getWidth(), bounds.getHeight());
//center and downscale glyph
final AffineTransform atrs = new AffineTransform(
scale,
0.0,
0.0,
scale,
-bounds.getCenterX()*scale,
-bounds.getCenterY()*scale);
return atrs.createTransformedShape(shape);
}
}