nux-1.14.0
|
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 }