Java Font Derive deriveFont(Font font, int style, int size)

Here you can find the source of deriveFont(Font font, int style, int size)

Description

derive Font

License

Open Source License

Declaration

public static Font deriveFont(Font font, int style, int size) 

Method Source Code

//package com.java2s;
/*/* www . jav a  2  s  .  c o m*/
SongScribe song notation program
Copyright (C) 2006 Csaba Kavai
    
This file is part of SongScribe.
    
SongScribe is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
    
SongScribe 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 General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
Created on Aug 6, 2006
*/

import sun.font.Font2D;

import java.awt.*;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import java.util.*;

public class Main {
    private static Font[] systemFonts;
    private static String[] systemFontBaseNames;
    private static String[] plainFontSuffixNames = { "", "Regular", "Medium" };
    private static String[] italicFontSuffixNames = { "It", "Italic", "Oblique", "ItalicMT" };
    private static String[] boldFontSuffixNames = { "Bold", "Semibold", "Demibold", "BoldMT" };

    public static Font deriveFont(Font font, int style, int size) {
        return createFont(font.getFamily(), style, size);
    }

    public static Font createFont(String familyName, int style, int size) {
        Font foundFont = null;

        for (int i = 0; i < systemFonts.length; ++i) {
            Font font = systemFonts[i];

            if (font.getFamily().equals(familyName)) {
                String baseName = systemFontBaseNames[i];

                if (style == Font.PLAIN) {
                    String name = matchFontName(font, baseName, plainFontSuffixNames, true);

                    // If we can't find the plain font, fail
                    if (name != null) {
                        foundFont = font;
                        break;
                    }
                } else if ((style & Font.BOLD) != 0) {
                    boolean wantItalic = (style & Font.ITALIC) != 0;
                    String name = matchFontName(font, baseName, boldFontSuffixNames, !wantItalic);

                    // If italic is also desired, try adding italic suffixes
                    if (name != null && wantItalic) {
                        name = matchFontName(font, name, italicFontSuffixNames, true);
                    }

                    if (name != null) {
                        foundFont = font;
                        break;
                    }
                } else if (style == Font.ITALIC) {
                    String name = matchFontName(font, baseName, italicFontSuffixNames, true);

                    if (name != null) {
                        foundFont = font;
                        break;
                    }
                }
            }
        }

        if (foundFont == null) {
            if (style == (Font.BOLD | Font.ITALIC)) {
                // If we can't find bold+italic, fall back to bold
                foundFont = createFont(familyName, Font.BOLD, size);
            } else if (style != Font.PLAIN) {
                // If we get here and no styled font is found, fall back to plain.
                foundFont = createFont(familyName, Font.PLAIN, size);
            }
        }

        // If all attempts fail, use Java's built in search
        if (foundFont == null) {
            foundFont = new Font(familyName, style, size);
        } else {
            // Always use plain for the style, if we get here we have
            // a styled font variant already.
            foundFont = foundFont.deriveFont(Font.PLAIN, (float) size);
            fixFont2DStyle(foundFont, style);
        }

        return foundFont;
    }

    private static String matchFontName(Font font, String baseName, String[] suffixes, boolean exactMatch) {
        String fontName = font.getPSName();
        boolean hasSuffix = baseName.contains("-");

        for (String suffix : suffixes) {
            if (!hasSuffix && suffix.length() > 0) {
                suffix = "-" + suffix;
            }

            String name = baseName + suffix;

            if (exactMatch) {
                if (fontName.equals(name)) {
                    return name;
                }
            } else if (fontName.startsWith(name)) {
                return name;
            }
        }

        return null;
    }

    public static void fixFont2DStyle(Font font, int style) {
        Map<String, Object> result = get2DStyleFieldForFont(font);

        if (result != null) {
            try {
                Field styleField = (Field) result.get("field");
                Font2D font2d = (Font2D) result.get("font");
                styleField.setInt(font2d, style);
            } catch (Exception ex) {
                // Oh well, we tried
            }
        }
    }

    public static Map<String, Object> get2DStyleFieldForFont(Font font) {
        try {
            Class<?>[] params = new Class[0];
            Method method = font.getClass().getDeclaredMethod("getFont2D", params);
            method.setAccessible(true);
            Font2D font2d = (Font2D) method.invoke(font);

            if (font2d != null) {
                // The style field we want to set is in the Font2D class, get that class
                Field styleField = Font2D.class.getDeclaredField("style");
                styleField.setAccessible(true);
                Map<String, Object> result = new HashMap<String, Object>();
                result.put("font", font2d);
                result.put("field", styleField);
                return result;
            }
        } catch (Exception ex) {
            // Oh well, we tried
        }

        return null;
    }
}

Related

  1. deriveFont(Font font, String name)
  2. deriveFont(Font sample, String family, String style, String sizeStr)