/* * 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. */ /** * @author Oleg V. Khaschansky * @version $Revision$ * * @date: Jul 12, 2005 */ package org.apache.harmony.awt.gl.font; import java.awt.Font; import java.awt.GraphicsEnvironment; import java.util.List; import java.util.Map; /** * This class chooses the default font for the given text. * If it finds the character which current font is unable to display * it starts the next font run and looks for the font which is able to * display the current character. It also caches the font mappings * (index in the array containing all fonts) for the characters, * using that fact that scripts are mainly contiguous in the UTF-16 encoding * and there's a high probability that the upper byte will be the same for the * next character as for the previous. This allows to save the space used for the cache. */ public class FontFinder { private static final float DEFAULT_FONT_SIZE = 12; private static final Font fonts[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); private static final int NUM_BLOCKS = 256; private static final int BLOCK_SIZE = 256; private static final int INDEX_MASK = 0xFF; private static final int BLOCK_SHIFT = 8; // Maps characters into the fonts array private static final int blocks[][] = new int[NUM_BLOCKS][]; /** * Finds the font which is able to display the given character * and saves the font mapping for this character * @param c - character * @return font */ static Font findFontForChar(char c) { int blockNum = c >> BLOCK_SHIFT; int index = c & INDEX_MASK; if (blocks[blockNum] == null) { blocks[blockNum] = new int[BLOCK_SIZE]; } if (blocks[blockNum][index] == 0) { blocks[blockNum][index] = 1; for (int i=0; i<fonts.length; i++) { if (fonts[i].canDisplay(c)) { blocks[blockNum][index] = i+1; break; } } } return getDefaultSizeFont(blocks[blockNum][index]-1); } /** * Derives the default size font * @param i - index in the array of all fonts * @return derived font */ static Font getDefaultSizeFont(int i) { if (fonts[i].getSize() != DEFAULT_FONT_SIZE) { fonts[i] = fonts[i].deriveFont(DEFAULT_FONT_SIZE); } return fonts[i]; } /** * Assigns default fonts for the given text run. * First three parameters are input, last three are output. * @param text - given text * @param runStart - start of the text run * @param runLimit - end of the text run * @param runStarts - starts of the resulting font runs * @param fonts - mapping of the font run starts to the fonts */ static void findFonts(char text[], int runStart, int runLimit, List<Integer> runStarts, Map<Integer, Font> fonts) { Font prevFont = null; Font currFont; for (int i = runStart; i < runLimit; i++) { currFont = findFontForChar(text[i]); if (currFont != prevFont) { prevFont = currFont; Integer idx = new Integer(i); fonts.put(idx, currFont); if (i != runStart) { runStarts.add(idx); } } } } }