1 /*** 2 * Redistribution and use in source and binary forms, with or without 3 * modification, are permitted provided that the following conditions are 4 * met : 5 * 6 * . Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * 9 * . Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * . The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $Id: MonospacedFont.java 395 2005-12-31 04:05:41Z mat007 $ 29 */ 30 31 package palmed.edit; 32 33 import javax.microedition.lcdui.Graphics; 34 import javax.microedition.lcdui.Image; 35 36 /*** 37 * This class implements a custom monospaced bitmap font. 38 * <p> 39 * The only image format supported is png. 40 * 41 * @author Mathieu Champlon 42 * @version $Revision: 395 $ $Date: 2005-12-31 13:05:41 +0900 (sam., 31 déc. 2005) $ 43 */ 44 public final class MonospacedFont implements IFont 45 { 46 /*** 47 * The value of the first character. 48 */ 49 private static final int FIRST_CHARACTER = 32; 50 /*** 51 * The number of characters in the resource bitmap. 52 */ 53 private static final int NUMBER_OF_CHARACTERS = 0xFF; 54 /*** 55 * The fonts resource directory. 56 */ 57 private static final String PREFIX = "/fonts/"; 58 /*** 59 * The selection background color. 60 */ 61 private static final int SELECTION_BACKGROUND_COLOR = 0x3165CE; 62 /*** 63 * The characters resource. 64 */ 65 private final Image image_; 66 /*** 67 * The selected characters resource. 68 */ 69 private final Image selected_; 70 /*** 71 * The height of a character. 72 */ 73 private final int height_; 74 /*** 75 * The width of a character. 76 */ 77 private final int width_; 78 79 /*** 80 * Create a monospaced font. 81 * 82 * @param name the font bitmap filename 83 */ 84 public MonospacedFont( final String name ) 85 { 86 image_ = load( PREFIX + name + ".png" ); 87 selected_ = load( PREFIX + "s_" + name + ".png" ); 88 if( selected_.getHeight() != image_.getHeight() || selected_.getWidth() != image_.getWidth() ) 89 throw new RuntimeException( "font bitmaps sizes mismatch" ); 90 height_ = image_.getHeight(); 91 width_ = image_.getWidth() / (NUMBER_OF_CHARACTERS - FIRST_CHARACTER); 92 } 93 94 private Image load( final String filename ) 95 { 96 Image image; 97 try 98 { 99 image = Image.createImage( filename ); 100 } 101 catch( Exception e ) 102 { 103 throw new IllegalArgumentException( "cannot load font file '" + filename + "': " + e ); 104 } 105 if( image.getHeight() <= 0 || image.getWidth() <= 0 ) 106 throw new RuntimeException( "bitmap font has null size" ); 107 return image; 108 } 109 110 /*** 111 * {@inheritDoc} 112 */ 113 public int getWidth() 114 { 115 return width_; 116 } 117 118 /*** 119 * {@inheritDoc} 120 */ 121 public int getHeight() 122 { 123 return height_; 124 } 125 126 /*** 127 * {@inheritDoc} 128 */ 129 public void draw( final Graphics g, final String text, final int start, final int end, final int y ) 130 { 131 drawChars( g, text, start, end, y, image_ ); 132 } 133 134 /*** 135 * {@inheritDoc} 136 */ 137 public void drawSelection( final Graphics g, final String text, final int start, final int end, final int y ) 138 { 139 drawChars( g, text, start, end, y, selected_ ); 140 } 141 142 private void drawChars( final Graphics g, final String text, final int start, final int end, final int y, 143 final Image image ) 144 { 145 int clipX = g.getClipX(); 146 int clipY = g.getClipY(); 147 int clipW = g.getClipWidth(); 148 int clipH = g.getClipHeight(); 149 for( int i = start; i < end; i++ ) 150 { 151 final int w = Math.min( width_, clipX + clipW - i * width_ ); 152 final int h = Math.min( height_, clipY + clipH - y * height_ ); 153 g.setClip( i * width_, y * height_, w, h ); 154 final int offset = i - text.charAt( i ) + FIRST_CHARACTER; 155 g.drawImage( image, offset * width_, y * height_, Graphics.TOP | Graphics.LEFT ); 156 } 157 g.setClip( clipX, clipY, clipW, clipH ); 158 } 159 160 /*** 161 * {@inheritDoc} 162 */ 163 public void drawEmptySelection( final Graphics g, final int start, final int end, final int y ) 164 { 165 g.setColor( SELECTION_BACKGROUND_COLOR ); 166 g.fillRect( start * width_, y * height_, (end - start) * width_, height_ ); 167 } 168 }