blob: df3a6c934ffa2ae6f0d8e8551a2a11b58d553c92 [file] [log] [blame]
Constantin Kaplinsky729598c2006-05-25 05:12:25 +00001/* Copyright (C) 2006 TightVNC Team. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 *
18 * TightVNC distribution homepage on the Web: http://www.tightvnc.com/
19 *
20 */
21
22// -=- ScaledDIBSectionBuffer.cxx
23
24#include <math.h>
25
26#include <rfb_win32/ScaledDIBSectionBuffer.h>
27
28using namespace rfb;
29using namespace win32;
30
31ScaledDIBSectionBuffer::ScaledDIBSectionBuffer(HWND window)
32 : src_buffer(0), scaling(false), DIBSectionBuffer(window) {
33 scaled_data = data;
34}
35
36ScaledDIBSectionBuffer::~ScaledDIBSectionBuffer() {
37 if (src_buffer) delete src_buffer;
38}
39
george82bf0adb32006-07-29 10:29:41 +000040void ScaledDIBSectionBuffer::setScaleRatio(double scale_ratio_) {
41 if (scale_ratio == scale_ratio_) return;
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000042
george822ac935e2006-05-29 13:57:39 +000043 if (format.depth != 24) throw rfb::UnsupportedPixelFormatException();
44
george82bf0adb32006-07-29 10:29:41 +000045 if (scale_ratio_ != 1) {
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000046 scaling = true;
Constantin Kaplinsky1ae2eb02006-05-26 05:24:24 +000047 if (!src_buffer) {
48 src_buffer = new ManagedPixelBuffer(format, src_width, src_height);
49 src_data = &(src_buffer->data);
george82e89d47f2006-05-27 12:31:08 +000050 memcpy(src_buffer->data, data, area() * (getPF().bpp/8));
Constantin Kaplinsky1ae2eb02006-05-26 05:24:24 +000051 }
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000052 } else {
53 scaling = false;
54 }
george82bf0adb32006-07-29 10:29:41 +000055 ScaledPixelBuffer::setScaleRatio(scale_ratio_);
Constantin Kaplinsky1ae2eb02006-05-26 05:24:24 +000056 recreateScaledBuffer();
george82e89d47f2006-05-27 12:31:08 +000057 if (scaling) {
58 scaleRect(Rect(0, 0, src_width, src_height));
59 } else {
60 memcpy(data, src_buffer->data, src_buffer->area() * (src_buffer->getPF().bpp/8));
61 if (src_buffer) {
62 delete src_buffer;
63 src_buffer = 0;
64 src_data = 0;
65 }
66 }
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000067}
68
Constantin Kaplinsky1ae2eb02006-05-26 05:24:24 +000069void ScaledDIBSectionBuffer::setPF(const PixelFormat &pf_) {
george82e3341e72006-08-02 15:23:39 +000070 if (memcmp(&getPF(), &pf_, sizeof(pf_)) == 0) return;
71
Constantin Kaplinsky1ae2eb02006-05-26 05:24:24 +000072 if (scaling) {
73 ScaledPixelBuffer::setPF(pf_);
74 src_buffer->setPF(pf_);
75 }
76 DIBSectionBuffer::setPF(pf_);
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000077 scaled_data = data;
78}
79
80void ScaledDIBSectionBuffer::setSize(int src_width_, int src_height_) {
george82e3341e72006-08-02 15:23:39 +000081 if (src_width == src_width_ && src_height == src_height_) return;
82
Constantin Kaplinsky729598c2006-05-25 05:12:25 +000083 src_width = src_width_;
84 src_height = src_height_;
85 if (scaling) {
86 src_buffer->setSize(src_width, src_height);
87 }
88 calculateScaledBufferSize();
89 recreateScaledBuffer();
90 scaled_data = data;
91}
92
93void ScaledDIBSectionBuffer::recreateScaledBuffer() {
94 width_ = scaled_width;
95 height_ = scaled_height;
george82e3341e72006-08-02 15:23:39 +000096 if (width_ && height_ && (format.depth != 0)) {
97 DIBSectionBuffer::recreateBuffer();
98 scaled_data = data;
99 }
Constantin Kaplinsky729598c2006-05-25 05:12:25 +0000100}
101
102void ScaledDIBSectionBuffer::fillRect(const Rect &dest, Pixel pix) {
103 if (scaling) {
104 src_buffer->fillRect(dest, pix);
105 scaleRect(dest);
106 } else {
107 DIBSectionBuffer::fillRect(dest, pix);
108 }
109}
110
111void ScaledDIBSectionBuffer::imageRect(const Rect &dest, const void* pixels, int stride) {
112 if (scaling) {
113 src_buffer->imageRect(dest, pixels, stride);
114 scaleRect(dest);
115 } else {
116 DIBSectionBuffer::imageRect(dest, pixels, stride);
117 }
118}
119
120void ScaledDIBSectionBuffer::copyRect(const Rect &dest, const Point &move_by_delta) {
121 if (scaling) {
122 src_buffer->copyRect(dest, move_by_delta);
123 scaleRect(dest);
124 } else {
125 DIBSectionBuffer::copyRect(dest, move_by_delta);
126 }
127}
128
129void ScaledDIBSectionBuffer::maskRect(const Rect& r, const void* pixels, const void* mask_) {
130 if (scaling) {
131 src_buffer->maskRect(r, pixels, mask_);
132 scaleRect(r);
133 } else {
134 DIBSectionBuffer::maskRect(r, pixels, mask_);
135 }
136}
137
138void ScaledDIBSectionBuffer::maskRect(const Rect& r, Pixel pixel, const void* mask_) {
139 if (scaling) {
140 src_buffer->maskRect(r, pixel, mask_);
141 scaleRect(r);
142 } else {
143 DIBSectionBuffer::maskRect(r, pixel, mask_);
144 }
145}