CustomFont.java
上传用户:haobig99
上传日期:2022-06-15
资源大小:369k
文件大小:11k
- /*
- * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
- package com.sun.lwuit;
- import java.lang.ref.WeakReference;
- import java.util.Hashtable;
- /**
- * Implements a bitmap font that uses an image and sets of offsets to draw a font
- * with a given character set.
- *
- * @author Shai Almog
- */
- class CustomFont extends Font {
- /**
- * Keep two colors in cache by default to allow faster selection colors
- */
- private static final int COLOR_CACHE_SIZE = 20;
-
- private Hashtable colorCache = new Hashtable();
- private String charsets;
- private int color;
-
- // package protected for the resource editor
- Image cache;
-
- /**
- * The offset in which to cut the character from the bitmap
- */
- int[] cutOffsets;
- /**
- * The width of the character when drawing... this should not be confused with
- * the number of cutOffset[o + 1] - cutOffset[o]. They are completely different
- * since a character can be "wider" and "seep" into the next region. This is
- * especially true with italic characters all of which "lean" outside of their
- * bounds.
- */
- int[] charWidth;
- private int imageWidth;
- private int imageHeight;
- private WeakReference imageArrayRef;
-
-
- private int[] getImageArray() {
- if(imageArrayRef != null) {
- int[] a = (int[])imageArrayRef.get();
- if(a != null) {
- return a;
- }
- }
- int[] a = cache.getRGBCached();
-
- imageArrayRef = new WeakReference(a);
- return a;
- }
-
- /**
- * Creates a bitmap font with the given arguments
- *
- * @param bitmap a transparency map in red and black that indicates the characters
- * @param cutOffsets character offsets matching the bitmap pixels and characters in the font
- * @param charWidth The width of the character when drawing... this should not be confused with
- * the number of cutOffset[o + 1] - cutOffset[o]. They are completely different
- * since a character can be "wider" and "seep" into the next region. This is
- * especially true with italic characters all of which "lean" outside of their
- * bounds.
- * @param charsets the set of characters in the font
- * @return a font object to draw bitmap fonts
- */
- public CustomFont(Image bitmap, int[] cutOffsets, int[] charWidth, String charsets) {
- this.cutOffsets = cutOffsets;
- this.charWidth = charWidth;
- this.charsets = charsets;
- imageWidth = bitmap.getWidth();
- imageHeight = bitmap.getHeight();
- int[] imageArray = new int[imageWidth * imageHeight];
-
- // default to black colored font
- bitmap.getRGB(imageArray, 0, 0, 0, imageWidth, imageHeight);
- for(int iter = 0 ; iter < imageArray.length ; iter++) {
- // extract the red component from the font image
- // shift the alpha 8 bits to the left
- // apply the alpha to the image
- imageArray[iter] = ((imageArray[iter] & 0xff0000) << 8);
- }
- cache = Image.createImage(imageArray, imageWidth, imageHeight);
- imageArrayRef = new WeakReference(imageArray);
- }
-
- /**
- * @inheritDoc
- */
- public int charWidth(char ch) {
- int i = charsets.indexOf(ch);
- if(i < 0) {
- return 0;
- }
- return charWidth[i];
- }
- /**
- * @inheritDoc
- */
- public int getHeight() {
- return imageHeight;
- }
- private boolean checkCacheCurrentColor(int newColor) {
- Integer currentColor = new Integer(color);
- Integer newColorKey = new Integer(newColor);
- if(colorCache.get(currentColor) == null){
- colorCache.put(currentColor, new WeakReference(cache));
- }
- color = newColor;
- WeakReference newCache = (WeakReference)colorCache.get(newColorKey);
- if(newCache != null) {
- Image i = (Image)newCache.get();
- if(i != null) {
- cache = i;
- if(colorCache.size() > COLOR_CACHE_SIZE) {
- // remove a random cache element
- colorCache.remove(colorCache.keys().nextElement());
- }
- return true;
- }else{
- colorCache.remove(newColorKey);
- }
- }
- if(colorCache.size() > COLOR_CACHE_SIZE) {
- // remove a random cache element
- colorCache.remove(colorCache.keys().nextElement());
- }
- return false;
- }
-
- private void initColor(Graphics g) {
- int newColor = g.getColor();
-
- if(newColor != color && !checkCacheCurrentColor(newColor)) {
- color = newColor & 0xffffff;
- int[] imageArray = getImageArray();
- for(int iter = 0 ; iter < imageArray.length ; iter++) {
- // extract the red component from the font image
- // shift the alpha 8 bits to the left
- // apply the alpha to the image
- imageArray[iter] = color | (imageArray[iter] & 0xff000000);
- }
- cache = Image.createImage(imageArray, imageWidth, imageHeight);
- }
- }
-
- /**
- * @inheritDoc
- */
- void drawChar(Graphics g, char character, int x, int y) {
- int clipX = g.getClipX();
- int clipY = g.getClipY();
- int clipWidth = g.getClipWidth();
- int clipHeight = g.getClipHeight();
- int i = charsets.indexOf(character);
- if(i > -1) {
- initColor(g);
-
- // draw region is flaky on some devices, use setClip instead
- g.clipRect(x, y, charWidth[i], imageHeight);
- g.drawImage(cache, x - cutOffsets[i], y);
- //g.drawRegion(cache, cutOffsets[i], 0, charWidth[i], imageHeight, x, y);
- }
- // restore the clip
- g.setClip(clipX, clipY, clipWidth, clipHeight);
- }
- /**
- * @inheritDoc
- */
- public void addContrast(byte value) {
- int[] imageArray = getImageArray();
- for(int iter = 0 ; iter < imageArray.length ; iter++) {
- int alpha = (imageArray[iter] >> 24) & 0xff;
- if(alpha != 0) {
- alpha = Math.min(alpha + value, 255);
- imageArray[iter] = ((alpha << 24) & 0xff000000) | color;
- }
- }
- }
- /**
- * Override this frequently used method for a slight performance boost...
- *
- * @param g the component graphics
- * @param data the chars to draw
- * @param offset the offset to draw the chars
- * @param length the length of chars
- * @param x the x coordinate to draw the chars
- * @param y the y coordinate to draw the chars
- */
- void drawChars(Graphics g, char[] data, int offset, int length, int x, int y) {
- initColor(g);
- int clipX = g.getClipX();
- int clipY = g.getClipY();
- int clipWidth = g.getClipWidth();
- int clipHeight = g.getClipHeight();
- if(clipY <= y + getHeight() && clipY + clipHeight >= y) {
- char c;
- for ( int i = 0; i < length; i++ ) {
- c = data[offset+i];
- int position = charsets.indexOf(c);
- if(position < 0) {
- continue;
- }
- // draw region is flaky on some devices, use setClip instead
- g.clipRect(x, y, charWidth[position], imageHeight);
- if(g.getClipWidth() > 0 && g.getClipHeight() > 0) {
- g.drawImage(cache, x - cutOffsets[position], y);
- }
- x += charWidth[position];
- g.setClip(clipX, clipY, clipWidth, clipHeight);
- }
- }
- }
- /**
- * @inheritDoc
- */
- public String getCharset() {
- return charsets;
- }
- /**
- * @inheritDoc
- */
- public int charsWidth(char[] ch, int offset, int length){
- int retVal = 0;
- for(int i=0; i<length; i++){
- retVal += charWidth(ch[i + offset]);
- }
- return retVal;
- }
- /**
- * @inheritDoc
- */
- public int substringWidth(String str, int offset, int len){
- return charsWidth(str.toCharArray(), offset, len);
- }
- /**
- * @inheritDoc
- */
- public int stringWidth(String str){
- if( str==null || str.length()==0)
- return 0;
- return substringWidth(str, 0, str.length());
- }
- /**
- * @inheritDoc
- */
- public int getFace(){
- return 0;
- }
- /**
- * @inheritDoc
- */
- public int getSize(){
- return 0;
- }
- /**
- * @inheritDoc
- */
- public int getStyle() {
- return 0;
- }
-
- /**
- * @inheritDoc
- */
- public boolean equals(Object o) {
- if(o == this) {
- return true;
- }
- if(o.getClass() == getClass()) {
- CustomFont f = (CustomFont)o;
- if(charsets.equals(f.charsets)) {
- for(int iter = 0 ; iter < cutOffsets.length ; iter++) {
- if(cutOffsets[iter] != f.cutOffsets[iter]) {
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
- }