Mercurial > hg > Applications > TightVNC_orginal
comparison src/main/java/com/glavsoft/drawing/AbstructRenderer.java @ 30:0c08cdc4b572
Create AbstractRenderer.java
and
Renderer change to Interface
author | one |
---|---|
date | Sat, 01 Sep 2012 20:33:48 +0900 |
parents | |
children | 3c072f2f39bb |
comparison
equal
deleted
inserted
replaced
29:57eb5575e6c4 | 30:0c08cdc4b572 |
---|---|
1 package com.glavsoft.drawing; | |
2 | |
3 import java.util.Arrays; | |
4 | |
5 import com.glavsoft.exceptions.TransportException; | |
6 import com.glavsoft.rfb.encoding.PixelFormat; | |
7 import com.glavsoft.rfb.encoding.decoder.FramebufferUpdateRectangle; | |
8 import com.glavsoft.transport.Reader; | |
9 | |
10 public abstract class AbstructRenderer implements Renderer { | |
11 | |
12 protected Reader reader; | |
13 | |
14 public abstract void drawJpegImage(byte[] bytes, int offset, | |
15 int jpegBufferLength, FramebufferUpdateRectangle rect); | |
16 | |
17 protected int width; | |
18 protected int height; | |
19 protected int bytesPerPixel; | |
20 protected int bytesPerPixelSignificant; | |
21 protected int[] pixels; | |
22 protected SoftCursor cursor; | |
23 protected PixelFormat pixelFormat; | |
24 private ColorDecoder colorDecoder; | |
25 | |
26 protected void init(Reader reader, int width, int height, PixelFormat pixelFormat) { | |
27 this.reader = reader; | |
28 this.width = width; | |
29 this.height = height; | |
30 initPixelFormat(pixelFormat); | |
31 pixels = new int[width * height]; | |
32 Arrays.fill(pixels, 0); | |
33 } | |
34 | |
35 public synchronized void initPixelFormat(PixelFormat pixelFormat) { | |
36 this.pixelFormat = pixelFormat; | |
37 bytesPerPixel = pixelFormat.bitsPerPixel / 8; | |
38 bytesPerPixelSignificant = | |
39 24 == pixelFormat.depth && 32 == pixelFormat.bitsPerPixel ? 3 : bytesPerPixel; | |
40 colorDecoder = new ColorDecoder(pixelFormat); | |
41 } | |
42 | |
43 /** | |
44 * Draw byte array bitmap data | |
45 * | |
46 * @param bytes bitmap data | |
47 * @param x bitmap x position | |
48 * @param y bitmap y position | |
49 * @param width bitmap width | |
50 * @param height bitmap height | |
51 */ | |
52 public void drawBytes(byte[] bytes, int x, int y, int width, int height) { | |
53 int i = 0; | |
54 for (int ly = y; ly < y + height; ++ly) { | |
55 int end = ly * this.width + x + width; | |
56 for (int pixelsOffset = ly * this.width + x; pixelsOffset < end; ++pixelsOffset) { | |
57 pixels[pixelsOffset] = getPixelColor(bytes, i); | |
58 i += bytesPerPixel; | |
59 } | |
60 } | |
61 } | |
62 | |
63 /** | |
64 * Draw byte array bitmap data (for ZRLE) | |
65 */ | |
66 public synchronized int drawCompactBytes(byte[] bytes, int offset, int x, int y, int width, int height) { | |
67 int i = offset; | |
68 for (int ly = y; ly < y + height; ++ly) { | |
69 int end = ly * this.width + x + width; | |
70 for (int pixelsOffset = ly * this.width + x; pixelsOffset < end; ++pixelsOffset) { | |
71 pixels[pixelsOffset] = getCompactPixelColor(bytes, i); | |
72 i += bytesPerPixelSignificant; | |
73 } | |
74 } | |
75 return i - offset; | |
76 } | |
77 | |
78 /** | |
79 * Draw int (colors) array bitmap data (for ZRLE) | |
80 */ | |
81 public synchronized void drawColoredBitmap(int[] colors, 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] = colors[i++]; | |
87 } | |
88 } | |
89 } | |
90 | |
91 /** | |
92 * Draw byte array bitmap data (for Tight) | |
93 */ | |
94 public synchronized int drawTightBytes(byte[] bytes, int offset, int x, int y, int width, int height) { | |
95 int i = offset; | |
96 for (int ly = y; ly < y + height; ++ly) { | |
97 int end = ly * this.width + x + width; | |
98 for (int pixelsOffset = ly * this.width + x; pixelsOffset < end; ++pixelsOffset) { | |
99 pixels[pixelsOffset] = colorDecoder.getTightColor(bytes, i); | |
100 i += bytesPerPixelSignificant; | |
101 } | |
102 } | |
103 return i - offset; | |
104 } | |
105 | |
106 /** | |
107 * Draw byte array bitmap data (from array with plain RGB color components. Assumed: rrrrrrrr gggggggg bbbbbbbb) | |
108 */ | |
109 public synchronized void drawUncaliberedRGBLine(byte[] bytes, int x, int y, int width) { | |
110 int end = y * this.width + x + width; | |
111 for (int i=3, pixelsOffset = y * this.width + x; pixelsOffset < end; ++pixelsOffset) { | |
112 pixels[pixelsOffset] = | |
113 // (0xff & bytes[i++]) << 16 | | |
114 // (0xff & bytes[i++]) << 8 | | |
115 // 0xff & bytes[i++]; | |
116 (0xff & 255 * (colorDecoder.redMax & bytes[i++]) / colorDecoder.redMax) << 16 | | |
117 (0xff & 255 * (colorDecoder.greenMax & bytes[i++]) / colorDecoder.greenMax) << 8 | | |
118 0xff & 255 * (colorDecoder.blueMax & bytes[i++]) / colorDecoder.blueMax; | |
119 } | |
120 } | |
121 | |
122 /** | |
123 * Draw paletted byte array bitmap data | |
124 * | |
125 * @param buffer bitmap data | |
126 * @param rect bitmap location and dimensions | |
127 * @param palette colour palette | |
128 */ | |
129 public synchronized void drawBytesWithPalette(byte[] buffer, FramebufferUpdateRectangle rect, | |
130 int[] palette) { | |
131 // 2 colors | |
132 if (palette.length == 2) { | |
133 int dx, dy, n; | |
134 int i = rect.y * this.width + rect.x; | |
135 int rowBytes = (rect.width + 7) / 8; | |
136 byte b; | |
137 | |
138 for (dy = 0; dy < rect.height; dy++) { | |
139 for (dx = 0; dx < rect.width / 8; dx++) { | |
140 b = buffer[dy * rowBytes + dx]; | |
141 for (n = 7; n >= 0; n--) { | |
142 pixels[i++] = palette[b >> n & 1]; | |
143 } | |
144 } | |
145 for (n = 7; n >= 8 - rect.width % 8; n--) { | |
146 pixels[i++] = palette[buffer[dy * rowBytes + dx] >> n & 1]; | |
147 } | |
148 i += this.width- rect.width; | |
149 } | |
150 } else { | |
151 // 3..255 colors (assuming bytesPixel == 4). | |
152 int i = 0; | |
153 for (int ly = rect.y; ly < rect.y + rect.height; ++ly) { | |
154 for (int lx = rect.x; lx < rect.x + rect.width; ++lx) { | |
155 int pixelsOffset = ly * this.width + lx; | |
156 pixels[pixelsOffset] = palette[buffer[i++] & 0xFF]; | |
157 } | |
158 } | |
159 } | |
160 | |
161 } | |
162 | |
163 /** | |
164 * Copy rectangle region from one position to another. Regions may be overlapped. | |
165 * | |
166 * @param srcX source rectangle x position | |
167 * @param srcY source rectangle y position | |
168 * @param dstRect destination rectangle | |
169 */ | |
170 public synchronized void copyRect(int srcX, int srcY, FramebufferUpdateRectangle dstRect) { | |
171 int startSrcY, endSrcY, dstY, deltaY; | |
172 if (srcY > dstRect.y) { | |
173 startSrcY = srcY; | |
174 endSrcY = srcY + dstRect.height; | |
175 dstY = dstRect.y; | |
176 deltaY = +1; | |
177 } else { | |
178 startSrcY = srcY + dstRect.height - 1; | |
179 endSrcY = srcY -1; | |
180 dstY = dstRect.y + dstRect.height - 1; | |
181 deltaY = -1; | |
182 } | |
183 for (int y = startSrcY; y != endSrcY; y += deltaY) { | |
184 System.arraycopy(pixels, y * width + srcX, | |
185 pixels, dstY * width + dstRect.x, dstRect.width); | |
186 dstY += deltaY; | |
187 } | |
188 } | |
189 | |
190 /** | |
191 * Fill rectangle region with specified colour | |
192 * | |
193 * @param color colour to fill with | |
194 * @param rect rectangle region posions and dimensions | |
195 */ | |
196 public void fillRect(int color, FramebufferUpdateRectangle rect) { | |
197 fillRect(color, rect.x, rect.y, rect.width, rect.height); | |
198 } | |
199 | |
200 /** | |
201 * Fill rectangle region with specified colour | |
202 * | |
203 * @param color colour to fill with | |
204 * @param x rectangle x position | |
205 * @param y rectangle y position | |
206 * @param width rectangle width | |
207 * @param height rectangle height | |
208 */ | |
209 public synchronized void fillRect(int color, int x, int y, int width, int height) { | |
210 int sy = y * this.width + x; | |
211 int ey = sy + height * this.width; | |
212 for (int i = sy; i < ey; i += this.width) { | |
213 Arrays.fill(pixels, i, i + width, color); | |
214 } | |
215 } | |
216 | |
217 /** | |
218 * Reads color bytes (PIXEL) from reader, returns int combined RGB | |
219 * value consisting of the red component in bits 16-23, the green component | |
220 * in bits 8-15, and the blue component in bits 0-7. May be used directly for | |
221 * creation awt.Color object | |
222 */ | |
223 public int readPixelColor(Reader reader) throws TransportException { | |
224 return colorDecoder.readColor(reader); | |
225 } | |
226 | |
227 public int readTightPixelColor(Reader reader) throws TransportException { | |
228 return colorDecoder.readTightColor(reader); | |
229 } | |
230 | |
231 public ColorDecoder getColorDecoder() { | |
232 return colorDecoder; | |
233 } | |
234 | |
235 public int getCompactPixelColor(byte[] bytes, int offset) { | |
236 return colorDecoder.getCompactColor(bytes, offset); | |
237 } | |
238 | |
239 public int getPixelColor(byte[] bytes, int offset) { | |
240 return colorDecoder.getColor(bytes, offset); | |
241 } | |
242 | |
243 public int getBytesPerPixel() { | |
244 return bytesPerPixel; | |
245 } | |
246 | |
247 public int getBytesPerPixelSignificant() { | |
248 return bytesPerPixelSignificant; | |
249 } | |
250 | |
251 public void fillColorBitmapWithColor(int[] bitmapData, int decodedOffset, int rlength, int color) { | |
252 while (rlength-- > 0) { | |
253 bitmapData[decodedOffset++] = color; | |
254 } | |
255 } | |
256 | |
257 /** | |
258 * Width of rendered image | |
259 * | |
260 * @return width | |
261 */ | |
262 public int getWidth() { | |
263 return width; | |
264 } | |
265 | |
266 /** | |
267 * Height of rendered image | |
268 * | |
269 * @return height | |
270 */ | |
271 public int getHeight() { | |
272 return height; | |
273 } | |
274 | |
275 /** | |
276 * Read and decode cursor image | |
277 * | |
278 * @param rect new cursor hot point position and cursor dimensions | |
279 * @throws TransportException | |
280 */ | |
281 public void createCursor(int[] cursorPixels, FramebufferUpdateRectangle rect) | |
282 throws TransportException { | |
283 synchronized (cursor) { | |
284 cursor.createCursor(cursorPixels, rect.x, rect.y, rect.width, rect.height); | |
285 } | |
286 } | |
287 | |
288 /** | |
289 * Read and decode new cursor position | |
290 * | |
291 * @param rect cursor position | |
292 */ | |
293 public void decodeCursorPosition(FramebufferUpdateRectangle rect) { | |
294 synchronized (cursor) { | |
295 cursor.updatePosition(rect.x, rect.y); | |
296 } | |
297 } | |
298 | |
299 } |