nux-1.16.0
CairoWrapper.cpp
00001 /*
00002  * Copyright (C) 2011 Canonical Ltd
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License version 3 as
00006  * published by the Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful,
00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  * GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00015  *
00016  * Authored by: Mirco Müller <mirco.mueller@canonical.com
00017  */
00018 
00019 
00020 #include "CairoWrapper.h"
00021 
00022 #include <iostream>
00023 
00024 namespace nux
00025 {
00026   CairoWrapper::CairoWrapper (Geometry const& geom, DrawCanvasCallback callback)
00027   {
00028     draw_canvas_callback_ = callback;
00029         geometry_.x           = geom.x;
00030         geometry_.y           = geom.y;
00031         geometry_.width       = geom.width;
00032         geometry_.height      = geom.height;
00033     cr_                   = NULL;
00034     surface_              = NULL;
00035     bitmap_               = NULL;
00036     texture_              = NULL;
00037         Recreate ();
00038   }
00039 
00040   CairoWrapper::~CairoWrapper ()
00041   {
00042     if (surface_)
00043       cairo_surface_destroy (surface_);
00044 
00045     if (cr_)
00046       cairo_destroy (cr_);
00047 
00048         if (bitmap_)
00049       delete bitmap_;
00050 
00051     if (texture_)
00052       texture_->UnReference ();
00053   }
00054 
00055   bool CairoWrapper::Recreate ()
00056   {
00057     if (surface_)
00058       cairo_surface_destroy (surface_);
00059 
00060     if (cr_)
00061       cairo_destroy (cr_);
00062 
00063     surface_ = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
00064                                            geometry_.width,
00065                                            geometry_.height);
00066 
00067     if (cairo_surface_status (surface_) != CAIRO_STATUS_SUCCESS)
00068         {
00069       g_debug ("Could not create image-surface!");
00070       return false;
00071     }
00072 
00073     cr_ = cairo_create (surface_);
00074     if (cairo_status (cr_) != CAIRO_STATUS_SUCCESS)
00075     {
00076       cairo_surface_destroy (surface_);
00077       g_debug ("Could not create cairo-context!");
00078       return false;
00079     }
00080 
00081     if (!draw_canvas_callback_)
00082       return false;
00083 
00084     draw_canvas_callback_ (geometry_, cr_);
00085 
00086     CreateBitmap ();
00087     NBitmapData* bitmap = GetBitmap ();
00088     if (texture_)
00089         texture_->UnReference ();
00090 
00091         if (GetGraphicsDisplay()->GetGraphicsEngine() == NULL)
00092           return false;
00093 
00094     texture_ = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture();
00095     texture_->Update (bitmap);
00096 
00097         return true;
00098   }
00099 
00100   bool CairoWrapper::CreateBitmap ()
00101   {
00102     if (geometry_.width < 1 || geometry_.height < 1)
00103     {
00104       g_debug ("Width or height invalid!");
00105       return false;
00106     }
00107 
00108     if (bitmap_)
00109     {
00110       delete bitmap_;
00111           bitmap_ = NULL;
00112     }
00113 
00114     BitmapFormat bitmap_format = BITFMT_B8G8R8A8;
00115     bitmap_ = new NTextureData (bitmap_format,
00116                                 geometry_.width,
00117                                 geometry_.height,
00118                                 1);
00119     t_u8* ptr = cairo_image_surface_get_data (surface_);
00120     int stride = cairo_image_surface_get_stride (surface_);
00121 
00122     if (ptr == NULL || stride == 0)
00123     {
00124       g_debug ("Invalid surface!");
00125       return false;
00126     }
00127 
00128     for (int j = 0; j < geometry_.height; j++)
00129     {
00130       Memcpy (bitmap_->GetSurface (0).GetPtrRawData() + j * bitmap_->GetSurface (0).GetPitch(),
00131                 (const void *) (&ptr[j * stride]),
00132                 geometry_.width * GPixelFormats[bitmap_format].NumComponents);
00133     }
00134 
00135     return true;
00136   }
00137 
00138   NBitmapData* CairoWrapper::GetBitmap () const
00139   {
00140     return bitmap_;
00141   }
00142 
00143   void CairoWrapper::SetDrawCanvasCallback (DrawCanvasCallback callback)
00144   {
00145     if (!callback)
00146       return;
00147 
00148     draw_canvas_callback_ = callback;
00149 
00150     Recreate (); 
00151   }
00152 
00153   bool CairoWrapper::DumpToFile (std::string const& filename)
00154   {
00155     cairo_surface_write_to_png (surface_, filename.c_str ());
00156 
00157     return true;
00158   }
00159 
00160   BaseTexture* CairoWrapper::GetTexture () const
00161   {
00162     return texture_;
00163   }
00164 
00165   cairo_surface_t* CairoWrapper::GetCairoSurface () const
00166   {
00167     return surface_;
00168   }
00169 
00170   cairo_t* CairoWrapper::GetCairoContext () const
00171   {
00172     return cr_;
00173   }
00174 
00175   bool CairoWrapper::Invalidate (Geometry const& geom)
00176   {
00177     if (geometry_.width  == geom.width &&
00178             geometry_.height == geom.height)
00179       return false;
00180 
00181         geometry_.x      = geom.x;
00182         geometry_.y      = geom.y;
00183         geometry_.width  = geom.width;
00184         geometry_.height = geom.height;
00185 
00186     Recreate (); 
00187 
00188     return true;
00189   }
00190 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends