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 }