001/*
002 * SVG Salamander
003 * Copyright (c) 2004, Mark McKay
004 * All rights reserved.
005 *
006 * Redistribution and use in source and binary forms, with or 
007 * without modification, are permitted provided that the following
008 * conditions are met:
009 *
010 *   - Redistributions of source code must retain the above 
011 *     copyright notice, this list of conditions and the following
012 *     disclaimer.
013 *   - Redistributions in binary form must reproduce the above
014 *     copyright notice, this list of conditions and the following
015 *     disclaimer in the documentation and/or other materials 
016 *     provided with the distribution.
017 *
018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
019 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
020 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
021 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
022 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
023 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
025 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
026 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
027 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
029 * OF THE POSSIBILITY OF SUCH DAMAGE. 
030 * 
031 * Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
032 * projects can be found at http://www.kitfox.com
033 *
034 * Created on April 24, 2015
035 */
036package com.kitfox.svg.util;
037
038import com.kitfox.svg.Font;
039import com.kitfox.svg.FontFace;
040import com.kitfox.svg.Glyph;
041import com.kitfox.svg.MissingGlyph;
042import java.awt.Canvas;
043import java.awt.FontMetrics;
044import java.awt.GraphicsEnvironment;
045import java.awt.font.FontRenderContext;
046import java.awt.font.GlyphMetrics;
047import java.awt.font.GlyphVector;
048import java.util.HashMap;
049import java.util.HashSet;
050import java.util.regex.Matcher;
051import java.util.regex.Pattern;
052
053/**
054 *
055 * @author kitfox
056 */
057public class FontSystem extends Font
058{
059    java.awt.Font sysFont;
060    FontMetrics fm;
061
062    HashMap<String, Glyph> glyphCache = new HashMap<String, Glyph>();
063    
064    static HashSet<String> sysFontNames = new HashSet<String>();
065    
066    public static boolean checkIfSystemFontExists(String fontName)
067    {
068        if (sysFontNames.isEmpty())
069        {
070            for (String name: GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames())
071            {
072                sysFontNames.add(name);
073            }
074        }
075        
076        return sysFontNames.contains(fontName);
077    }
078    
079    public static FontSystem createFont(String fontFamily, int fontStyle, int fontWeight, int fontSize)
080    {
081        String[] families = fontFamily.split(",");
082        for (String fontName: families)
083        {
084            if (checkIfSystemFontExists(fontName))
085            {
086                return new FontSystem(fontName, fontStyle, fontWeight, (int) fontSize);
087            }
088        }
089        
090        return null;
091    }
092    
093    private FontSystem(String fontFamily, int fontStyle, int fontWeight, int fontSize)
094    {
095        int style;
096        switch (fontStyle)
097        {
098            case com.kitfox.svg.Text.TXST_ITALIC:
099                style = java.awt.Font.ITALIC;
100                break;
101            default:
102                style = java.awt.Font.PLAIN;
103                break;
104        }
105
106        int weight;
107        switch (fontWeight)
108        {
109            case com.kitfox.svg.Text.TXWE_BOLD:
110            case com.kitfox.svg.Text.TXWE_BOLDER:
111                weight = java.awt.Font.BOLD;
112                break;
113            default:
114                weight = java.awt.Font.PLAIN;
115                break;
116        }
117        
118        sysFont = new java.awt.Font(fontFamily, style | weight, (int) fontSize);
119        
120        Canvas c = new Canvas();
121        fm = c.getFontMetrics(sysFont);
122        
123        FontFace face = new FontFace();
124        face.setAscent(fm.getAscent());
125        face.setDescent(fm.getDescent());
126        face.setUnitsPerEm(fm.charWidth('M'));
127        setFontFace(face);
128    }
129
130    @Override
131    public MissingGlyph getGlyph(String unicode)
132    {
133        FontRenderContext frc = new FontRenderContext(null, true, true);
134        GlyphVector vec = sysFont.createGlyphVector(frc, unicode);
135        
136        Glyph glyph = (Glyph)glyphCache.get(unicode);
137        if (glyph == null)
138        {
139            glyph = new Glyph();
140            glyph.setPath(vec.getGlyphOutline(0));
141
142            GlyphMetrics gm = vec.getGlyphMetrics(0);
143            glyph.setHorizAdvX(gm.getAdvanceX());
144            glyph.setVertAdvY(gm.getAdvanceY());
145            glyph.setVertOriginX(0);
146            glyph.setVertOriginY(0);
147            
148            glyphCache.put(unicode, glyph);
149        }
150        
151        return glyph;
152    }
153    
154    
155}