Try to guess physical font from the properties of a logical font, like "Dialog", "Serif", "Monospaced" etc. - Java 2D Graphics

Java examples for 2D Graphics:Font

Description

Try to guess physical font from the properties of a logical font, like "Dialog", "Serif", "Monospaced" etc.

Demo Code

/*//from  w  ww  .ja  va  2  s .  c  o m
 * VectorGraphics2D: Vector export for Java(R) Graphics2D
 *
 * (C) Copyright 2010-2015 Erich Seifert <dev[at]erichseifert.de>
 *
 * This file is part of VectorGraphics2D.
 *
 * VectorGraphics2D 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, either version 3 of the License, or
 * (at your option) any later version.
 *
 * VectorGraphics2D 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.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with VectorGraphics2D.  If not, see <http://www.gnu.org/licenses/>.
 */
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.PixelGrabber;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.WritableRaster;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import javax.swing.ImageIcon;

public class Main{
    private static final FontRenderContext FONT_RENDER_CONTEXT = new FontRenderContext(
            null, false, true);
    private static final String FONT_TEST_STRING = "this is a test";
    private static final FontExpressivenessComparator FONT_EXPRESSIVENESS_COMPARATOR = new FontExpressivenessComparator();
    /**
     * Try to guess physical font from the properties of a logical font, like
     * "Dialog", "Serif", "Monospaced" etc.
     * @param logicalFont Logical font object.
     * @param testText Text used to determine font properties.
     * @return An object of the first matching physical font. The original font
     * object is returned if it was a physical font or no font matched.
     */
    public static Font getPhysicalFont(Font logicalFont, String testText) {
        String logicalFamily = logicalFont.getFamily();
        if (!isLogicalFontFamily(logicalFamily)) {
            return logicalFont;
        }

        final TextLayout logicalLayout = new TextLayout(testText,
                logicalFont, FONT_RENDER_CONTEXT);

        // Create a list of matches sorted by font expressiveness (in descending order)
        Queue<Font> physicalFonts = new PriorityQueue<Font>(1,
                FONT_EXPRESSIVENESS_COMPARATOR);

        Font[] allPhysicalFonts = GraphicsEnvironment
                .getLocalGraphicsEnvironment().getAllFonts();
        for (Font physicalFont : allPhysicalFonts) {
            String physicalFamily = physicalFont.getFamily();
            // Skip logical fonts
            if (isLogicalFontFamily(physicalFamily)) {
                continue;
            }

            // Derive identical variant of physical font
            physicalFont = physicalFont.deriveFont(logicalFont.getStyle(),
                    logicalFont.getSize2D());
            TextLayout physicalLayout = new TextLayout(testText,
                    physicalFont, FONT_RENDER_CONTEXT);

            // Compare various properties of physical and logical font
            if (physicalLayout.getBounds()
                    .equals(logicalLayout.getBounds())
                    && physicalLayout.getAscent() == logicalLayout
                            .getAscent()
                    && physicalLayout.getDescent() == logicalLayout
                            .getDescent()
                    && physicalLayout.getLeading() == logicalLayout
                            .getLeading()
                    && physicalLayout.getAdvance() == logicalLayout
                            .getAdvance()
                    && physicalLayout.getVisibleAdvance() == logicalLayout
                            .getVisibleAdvance()) {
                // Store matching font in list
                physicalFonts.add(physicalFont);
            }
        }

        // Return a valid font even when no matching font could be found
        if (physicalFonts.isEmpty()) {
            return logicalFont;
        }

        return physicalFonts.poll();
    }
    public static Font getPhysicalFont(Font logicalFont) {
        return getPhysicalFont(logicalFont, FONT_TEST_STRING);
    }
    private static boolean isLogicalFontFamily(String family) {
        return (Font.DIALOG.equals(family)
                || Font.DIALOG_INPUT.equals(family)
                || Font.SANS_SERIF.equals(family)
                || Font.SERIF.equals(family) || Font.MONOSPACED
                    .equals(family));
    }
    public static boolean equals(Shape shapeA, Shape shapeB) {
        PathIterator pathAIterator = shapeA.getPathIterator(null);
        PathIterator pathBIterator = shapeB.getPathIterator(null);

        if (pathAIterator.getWindingRule() != pathBIterator
                .getWindingRule()) {
            return false;
        }
        double[] pathASegment = new double[6];
        double[] pathBSegment = new double[6];
        while (!pathAIterator.isDone()) {
            int pathASegmentType = pathAIterator
                    .currentSegment(pathASegment);
            int pathBSegmentType = pathBIterator
                    .currentSegment(pathBSegment);
            if (pathASegmentType != pathBSegmentType) {
                return false;
            }
            for (int segmentIndex = 0; segmentIndex < pathASegment.length; segmentIndex++) {
                if (pathASegment[segmentIndex] != pathBSegment[segmentIndex]) {
                    return false;
                }
            }

            pathAIterator.next();
            pathBIterator.next();
        }
        // When the iterator of shapeA is done and shapeA equals shapeB, the iterator of shapeB must also be done
        if (!pathBIterator.isDone()) {
            return false;
        }
        return true;
    }
}

Related Tutorials