001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Oleg V. Khaschansky
019: * @version $Revision$
020: *
021: * @date: Jul 12, 2005
022: */package org.apache.harmony.awt.gl.font;
023:
024: import java.awt.Font;
025: import java.awt.GraphicsEnvironment;
026: import java.util.List;
027: import java.util.Map;
028:
029: /**
030: * This class chooses the default font for the given text.
031: * If it finds the character which current font is unable to display
032: * it starts the next font run and looks for the font which is able to
033: * display the current character. It also caches the font mappings
034: * (index in the array containing all fonts) for the characters,
035: * using that fact that scripts are mainly contiguous in the UTF-16 encoding
036: * and there's a high probability that the upper byte will be the same for the
037: * next character as for the previous. This allows to save the space used for the cache.
038: */
039: public class FontFinder {
040: private static final float DEFAULT_FONT_SIZE = 12;
041:
042: private static final Font fonts[] = GraphicsEnvironment
043: .getLocalGraphicsEnvironment().getAllFonts();
044:
045: private static final int NUM_BLOCKS = 256;
046: private static final int BLOCK_SIZE = 256;
047: private static final int INDEX_MASK = 0xFF;
048: private static final int BLOCK_SHIFT = 8;
049:
050: // Maps characters into the fonts array
051: private static final int blocks[][] = new int[NUM_BLOCKS][];
052:
053: /**
054: * Finds the font which is able to display the given character
055: * and saves the font mapping for this character
056: * @param c - character
057: * @return font
058: */
059: static Font findFontForChar(char c) {
060: int blockNum = c >> BLOCK_SHIFT;
061: int index = c & INDEX_MASK;
062:
063: if (blocks[blockNum] == null) {
064: blocks[blockNum] = new int[BLOCK_SIZE];
065: }
066:
067: if (blocks[blockNum][index] == 0) {
068: blocks[blockNum][index] = 1;
069:
070: for (int i = 0; i < fonts.length; i++) {
071: if (fonts[i].canDisplay(c)) {
072: blocks[blockNum][index] = i + 1;
073: break;
074: }
075: }
076: }
077:
078: return getDefaultSizeFont(blocks[blockNum][index] - 1);
079: }
080:
081: /**
082: * Derives the default size font
083: * @param i - index in the array of all fonts
084: * @return derived font
085: */
086: static Font getDefaultSizeFont(int i) {
087: if (fonts[i].getSize() != DEFAULT_FONT_SIZE) {
088: fonts[i] = fonts[i].deriveFont(DEFAULT_FONT_SIZE);
089: }
090:
091: return fonts[i];
092: }
093:
094: /**
095: * Assigns default fonts for the given text run.
096: * First three parameters are input, last three are output.
097: * @param text - given text
098: * @param runStart - start of the text run
099: * @param runLimit - end of the text run
100: * @param runStarts - starts of the resulting font runs
101: * @param fonts - mapping of the font run starts to the fonts
102: */
103: static void findFonts(char text[], int runStart, int runLimit,
104: List<Integer> runStarts, Map<Integer, Object> fonts) {
105: Font prevFont = null;
106: Font currFont;
107: for (int i = runStart; i < runLimit; i++) {
108: currFont = findFontForChar(text[i]);
109: if (currFont != prevFont) {
110: prevFont = currFont;
111: Integer idx = new Integer(i);
112: fonts.put(idx, currFont);
113: if (i != runStart) {
114: runStarts.add(idx);
115: }
116: }
117: }
118: }
119: }
|