View Javadoc

1   /*
2    * MicroEmulator 
3    * Copyright (C) 2001 Bartek Teodorczyk <barteo@barteo.net>
4    * 
5    * This library is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as published by the
7    * Free Software Foundation; either version 2.1 of the License, or (at your
8    * option) any later version.
9    * 
10   * This library is distributed in the hope that it will be useful, but WITHOUT
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12   * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13   * for more details.
14   * 
15   * You should have received a copy of the GNU Lesser General Public License
16   * along with this library; if not, write to the Free Software Foundation,
17   * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18   */
19  
20  package javax.microedition.lcdui;
21  
22  import org.microemu.device.DeviceFactory;
23  
24  class StringComponent {
25  	private String text;
26  
27  	private int breaks[] = new int[4];
28  
29  	private boolean invertPaint = false;
30  
31  	private int numOfBreaks;
32  
33  	private int width;
34  
35  	private int widthDecreaser;
36  
37  	public StringComponent() {
38  		this(null);
39  	}
40  
41  	public StringComponent(String text) {
42  		synchronized (this) {
43  			this.width = -1;
44  			this.widthDecreaser = 0;
45  			setText(text);
46  		}
47  	}
48  
49  	public int getCharHeight() {
50  		return Font.getDefaultFont().getHeight();
51  	}
52  
53  	public int getCharPositionX(int num) {
54  		synchronized (this) {
55  			if (numOfBreaks == -1) {
56  				updateBreaks();
57  			}
58  	
59  			int i, prevIndex = 0;
60  			Font f = Font.getDefaultFont();
61  	
62  			for (i = 0; i < numOfBreaks; i++) {
63  				if (num < breaks[i]) {
64  					break;
65  				}
66  				prevIndex = breaks[i];
67  			}
68  			
69  			return f.substringWidth(text, prevIndex, num - prevIndex);
70  		}
71  	}
72  
73  	public int getCharPositionY(int num) {
74  		int y = 0;
75  		synchronized (this) {
76  			if (numOfBreaks == -1) {
77  				updateBreaks();
78  			}
79  	
80  			Font f = Font.getDefaultFont();
81  	
82  			for (int i = 0; i < numOfBreaks; i++) {
83  				if (num < breaks[i]) {
84  					break;
85  				}
86  				y += f.getHeight();
87  			}
88  		}
89  
90  		return y;
91  	}
92  
93  	public int getHeight() {
94  		int height;
95  		synchronized (this) {
96  			if (numOfBreaks == -1) {
97  				updateBreaks();
98  			}
99  
100 			Font f = Font.getDefaultFont();
101 
102 			if (text == null) {
103 				return 0;
104 			}
105 
106 			if (numOfBreaks == 0) {
107 				return f.getHeight();
108 			}
109 
110 			height = numOfBreaks * f.getHeight();
111 
112 			if (breaks[numOfBreaks - 1] == text.length() - 1
113 					&& text.charAt(text.length() - 1) == '\n') {
114 			} else {
115 				height += f.getHeight();
116 			}
117 		}
118 
119 		return height;
120 	}
121 
122 	public String getText() {
123 		return text;
124 	}
125 
126 	public void invertPaint(boolean state) {
127 		synchronized (this) {
128 			invertPaint = state;
129 		}
130 	}
131 
132 	public int paint(Graphics g) {
133 		if (text == null) {
134 			return 0;
135 		}
136 
137 		int y;
138 		synchronized (this) {
139 			if (numOfBreaks == -1) {
140 				updateBreaks();
141 			}
142 	
143 			int i, prevIndex;
144 			Font f = Font.getDefaultFont();
145 	
146 			for (i = prevIndex = y = 0; i < numOfBreaks; i++) {
147 				if (invertPaint) {
148 					g.setGrayScale(0);
149 				} else {
150 					g.setGrayScale(255);
151 				}
152 				g.fillRect(0, y, width, f.getHeight());
153 				if (invertPaint) {
154 					g.setGrayScale(255);
155 				} else {
156 					g.setGrayScale(0);
157 				}
158 				g.drawSubstring(text, prevIndex, breaks[i] - prevIndex, 0, y, 0);
159 				prevIndex = breaks[i];
160 				y += f.getHeight();
161 			}
162 			if (prevIndex != text.length()) {
163 				if (invertPaint) {
164 					g.setGrayScale(0);
165 				} else {
166 					g.setGrayScale(255);
167 				}
168 				g.fillRect(0, y, width, f.getHeight());
169 				if (invertPaint) {
170 					g.setGrayScale(255);
171 				} else {
172 					g.setGrayScale(0);
173 				}
174 				g.drawSubstring(text, prevIndex, text.length() - prevIndex, 0, y, 0);
175 				y += f.getHeight();
176 			}
177 		}
178 
179 		return y;
180 	}
181 
182 	public void setText(String text) {
183 		synchronized (this) {
184 			this.text = text;
185 			this.numOfBreaks = -1;
186 		}
187 	}
188 
189 	public void setWidthDecreaser(int widthDecreaser) {
190 		synchronized (this) {
191 			this.widthDecreaser = widthDecreaser;
192 			numOfBreaks = -1;
193 		}
194 	}
195 
196 	private void insertBreak(int pos) {
197 		int i;
198 
199 		for (i = 0; i < numOfBreaks; i++) {
200 			if (pos < breaks[i]) {
201 				break;
202 			}
203 		}
204 		if (numOfBreaks + 1 == breaks.length) {
205 			int newbreaks[] = new int[breaks.length + 4];
206 			System.arraycopy(breaks, 0, newbreaks, 0, numOfBreaks);
207 			breaks = newbreaks;
208 		}
209 		System.arraycopy(breaks, i, breaks, i + 1, numOfBreaks - i);
210 		breaks[i] = pos;
211 		numOfBreaks++;
212 	}
213 
214 	private void updateBreaks() {
215 		if (text == null) {
216 			return;
217 		}
218 
219 		// TODO use Displayable width
220 		width = DeviceFactory.getDevice().getDeviceDisplay().getWidth()
221 				- widthDecreaser;
222 
223 		int prevIndex = 0;
224 		int canBreak = 0;
225 		numOfBreaks = 0;
226 		Font f = Font.getDefaultFont();
227 
228 		for (int i = 0; i < text.length(); i++) {
229 			if (text.charAt(i) == ' ') {
230 				canBreak = i + 1;
231 			}
232 			if (text.charAt(i) == '\n') {
233 				insertBreak(i);
234 				canBreak = 0;
235 				prevIndex = i + 1;
236 				continue;
237 			}
238 			if (f.substringWidth(text, prevIndex, i - prevIndex + 1) > width) {
239 				if (canBreak != 0) {
240 					insertBreak(canBreak);
241 					i = canBreak;
242 					prevIndex = i;
243 				} else {
244 					insertBreak(i);
245 					prevIndex = i + 1;
246 				}
247 				canBreak = 0;
248 			}
249 		}
250 	}
251 
252 }