"Fossies" - the Fresh Open Source Software Archive

Member "google-gadgets-for-linux-0.11.2/ggadget/qt/qt_image.cc" (23 May 2009, 5690 Bytes) of package /linux/misc/old/google-gadgets-for-linux-0.11.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*
    2   Copyright 2008 Google Inc.
    3 
    4   Licensed under the Apache License, Version 2.0 (the "License");
    5   you may not use this file except in compliance with the License.
    6   You may obtain a copy of the License at
    7 
    8        http://www.apache.org/licenses/LICENSE-2.0
    9 
   10   Unless required by applicable law or agreed to in writing, software
   11   distributed under the License is distributed on an "AS IS" BASIS,
   12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   13   See the License for the specific language governing permissions and
   14   limitations under the License.
   15 */
   16 
   17 #include <algorithm>
   18 #include <cmath>
   19 #include <string>
   20 #include <QtGui/QPixmap>
   21 #include <ggadget/logger.h>
   22 #include <ggadget/color.h>
   23 #include "qt_graphics.h"
   24 #include "qt_canvas.h"
   25 #include "qt_image.h"
   26 
   27 namespace ggadget {
   28 namespace qt {
   29 static void QImageMultiplyColor(QImage* dest,
   30                                 const QImage *src,
   31                                 const Color &c) {
   32   // Note: assume that the source image is pre-multiplied.
   33   // Color(0.5, 0.5, 0.5) is the middle color, so multiplying a color greater
   34   // than 0.5 makes the image brighter.
   35   int width = src->width();
   36   int height = src->height();
   37   int rm = c.RedInt() * 2;
   38   int gm = c.GreenInt() * 2;
   39   int bm = c.BlueInt() * 2;
   40   for (int y = 0; y < height; y++) {
   41     for (int x = 0; x < width; x++) {
   42       QRgb rgb = src->pixel(x, y);
   43       int a = qAlpha(rgb);
   44       if (a == 0) {
   45         dest->setPixel(x, y, qRgba(0, 0, 0, 0));
   46       } else {
   47         int r = std::min((qRed(rgb) * rm) >> 8, a);
   48         int g = std::min((qGreen(rgb) * gm) >> 8, a);
   49         int b = std::min((qBlue(rgb) * bm) >> 8, a);
   50         dest->setPixel(x, y, qRgba(r, g, b, a));
   51       }
   52     }
   53   }
   54 }
   55 
   56 class QtImage::Impl {
   57  public:
   58   Impl(QtGraphics *g, const std::string &tag,
   59        const std::string &data, bool is_mask)
   60     : is_mask_(is_mask),
   61       canvas_(NULL),
   62       tag_(tag),
   63       graphics_(g),
   64       fully_opaque_(false) {
   65     canvas_ = new QtCanvas(data, false);
   66     if (!canvas_) return;
   67     if (canvas_->GetWidth() == 0) {
   68       delete canvas_;
   69       canvas_ = NULL;
   70       return;
   71     }
   72     QImage *img = canvas_->GetImage();
   73     if (is_mask) {
   74       // Setup alpha channel and black color will be set to fully transparent
   75       QImage mask = img->createMaskFromColor(qRgb(0, 0, 0), Qt::MaskOutColor);
   76       img->setAlphaChannel(mask);
   77     } else if (!canvas_->GetImage()->hasAlphaChannel()) {
   78       fully_opaque_ = true;
   79     } else {
   80       for (int y = 0; y < img->height() && fully_opaque_; y++) {
   81         for (int x = 0; x < img->width(); x++) {
   82           QRgb rgb = img->pixel(x, y);
   83           if (qAlpha(rgb) != 255) {
   84             fully_opaque_ = false;
   85             break;
   86           }
   87         }
   88       }
   89     }
   90   }
   91 
   92   Impl(double width, double height)
   93     : is_mask_(false),
   94       canvas_(NULL),
   95       graphics_(NULL) {
   96     canvas_ = new QtCanvas(NULL, width, height, false);
   97     if (!canvas_) return;
   98     if (canvas_->GetWidth() == 0) {
   99       delete canvas_;
  100       canvas_ = NULL;
  101     }
  102   }
  103 
  104   ~Impl() {
  105     if (canvas_) delete canvas_;
  106   }
  107 
  108   void Draw(CanvasInterface *canvas, double x, double y) {
  109     ASSERT(canvas && canvas_);
  110     canvas->DrawCanvas(x, y, canvas_);
  111   }
  112 
  113   void StretchDraw(CanvasInterface *canvas,
  114                    double x, double y,
  115                    double width, double height) {
  116     ASSERT(canvas && canvas_);
  117     double cx = width / canvas_->GetWidth();
  118     double cy = height / canvas_->GetHeight();
  119     if (cx != 1.0 || cy != 1.0) {
  120       canvas->PushState();
  121       canvas->ScaleCoordinates(cx, cy);
  122       canvas->DrawCanvas(x / cx, y / cy, canvas_);
  123       canvas->PopState();
  124     } else {
  125       Draw(canvas, x, y);
  126     }
  127   }
  128 
  129   bool is_mask_;
  130   QtCanvas *canvas_;
  131   std::string tag_;
  132   QtGraphics *graphics_;
  133   bool fully_opaque_;
  134 };
  135 
  136 QtImage::QtImage(QtGraphics *graphics,
  137                  const std::string &tag,
  138                  const std::string &data,
  139                  bool is_mask)
  140   : impl_(new Impl(graphics, tag, data, is_mask)) {
  141 }
  142 
  143 QtImage::QtImage(double width, double height)
  144   : impl_(new Impl(width, height)) {
  145 }
  146 
  147 QtImage::~QtImage() {
  148   delete impl_;
  149   impl_ = NULL;
  150 }
  151 
  152 bool QtImage::IsValid() const {
  153   return impl_->canvas_ != NULL;
  154 }
  155 
  156 void QtImage::Destroy() {
  157   delete this;
  158 }
  159 
  160 const CanvasInterface *QtImage::GetCanvas() const {
  161   return impl_->canvas_;
  162 }
  163 
  164 void QtImage::Draw(CanvasInterface *canvas, double x, double y) const {
  165   impl_->Draw(canvas, x, y);
  166 }
  167 
  168 void QtImage::StretchDraw(CanvasInterface *canvas,
  169                               double x, double y,
  170                               double width, double height) const {
  171   impl_->StretchDraw(canvas, x, y, width, height);
  172 }
  173 
  174 double QtImage::GetWidth() const {
  175   return impl_->canvas_->GetWidth();
  176 }
  177 
  178 double QtImage::GetHeight() const {
  179   return impl_->canvas_->GetHeight();
  180 }
  181 
  182 ImageInterface* QtImage::MultiplyColor(const Color &color) const {
  183   QtImage *new_image = new QtImage(D2I(GetWidth()), D2I(GetHeight()));
  184   if (!new_image) return NULL;
  185   if (!new_image->IsValid()) {
  186     delete new_image;
  187     return NULL;
  188   }
  189   new_image->impl_->fully_opaque_ = impl_->fully_opaque_;
  190   QImageMultiplyColor(new_image->impl_->canvas_->GetImage(),
  191                       impl_->canvas_->GetImage(),
  192                       color);
  193   return new_image;
  194 }
  195 
  196 bool QtImage::GetPointValue(double x, double y,
  197                                 Color *color, double *opacity) const {
  198   return impl_->canvas_ && impl_->canvas_->GetPointValue(x, y, color, opacity);
  199 }
  200 
  201 std::string QtImage::GetTag() const {
  202   return impl_->tag_;
  203 }
  204 
  205 bool QtImage::IsFullyOpaque() const {
  206   return impl_->fully_opaque_;
  207 }
  208 
  209 } // namespace qt
  210 } // namespace ggadget