Class FontGlyphReader

  1 /*
  2  * Copyright (c) 2016 Vivid Solutions.
  3  *
  4  * All rights reserved. This program and the accompanying materials
  5  * are made available under the terms of the Eclipse Public License 2.0
  6  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
  7  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
  8  * and the Eclipse Distribution License is available at
  9  *
 10  * http://www.eclipse.org/org/documents/edl-v10.php.
 11  */
 12  
 13 package org.locationtech.jts.awt;
 14  
 15 import java.awt.Font;
 16 import java.awt.font.FontRenderContext;
 17 import java.awt.font.GlyphVector;
 18 import java.util.ArrayList;
 19 import java.util.List;
 20  
 21 import org.locationtech.jts.geom.Geometry;
 22 import org.locationtech.jts.geom.GeometryFactory;
 23 import org.locationtech.jts.geom.Polygonal;
 24 import org.locationtech.jts.geom.util.AffineTransformation;
 25  
 26 /**
 27  * Provides methods to read {@link Font} glyphs for strings 
 28  * into {@link Polygonal} geometry.
 29  * <p>
 30  * It is suggested to use larger point sizes to render fonts glyphs,
 31  * to reduce the effects of scale-dependent hints.
 32  * The result geometry is in the base coordinate system of the font.  
 33  * The geometry can be further transformed as necessary using
 34  * {@link AffineTransformation}s.
 35  * 
 36  * @author Martin Davis
 37  *
 38  */
 39 public class FontGlyphReader 
 40 {
 41   /**
 42    * The font name of the Java logical font Serif.
 43    */
 44   public static final String FONT_SERIF = "Serif";
 45   
 46   /**
 47    * The font name of the Java logical font SansSerif.
 48    * <p>
 49    * DEPRECATED - use FONT_SANSSERIF
 50    */
 51   public static final String FONT_SANSERIF = "SansSerif";
 52   
 53   
 54   /**
 55    * The font name of the Java logical font SansSerif.
 56    */
 57   public static final String FONT_SANSSERIF = "SansSerif";
 58   
 59   /**
 60    * The font name of the Java logical font Monospaced.
 61    */
 62  
 63   public static final String FONT_MONOSPACED = "Monospaced";
 64     
 65   // a flatness factor empirically determined to provide good results
 66   private static final double FLATNESS_FACTOR = 400;
 67  
 68   private FontGlyphReader() {}
 69  
 70   /**
 71    * Converts text rendered in the given font and pointsize to a {@link Geometry}
 72    * using a standard flatness factor.
 73    *  
 74    * @param text the text to render
 75    * @param fontName the name of the font
 76    * @param pointSize the pointSize to render at
 77    * @param geomFact the geometryFactory to use to create the result
 78    * @return a polygonal geometry representing the rendered text
 79    */
 80   public static Geometry read(String text, String fontName, int pointSize, GeometryFactory geomFact)
 81   {
 82     return read(text, new Font(fontName, Font.PLAIN, pointSize), geomFact);
 83   }
 84   
 85   /**
 86    * Converts text rendered in the given {@link Font} to a {@link Geometry}
 87    * using a standard flatness factor.
 88    * 
 89    * @param text the text to render
 90    * @param font  the font to render with
 91    * @param geomFact the geometryFactory to use to create the result
 92    * @return a polygonal geometry representing the rendered text
 93    */
 94   public static Geometry read(String text, Font font, GeometryFactory geomFact)
 95   {
 96     double flatness = font.getSize() / FLATNESS_FACTOR;
 97     return read(text, font, flatness, geomFact);
 98   }
 99   
100   /**
101    * Converts text rendered in the given {@link Font} to a {@link Geometry}
102    * 
103    * @param text the text to render
104    * @param font  the font to render with
105    * @param flatness the flatness factor to use
106    * @param geomFact the geometryFactory to use to create the result
107    * @return a polygonal geometry representing the rendered text
108    */
109   public static Geometry read(String text, Font font, double flatness, GeometryFactory geomFact)
110   {
111     char[] chs = text.toCharArray();
112     FontRenderContext fontContext = new FontRenderContext(nullfalsetrue);
113     GlyphVector gv = font.createGlyphVector(fontContext, chs);
114     List polys = new ArrayList();
115     for (int i = 0; i < gv.getNumGlyphs(); i++) {
116       Geometry geom = ShapeReader.read(gv.getGlyphOutline(i), flatness, geomFact);
117       for (int j = 0; j < geom.getNumGeometries(); j++) {
118         polys.add(geom.getGeometryN(j));
119       }
120     }
121     return geomFact.buildGeometry(polys);
122   }
123       
124 }
125