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 }