Mercurial > hg > Applications > TreeVNC
comparison src/main/java/com/glavsoft/drawing/Renderer.java @ 0:4689cc86d6cb
create TreeViewer2 Repository
author | Yu Taninari <you@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 03 Jul 2012 13:20:49 +0900 |
parents | |
children | 0c08cdc4b572 17b702648079 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4689cc86d6cb |
---|---|
1 // Copyright (C) 2010, 2011 GlavSoft LLC. | |
2 // All rights reserved. | |
3 // | |
4 //------------------------------------------------------------------------- | |
5 // This file is part of the TightVNC software. Please visit our Web site: | |
6 // | |
7 // http://www.tightvnc.com/ | |
8 // | |
9 // This program is free software; you can redistribute it and/or modify | |
10 // it under the terms of the GNU General Public License as published by | |
11 // the Free Software Foundation; either version 2 of the License, or | |
12 // (at your option) any later version. | |
13 // | |
14 // This program is distributed in the hope that it will be useful, | |
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 // GNU General Public License for more details. | |
18 // | |
19 // You should have received a copy of the GNU General Public License along | |
20 // with this program; if not, write to the Free Software Foundation, Inc., | |
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
22 //------------------------------------------------------------------------- | |
23 // | |
24 | |
25 package com.glavsoft.drawing; | |
26 | |
27 import com.glavsoft.exceptions.TransportException; | |
28 import com.glavsoft.rfb.encoding.PixelFormat; | |
29 import com.glavsoft.rfb.encoding.decoder.FramebufferUpdateRectangle; | |
30 import com.glavsoft.transport.Reader; | |
31 | |
32 import java.util.Arrays; | |
33 | |
34 /** | |
35 * Render bitmap data | |
36 * | |
37 * @author dime @ tightvnc.com | |
38 */ | |
39 public abstract class Renderer { | |
40 | |
41 protected Reader reader; | |
42 | |
43 public abstract void drawJpegImage(byte[] bytes, int offset, | |
44 int jpegBufferLength, FramebufferUpdateRectangle rect); | |
45 | |
46 protected int width; | |
47 protected int height; | |
48 protected int bytesPerPixel; | |
49 protected int bytesPerPixelSignificant; | |
50 protected int[] pixels; | |
51 protected SoftCursor cursor; | |
52 protected PixelFormat pixelFormat; | |
53 private ColorDecoder colorDecoder; | |
54 | |
55 protected void init(Reader reader, int width, int height, PixelFormat pixelFormat) { | |
56 this.reader = reader; | |
57 this.width = width; | |
58 this.height = height; | |
59 initPixelFormat(pixelFormat); | |
60 pixels = new int[width * height]; | |
61 Arrays.fill(pixels, 0); | |
62 } | |
63 | |
64 public synchronized void initPixelFormat(PixelFormat pixelFormat) { | |
65 this.pixelFormat = pixelFormat; | |
66 bytesPerPixel = pixelFormat.bitsPerPixel / 8; | |
67 bytesPerPixelSignificant = | |
68 24 == pixelFormat.depth && 32 == pixelFormat.bitsPerPixel ? 3 : bytesPerPixel; | |
69 colorDecoder = new ColorDecoder(pixelFormat); | |
70 } | |
71 | |
72 /** | |
73 * Draw byte array bitmap data | |
74 * | |
75 * @param bytes bitmap data | |
76 * @param x bitmap x position | |
77 * @param y bitmap y position | |
78 * @param width bitmap width | |
79 * @param height bitmap height | |
80 */ | |
81 public void drawBytes(byte[] bytes, int x, int y, int width, int height) { | |
82 int i = 0; | |
83 for (int ly = y; ly < y + height; ++ly) { | |
84 int end = ly * this.width + x + width; | |
85 for (int pixelsOffset = ly * this.width + x; pixelsOffset < end; ++pixelsOffset) { | |
86 pixels[pixelsOffset] = getPixelColor(bytes, i); | |
87 i += bytesPerPixel; | |
88 } | |
89 } | |
90 } | |
91 | |
92 /** | |
93 * Draw byte array bitmap data (for ZRLE) | |
94 */ | |
95 public synchronized int drawCompactBytes(byte[] bytes, int offset, int x, int y, int width, int height) { | |
96 int i = offset; | |
97 for (int ly = y; ly < y + height; ++ly) { | |
98 int end = ly * this.width + x + width; | |
99 for (int pixelsOffset = ly * this.width + x; pixelsOffset < end; ++pixelsOffset) { | |
100 pixels[pixelsOffset] = getCompactPixelColor(bytes, i); | |
101 i += bytesPerPixelSignificant; | |
102 } | |
103 } | |
104 return i - offset; | |
105 } | |
106 | |
107 /** | |
108 * Draw int (colors) array bitmap data (for ZRLE) | |
109 */ | |
110 public synchronized void drawColoredBitmap(int[] colors, int x, int y, int width, int height) { | |
111 int i = 0; | |
112 for (int ly = y; ly < y + height; ++ly) { | |
113 int end = ly * this.width + x + width; | |
114 for (int pixelsOffset = ly * this.width + x; pixelsOffset < end; ++pixelsOffset) { | |
115 pixels[pixelsOffset] = colors[i++]; | |
116 } | |
117 } | |
118 } | |
119 | |
120 /** | |
121 * Draw byte array bitmap data (for Tight) | |
122 */ | |
123 public synchronized int drawTightBytes(byte[] bytes, int offset, int x, int y, int width, int height) { | |
124 int i = offset; | |
125 for (int ly = y; ly < y + height; ++ly) { | |
126 int end = ly * this.width + x + width; | |
127 for (int pixelsOffset = ly * this.width + x; pixelsOffset < end; ++pixelsOffset) { | |
128 pixels[pixelsOffset] = colorDecoder.getTightColor(bytes, i); | |
129 i += bytesPerPixelSignificant; | |
130 } | |
131 } | |
132 return i - offset; | |
133 } | |
134 | |
135 /** | |
136 * Draw byte array bitmap data (from array with plain RGB color components. Assumed: rrrrrrrr gggggggg bbbbbbbb) | |
137 */ | |
138 public synchronized void drawUncaliberedRGBLine(byte[] bytes, int x, int y, int width) { | |
139 int end = y * this.width + x + width; | |
140 for (int i=3, pixelsOffset = y * this.width + x; pixelsOffset < end; ++pixelsOffset) { | |
141 pixels[pixelsOffset] = | |
142 // (0xff & bytes[i++]) << 16 | | |
143 // (0xff & bytes[i++]) << 8 | | |
144 // 0xff & bytes[i++]; | |
145 (0xff & 255 * (colorDecoder.redMax & bytes[i++]) / colorDecoder.redMax) << 16 | | |
146 (0xff & 255 * (colorDecoder.greenMax & bytes[i++]) / colorDecoder.greenMax) << 8 | | |
147 0xff & 255 * (colorDecoder.blueMax & bytes[i++]) / colorDecoder.blueMax; | |
148 } | |
149 } | |
150 | |
151 /** | |
152 * Draw paletted byte array bitmap data | |
153 * | |
154 * @param buffer bitmap data | |
155 * @param rect bitmap location and dimensions | |
156 * @param palette colour palette | |
157 */ | |
158 public synchronized void drawBytesWithPalette(byte[] buffer, FramebufferUpdateRectangle rect, | |
159 int[] palette) { | |
160 // 2 colors | |
161 if (palette.length == 2) { | |
162 int dx, dy, n; | |
163 int i = rect.y * this.width + rect.x; | |
164 int rowBytes = (rect.width + 7) / 8; | |
165 byte b; | |
166 | |
167 for (dy = 0; dy < rect.height; dy++) { | |
168 for (dx = 0; dx < rect.width / 8; dx++) { | |
169 b = buffer[dy * rowBytes + dx]; | |
170 for (n = 7; n >= 0; n--) { | |
171 pixels[i++] = palette[b >> n & 1]; | |
172 } | |
173 } | |
174 for (n = 7; n >= 8 - rect.width % 8; n--) { | |
175 pixels[i++] = palette[buffer[dy * rowBytes + dx] >> n & 1]; | |
176 } | |
177 i += this.width- rect.width; | |
178 } | |
179 } else { | |
180 // 3..255 colors (assuming bytesPixel == 4). | |
181 int i = 0; | |
182 for (int ly = rect.y; ly < rect.y + rect.height; ++ly) { | |
183 for (int lx = rect.x; lx < rect.x + rect.width; ++lx) { | |
184 int pixelsOffset = ly * this.width + lx; | |
185 pixels[pixelsOffset] = palette[buffer[i++] & 0xFF]; | |
186 } | |
187 } | |
188 } | |
189 | |
190 } | |
191 | |
192 /** | |
193 * Copy rectangle region from one position to another. Regions may be overlapped. | |
194 * | |
195 * @param srcX source rectangle x position | |
196 * @param srcY source rectangle y position | |
197 * @param dstRect destination rectangle | |
198 */ | |
199 public synchronized void copyRect(int srcX, int srcY, FramebufferUpdateRectangle dstRect) { | |
200 int startSrcY, endSrcY, dstY, deltaY; | |
201 if (srcY > dstRect.y) { | |
202 startSrcY = srcY; | |
203 endSrcY = srcY + dstRect.height; | |
204 dstY = dstRect.y; | |
205 deltaY = +1; | |
206 } else { | |
207 startSrcY = srcY + dstRect.height - 1; | |
208 endSrcY = srcY -1; | |
209 dstY = dstRect.y + dstRect.height - 1; | |
210 deltaY = -1; | |
211 } | |
212 for (int y = startSrcY; y != endSrcY; y += deltaY) { | |
213 System.arraycopy(pixels, y * width + srcX, | |
214 pixels, dstY * width + dstRect.x, dstRect.width); | |
215 dstY += deltaY; | |
216 } | |
217 } | |
218 | |
219 /** | |
220 * Fill rectangle region with specified colour | |
221 * | |
222 * @param color colour to fill with | |
223 * @param rect rectangle region posions and dimensions | |
224 */ | |
225 public void fillRect(int color, FramebufferUpdateRectangle rect) { | |
226 fillRect(color, rect.x, rect.y, rect.width, rect.height); | |
227 } | |
228 | |
229 /** | |
230 * Fill rectangle region with specified colour | |
231 * | |
232 * @param color colour to fill with | |
233 * @param x rectangle x position | |
234 * @param y rectangle y position | |
235 * @param width rectangle width | |
236 * @param height rectangle height | |
237 */ | |
238 public synchronized void fillRect(int color, int x, int y, int width, int height) { | |
239 int sy = y * this.width + x; | |
240 int ey = sy + height * this.width; | |
241 for (int i = sy; i < ey; i += this.width) { | |
242 Arrays.fill(pixels, i, i + width, color); | |
243 } | |
244 } | |
245 | |
246 /** | |
247 * Reads color bytes (PIXEL) from reader, returns int combined RGB | |
248 * value consisting of the red component in bits 16-23, the green component | |
249 * in bits 8-15, and the blue component in bits 0-7. May be used directly for | |
250 * creation awt.Color object | |
251 */ | |
252 public int readPixelColor(Reader reader) throws TransportException { | |
253 return colorDecoder.readColor(reader); | |
254 } | |
255 | |
256 public int readTightPixelColor(Reader reader) throws TransportException { | |
257 return colorDecoder.readTightColor(reader); | |
258 } | |
259 | |
260 public ColorDecoder getColorDecoder() { | |
261 return colorDecoder; | |
262 } | |
263 | |
264 public int getCompactPixelColor(byte[] bytes, int offset) { | |
265 return colorDecoder.getCompactColor(bytes, offset); | |
266 } | |
267 | |
268 public int getPixelColor(byte[] bytes, int offset) { | |
269 return colorDecoder.getColor(bytes, offset); | |
270 } | |
271 | |
272 public int getBytesPerPixel() { | |
273 return bytesPerPixel; | |
274 } | |
275 | |
276 public int getBytesPerPixelSignificant() { | |
277 return bytesPerPixelSignificant; | |
278 } | |
279 | |
280 public void fillColorBitmapWithColor(int[] bitmapData, int decodedOffset, int rlength, int color) { | |
281 while (rlength-- > 0) { | |
282 bitmapData[decodedOffset++] = color; | |
283 } | |
284 } | |
285 | |
286 /** | |
287 * Width of rendered image | |
288 * | |
289 * @return width | |
290 */ | |
291 public int getWidth() { | |
292 return width; | |
293 } | |
294 | |
295 /** | |
296 * Height of rendered image | |
297 * | |
298 * @return height | |
299 */ | |
300 public int getHeight() { | |
301 return height; | |
302 } | |
303 | |
304 /** | |
305 * Read and decode cursor image | |
306 * | |
307 * @param rect new cursor hot point position and cursor dimensions | |
308 * @throws TransportException | |
309 */ | |
310 public void createCursor(int[] cursorPixels, FramebufferUpdateRectangle rect) | |
311 throws TransportException { | |
312 synchronized (cursor) { | |
313 cursor.createCursor(cursorPixels, rect.x, rect.y, rect.width, rect.height); | |
314 } | |
315 } | |
316 | |
317 /** | |
318 * Read and decode new cursor position | |
319 * | |
320 * @param rect cursor position | |
321 */ | |
322 public void decodeCursorPosition(FramebufferUpdateRectangle rect) { | |
323 synchronized (cursor) { | |
324 cursor.updatePosition(rect.x, rect.y); | |
325 } | |
326 } | |
327 | |
328 } |