19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this work for additional information regarding copyright ownership. 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (the "License"); you may not use this file except in compliance with 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License. You may obtain a copy of the License at 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @author Oleg V. Khaschansky 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @version $Revision$ 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @date: Jul 12, 2005 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage org.apache.harmony.awt.gl.font; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.Font; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.awt.GraphicsEnvironment; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class chooses the default font for the given text. 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If it finds the character which current font is unable to display 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it starts the next font run and looks for the font which is able to 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * display the current character. It also caches the font mappings 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (index in the array containing all fonts) for the characters, 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using that fact that scripts are mainly contiguous in the UTF-16 encoding 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and there's a high probability that the upper byte will be the same for the 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * next character as for the previous. This allows to save the space used for the cache. 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class FontFinder { 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float DEFAULT_FONT_SIZE = 12; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final Font fonts[] = 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int NUM_BLOCKS = 256; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int BLOCK_SIZE = 256; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int INDEX_MASK = 0xFF; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int BLOCK_SHIFT = 8; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Maps characters into the fonts array 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int blocks[][] = new int[NUM_BLOCKS][]; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Finds the font which is able to display the given character 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and saves the font mapping for this character 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param c - character 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return font 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static Font findFontForChar(char c) { 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int blockNum = c >> BLOCK_SHIFT; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = c & INDEX_MASK; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (blocks[blockNum] == null) { 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project blocks[blockNum] = new int[BLOCK_SIZE]; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (blocks[blockNum][index] == 0) { 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project blocks[blockNum][index] = 1; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<fonts.length; i++) { 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fonts[i].canDisplay(c)) { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project blocks[blockNum][index] = i+1; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return getDefaultSizeFont(blocks[blockNum][index]-1); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Derives the default size font 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param i - index in the array of all fonts 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return derived font 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static Font getDefaultSizeFont(int i) { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fonts[i].getSize() != DEFAULT_FONT_SIZE) { 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fonts[i] = fonts[i].deriveFont(DEFAULT_FONT_SIZE); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return fonts[i]; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Assigns default fonts for the given text run. 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * First three parameters are input, last three are output. 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param text - given text 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param runStart - start of the text run 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param runLimit - end of the text run 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param runStarts - starts of the resulting font runs 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param fonts - mapping of the font run starts to the fonts 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static void findFonts(char text[], int runStart, int runLimit, List<Integer> runStarts, 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Map<Integer, Font> fonts) { 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Font prevFont = null; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Font currFont; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = runStart; i < runLimit; i++) { 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project currFont = findFontForChar(text[i]); 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (currFont != prevFont) { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project prevFont = currFont; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Integer idx = new Integer(i); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fonts.put(idx, currFont); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i != runStart) { 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project runStarts.add(idx); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 122