1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17/** 18 * @author Oleg V. Khaschansky 19 * @version $Revision$ 20 * 21 * @date: Jul 12, 2005 22 */ 23 24package org.apache.harmony.awt.gl.font; 25 26import java.awt.Font; 27import java.awt.GraphicsEnvironment; 28import java.util.List; 29import java.util.Map; 30 31/** 32 * This class chooses the default font for the given text. 33 * If it finds the character which current font is unable to display 34 * it starts the next font run and looks for the font which is able to 35 * display the current character. It also caches the font mappings 36 * (index in the array containing all fonts) for the characters, 37 * using that fact that scripts are mainly contiguous in the UTF-16 encoding 38 * and there's a high probability that the upper byte will be the same for the 39 * next character as for the previous. This allows to save the space used for the cache. 40 */ 41public class FontFinder { 42 private static final float DEFAULT_FONT_SIZE = 12; 43 44 private static final Font fonts[] = 45 GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); 46 47 private static final int NUM_BLOCKS = 256; 48 private static final int BLOCK_SIZE = 256; 49 private static final int INDEX_MASK = 0xFF; 50 private static final int BLOCK_SHIFT = 8; 51 52 // Maps characters into the fonts array 53 private static final int blocks[][] = new int[NUM_BLOCKS][]; 54 55 /** 56 * Finds the font which is able to display the given character 57 * and saves the font mapping for this character 58 * @param c - character 59 * @return font 60 */ 61 static Font findFontForChar(char c) { 62 int blockNum = c >> BLOCK_SHIFT; 63 int index = c & INDEX_MASK; 64 65 if (blocks[blockNum] == null) { 66 blocks[blockNum] = new int[BLOCK_SIZE]; 67 } 68 69 if (blocks[blockNum][index] == 0) { 70 blocks[blockNum][index] = 1; 71 72 for (int i=0; i<fonts.length; i++) { 73 if (fonts[i].canDisplay(c)) { 74 blocks[blockNum][index] = i+1; 75 break; 76 } 77 } 78 } 79 80 return getDefaultSizeFont(blocks[blockNum][index]-1); 81 } 82 83 /** 84 * Derives the default size font 85 * @param i - index in the array of all fonts 86 * @return derived font 87 */ 88 static Font getDefaultSizeFont(int i) { 89 if (fonts[i].getSize() != DEFAULT_FONT_SIZE) { 90 fonts[i] = fonts[i].deriveFont(DEFAULT_FONT_SIZE); 91 } 92 93 return fonts[i]; 94 } 95 96 /** 97 * Assigns default fonts for the given text run. 98 * First three parameters are input, last three are output. 99 * @param text - given text 100 * @param runStart - start of the text run 101 * @param runLimit - end of the text run 102 * @param runStarts - starts of the resulting font runs 103 * @param fonts - mapping of the font run starts to the fonts 104 */ 105 static void findFonts(char text[], int runStart, int runLimit, List<Integer> runStarts, 106 Map<Integer, Font> fonts) { 107 Font prevFont = null; 108 Font currFont; 109 for (int i = runStart; i < runLimit; i++) { 110 currFont = findFontForChar(text[i]); 111 if (currFont != prevFont) { 112 prevFont = currFont; 113 Integer idx = new Integer(i); 114 fonts.put(idx, currFont); 115 if (i != runStart) { 116 runStarts.add(idx); 117 } 118 } 119 } 120 } 121} 122