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 }