00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00033
00034 #ifndef GROOVX_GFX_GXSCALER_CC_UTC20050626084023_DEFINED
00035 #define GROOVX_GFX_GXSCALER_CC_UTC20050626084023_DEFINED
00036
00037 #include "gxscaler.h"
00038
00039 #include "geom/box.h"
00040 #include "geom/rect.h"
00041 #include "geom/vec3.h"
00042
00043 #include "gfx/bbox.h"
00044 #include "gfx/canvas.h"
00045 #include "gfx/glcanvas.h"
00046
00047 #include "io/reader.h"
00048 #include "io/writer.h"
00049
00050 #include "rutz/algo.h"
00051 #include "rutz/error.h"
00052
00053 #include "rutz/trace.h"
00054
00055 using geom::rectd;
00056
00057 GxScaler::GxScaler() :
00058 GxBin(),
00059 itsMode(NATIVE_SCALING),
00060 itsWidthFactor(1.0),
00061 itsHeightFactor(1.0),
00062 itsAspectRatio(1.0)
00063 {}
00064
00065 GxScaler::GxScaler(nub::ref<GxNode> child) :
00066 GxBin(child),
00067 itsMode(NATIVE_SCALING),
00068 itsWidthFactor(1.0),
00069 itsHeightFactor(1.0),
00070 itsAspectRatio(1.0)
00071 {}
00072
00073 GxScaler* GxScaler::make()
00074 {
00075 return new GxScaler;
00076 }
00077
00078 void GxScaler::setMode(Mode new_mode)
00079 {
00080 GVX_TRACE("GxScaler::setMode");
00081
00082 itsMode = new_mode;
00083 this->sigNodeChanged.emit();
00084 }
00085
00086 void GxScaler::setWidth(double new_width)
00087 {
00088 GVX_TRACE("GxScaler::setWidth");
00089 if (itsMode == NATIVE_SCALING) return;
00090
00091 const rectd native_bbox =
00092 child()->getBoundingBox(*(GLCanvas::getCurrent()));
00093
00094 const double current_width = native_bbox.width() * itsWidthFactor;
00095
00096 if (new_width == 0.0 || new_width == current_width) return;
00097
00098 const double new_width_factor = new_width / native_bbox.width();
00099
00100 const double change_factor = new_width_factor / itsWidthFactor;
00101
00102 itsWidthFactor = new_width_factor;
00103
00104 if (itsMode == MAINTAIN_ASPECT_SCALING)
00105 {
00106 itsHeightFactor *= change_factor;
00107 }
00108
00109 this->sigNodeChanged.emit();
00110 }
00111
00112 void GxScaler::setHeight(double new_height)
00113 {
00114 GVX_TRACE("GxScaler::setHeight");
00115 if (itsMode == NATIVE_SCALING) return;
00116
00117 const rectd native_bbox =
00118 child()->getBoundingBox(*(GLCanvas::getCurrent()));
00119
00120 const double current_height = native_bbox.height() * itsHeightFactor;
00121
00122 if (new_height == 0.0 || new_height == current_height) return;
00123
00124 const double new_height_factor = new_height / native_bbox.height();
00125
00126 const double change_factor = new_height_factor / itsHeightFactor;
00127
00128 itsHeightFactor = new_height_factor;
00129
00130 if (itsMode == MAINTAIN_ASPECT_SCALING)
00131 {
00132 itsWidthFactor *= change_factor;
00133 }
00134
00135 this->sigNodeChanged.emit();
00136 }
00137
00138 void GxScaler::setAspectRatio(double new_aspect_ratio)
00139 {
00140 GVX_TRACE("GxScaler::setAspectRatio");
00141 if (itsMode != FREE_SCALING) return;
00142
00143 itsAspectRatio = new_aspect_ratio;
00144
00145 this->sigNodeChanged.emit();
00146 }
00147
00148 void GxScaler::setWidthFactor(double f)
00149 {
00150 GVX_TRACE("GxScaler::setWidthFactor");
00151 itsWidthFactor = f;
00152 this->sigNodeChanged.emit();
00153 }
00154
00155 void GxScaler::setHeightFactor(double f)
00156 {
00157 GVX_TRACE("GxScaler::setHeightFactor");
00158 itsHeightFactor = f;
00159 this->sigNodeChanged.emit();
00160 }
00161
00162 void GxScaler::setMaxDim(double new_max_dimension)
00163 {
00164 GVX_TRACE("GxScaler::setMaxDim");
00165 if (itsMode == NATIVE_SCALING) return;
00166
00167 double scaling_factor = new_max_dimension / scaledMaxDim();
00168
00169 itsWidthFactor *= scaling_factor;
00170 itsHeightFactor *= scaling_factor;
00171
00172 this->sigNodeChanged.emit();
00173 }
00174
00175 double GxScaler::aspectRatio() const
00176 {
00177 GVX_TRACE("GxScaler::aspectRatio");
00178 return itsMode != FREE_SCALING ? 1.0 : itsAspectRatio;
00179 }
00180
00181 double GxScaler::scaledWidth() const
00182 {
00183 GVX_TRACE("GxScaler::scaledWidth");
00184 const rectd native_bbox =
00185 child()->getBoundingBox(*(GLCanvas::getCurrent()));
00186 return native_bbox.width() * itsWidthFactor * aspectRatio();
00187 }
00188
00189 double GxScaler::scaledHeight() const
00190 {
00191 GVX_TRACE("GxScaler::scaledHeight");
00192 const rectd native_bbox =
00193 child()->getBoundingBox(*(GLCanvas::getCurrent()));
00194 return native_bbox.height() * itsHeightFactor;
00195 }
00196
00197 double GxScaler::scaledMaxDim() const
00198 {
00199 GVX_TRACE("GxScaler::scaledMaxDim");
00200 return rutz::max(scaledWidth(), scaledHeight());
00201 }
00202
00203 void GxScaler::read_from(io::reader& reader)
00204 {
00205 GVX_TRACE("GxScaler::read_from");
00206 reader.read_value("mode", itsMode);
00207 reader.read_value("widthFactor", itsWidthFactor);
00208 reader.read_value("heightFactor", itsHeightFactor);
00209 reader.read_value("aspectRatio", itsAspectRatio);
00210 }
00211
00212 void GxScaler::write_to(io::writer& writer) const
00213 {
00214 GVX_TRACE("GxScaler::write_to");
00215 writer.write_value("mode", itsMode);
00216 writer.write_value("widthFactor", itsWidthFactor);
00217 writer.write_value("heightFactor", itsHeightFactor);
00218 writer.write_value("aspectRatio", itsAspectRatio);
00219 }
00220
00221 void GxScaler::draw(Gfx::Canvas& canvas) const
00222 {
00223 GVX_TRACE("GxScaler::draw");
00224 if (NATIVE_SCALING == itsMode)
00225 {
00226 child()->draw(canvas);
00227 }
00228 else
00229 {
00230 Gfx::MatrixSaver state(canvas);
00231 canvas.scale(geom::vec3<double>(itsWidthFactor * aspectRatio(),
00232 itsHeightFactor,
00233 1.0));
00234 child()->draw(canvas);
00235 }
00236 }
00237
00238 void GxScaler::getBoundingCube(Gfx::Bbox& bbox) const
00239 {
00240 GVX_TRACE("GxScaler::getBoundingCube");
00241 bbox.push();
00242
00243 if (NATIVE_SCALING != itsMode)
00244 bbox.scale(geom::vec3<double>(itsWidthFactor * aspectRatio(),
00245 itsHeightFactor,
00246 1.0));
00247
00248 child()->getBoundingCube(bbox);
00249
00250 bbox.pop();
00251
00252 dbg_dump(2, bbox.cube());
00253 }
00254
00255 static const char __attribute__((used)) vcid_groovx_gfx_gxscaler_cc_utc20050626084023[] = "$Id: gxscaler.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00256 #endif // !GROOVX_GFX_GXSCALER_CC_UTC20050626084023_DEFINED