blob: a19aae617734fde5aa6512139d2949feacd755ea [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id$ */
package org.apache.fop.fonts;
import org.apache.fop.datatypes.PercentBaseContext;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.flow.Character;
import org.apache.fop.fo.properties.CommonFont;
import org.apache.fop.util.CharUtilities;
/**
* Helper class for automatic font selection.
* <p>
* TODO: Check if this could be merged with another font class, such as
* {@link FontManager}.
*/
public final class FontSelector {
private FontSelector() {
// Static since this is an utility class.
}
private static Font selectFontForCharacter(char c, FONode fonode,
CommonFont commonFont, PercentBaseContext context) {
FontInfo fi = fonode.getFOEventHandler().getFontInfo();
FontTriplet[] fontkeys = commonFont.getFontState(fi);
for (FontTriplet fontkey : fontkeys) {
Font font = fi.getFontInstance(fontkey, commonFont.fontSize
.getValue(context));
if (font.hasChar(c)) {
return font;
}
}
return fi.getFontInstance(fontkeys[0], commonFont.fontSize
.getValue(context));
}
/**
* Selects a font which is able to display the given character.
*
* @param fobj
* a Character object containing the character and its
* attributes.
* @param context
* the Percent-based context needed for creating the actual font.
* @return a Font object.
*/
public static Font selectFontForCharacter(Character fobj,
PercentBaseContext context) {
return FontSelector.selectFontForCharacter(fobj.getCharacter(), fobj,
fobj.getCommonFont(), context);
}
/**
* Selects a font which is able to display the given character.
*
* @param c
* character to find.
* @param text
* the text object which contains the character
* @param context
* the Percent-based context needed for creating the actual font.
* @return a Font object.
*/
public static Font selectFontForCharacterInText(char c, FOText text,
PercentBaseContext context) {
return FontSelector.selectFontForCharacter(c, text, text
.getCommonFont(), context);
}
/**
* Selects a font which is able to display the most of the given characters.
*
* @param charSeq
* Text to go through
* @param firstIndex
* first index within text.
* @param breakIndex
* last index +1 within text.
* @param text
* the text object which contains the character
* @param context
* the Percent-based context needed for creating the actual font.
* @return a Font object.
*/
public static Font selectFontForCharactersInText(CharSequence charSeq,
int firstIndex, int breakIndex, FOText text,
PercentBaseContext context) {
final FontInfo fi = text.getFOEventHandler().getFontInfo();
final CommonFont commonFont = text.getCommonFont();
final FontTriplet[] fontkeys = commonFont.getFontState(fi);
final int numFonts = fontkeys.length;
final Font[] fonts = new Font[numFonts];
final int[] fontCount = new int[numFonts];
for (int fontnum = 0; fontnum < numFonts; fontnum++) {
final Font font = fi.getFontInstance(fontkeys[fontnum],
commonFont.fontSize.getValue(context));
fonts[fontnum] = font;
int numCodePoints = 0;
for (int cp : CharUtilities.codepointsIter(charSeq, firstIndex, breakIndex)) {
numCodePoints++;
if (font.hasCodePoint(cp)) {
fontCount[fontnum]++;
}
}
// quick fall through if all codepoints can be displayed
if (fontCount[fontnum] == numCodePoints) {
return font;
}
}
Font font = fonts[0];
int max = fontCount[0];
for (int fontnum = 1; fontnum < numFonts; fontnum++) {
final int curCount = fontCount[fontnum];
if (curCount > max) {
font = fonts[fontnum];
max = curCount;
}
}
return font;
}
}