Mercurial > hg > aimc
diff src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceCairo.cc @ 227:73c6d61440ad
- First add of a lot of graphics code from the old version. Not working yet, not even compiling yet.
author | tomwalters |
---|---|
date | Fri, 15 Oct 2010 05:40:53 +0000 |
parents | 89215dab69c5 |
children | 82e0dc3dfd16 |
line wrap: on
line diff
--- a/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceCairo.cc Wed Sep 29 00:24:03 2010 +0000 +++ b/src/Modules/Output/Graphics/Devices/GraphicsOutputDeviceCairo.cc Fri Oct 15 05:40:53 2010 +0000 @@ -1,4 +1,4 @@ -// Copyright 2007-2010, Thomas Walters, Willem van Engen +// Copyright 2007, Thomas Walters // // AIM-C: A C++ implementation of the Auditory Image Model // http://www.acousticscale.org/AIMC @@ -31,98 +31,56 @@ #include <string.h> #include <stdio.h> #include <math.h> -#include <limits.h> -#ifdef _WINDOWS -# include <direct.h> // for _mkdir&_rmdir -#endif - -//#include "cairo-quartz.h" - -#include "Modules/Output/Graphics/Devices/GraphicsOutputDeviceCairo.h" - -namespace aimc { +#include "Support/util.h" +#include "Output/GraphicsOutputDeviceCairo.h" GraphicsOutputDeviceCairo::GraphicsOutputDeviceCairo(Parameters *pParam) - : GraphicsOutputDevice(pParam) { - m_bOutputFile = false; - m_iFileNumber = 0; - m_iVertexType = VertexTypeNone; - m_bUseMemoryBuffer=false; - parameters_->DefaultString("output.img.format", "png"); + : GraphicsOutputDevice(pParam) { + m_bOutputFile = false; + m_iFileNumber = 0; + m_iVertexType = VertexTypeNone; + m_bUseMemoryBuffer=false; } -void GraphicsOutputDeviceCairo::Reset(Parameters* global_parameters) { - Initialize(global_parameters); +bool GraphicsOutputDeviceCairo::Initialize(const char *sDir) { + Init(); + + //! \todo Output to file if sDir is a file, to directory with + //! multiple images if it's a directory. + strncpy(m_sDir, sDir, sizeof(m_sDir)/sizeof(m_sDir[0])); + + /* Try to open an image to see if everything is allright. We want to avoid + * errors in the main Process()ing loop. */ + if ( !OpenFile(0) ) { + //! \todo Better error message that is more specific about the cause. + AIM_ERROR(_T("Could not open output directory '%s' using graphics format '%s'."), + m_sDir, m_pParam->GetString("output.img.format") ); + return false; + } + CloseFile(); + + return true; } -bool GraphicsOutputDeviceCairo::Initialize(Parameters *global_parameters) { - global_parameters_ = global_parameters; -#ifdef _WINDOWS - string pathsep("\\"); -#else - string pathsep("/"); -#endif - directory_ = global_parameters->GetString("output_filename_base") + pathsep; - //! \todo Make build system check for mkdtemp() to use it when available. See TODO.txt. -#ifdef _WINDOWS - _mkdir(directory_.c_str()); -#else - mkdir(directory_.c_str(), S_IRWXU); -#endif - InitialzeInternal(); - return true; -} - -bool GraphicsOutputDeviceCairo::Initialize(string directory) { - directory_ = directory; - InitialzeInternal(); - - /* Try to open an image to see if everything is allright. We want to avoid - * errors in the main Process()ing loop. */ - /*if (!OpenFile(0)) { - //! \todo Better error message that is more specific about the cause. - LOG_ERROR(_T("Could not open output directory '%s' using graphics format '%s'."), - directory_.c_str(), parameters_->DefaultString("output.img.format", "png")); - return false; - } - CloseFile();*/ - - return true; -} - -/*bool GraphicsOutputDeviceCairo::Initialize() { +bool GraphicsOutputDeviceCairo::Initialize() { Init(); m_bUseMemoryBuffer = true; return(true); -}*/ +} -void GraphicsOutputDeviceCairo::InitialzeInternal() { - AIM_ASSERT(parameters_); +void GraphicsOutputDeviceCairo::Init() { + AIM_ASSERT(m_pParam); + /* + * Set parameters + */ + m_pParam->GetString("output.img.color.background"); - parameters_->DefaultString("output.img.color.background", "black"); + m_bInvertColors = m_pParam->GetBool("output.img.color.invert"); - m_bInvertColors = parameters_->DefaultBool("output.img.color.invert", "false"); - - // Output size. - m_iWidth = parameters_->DefaultInt("output.img.width", 800); - m_iHeight = parameters_->DefaultInt("output.img.height", 600); - - // Cairo's RGB24 format has 32-bit pixels with the upper 8 bits unused. - // This is not the same as the plotutils PNG format. This information is transferred by the - // function GetPixelFormat. The pixel format is dealt with by the reciever. - m_cSurface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, - m_iWidth, - m_iHeight); - m_cCr = cairo_create(m_cSurface); - cairo_scale(m_cCr, (float)m_iWidth, (float)m_iHeight); - // Now setup things for this plotter. - cairo_select_font_face(m_cCr, - parameters_->DefaultString("output.img.fontname", - "HersheySans"), - CAIRO_FONT_SLANT_NORMAL, - CAIRO_FONT_WEIGHT_BOLD); - cairo_set_font_size (m_cCr, 0.02); + // Output size! + m_iWidth = m_pParam->GetUInt("output.img.width"); + m_iHeight = m_pParam->GetUInt("output.img.height"); } unsigned char* GraphicsOutputDeviceCairo::GetBuffer() { @@ -133,27 +91,25 @@ } bool GraphicsOutputDeviceCairo::OpenFile(unsigned int index) { - const char *strPlottype = parameters_->GetString("output.img.format"); + const char *strPlottype = m_pParam->GetString("output.img.format"); if (!m_bUseMemoryBuffer) { struct stat fileinfo; // Get filename without trailing slash - char filename[PATH_MAX]; - strncpy(filename, directory_.c_str(), sizeof(filename)/sizeof(filename[0])); + strncpy(m_sFilename, m_sDir, sizeof(m_sFilename)/sizeof(m_sFilename[0])); #ifdef _WINDOWS - if (filename[strlen(filename)-1]=='\\') { - filename[strlen(filename)-1]='\0'; + if (m_sFilename[strlen(m_sFilename)-1]=='\\') { + m_sFilename[strlen(m_sFilename)-1]='\0'; } #else - if (filename[strlen(filename)-1]=='/') { - filename[strlen(filename)-1]='\0'; + if (m_sFilename[strlen(m_sFilename)-1]=='/') { + m_sFilename[strlen(m_sFilename)-1]='\0'; } #endif // Enumerate files it m_sDir is a directory. - if (stat(filename, &fileinfo) == 0 && (fileinfo.st_mode & S_IFDIR)) { + if (stat(m_sFilename, &fileinfo) == 0 && (fileinfo.st_mode & S_IFDIR)) { // We have a directory: enumerate with index - snprintf(filename, sizeof(filename) / sizeof(filename[0]), - "%s%06d.%s", - directory_.c_str(), + snprintf(m_sFilename, sizeof(m_sFilename)/sizeof(m_sFilename[0]),"%s%06d.%s", + m_sDir, index, strPlottype); // If type is 'auto', fallback to 'png' @@ -161,49 +117,61 @@ strPlottype = "png"; } else { // We have a (probably non-existant) file. Auto-detect type by extension if requested - strncpy(filename, - directory_.c_str(), - sizeof(filename)/sizeof(filename[0])); - char *pDot = strrchr(filename, '.'); + strncpy(m_sFilename, m_sDir, sizeof(m_sFilename)/sizeof(m_sFilename[0])); + char *pDot = strrchr(m_sFilename, '.'); if (!pDot) { - LOG_ERROR(_T("Please supply extension on filename when using 'auto' format: '%s'"), - filename); + AIM_ERROR(_T("Please supply extension on filename when using 'auto' format: '%s'"), + m_sFilename); return false; } strPlottype = &pDot[1]; } - image_filename_ = filename; m_bOutputFile= true; //! \todo Should check that it's possible to write to the file } - - return true; + // Cairo's RGB24 format has 32-bit pixels with the upper 8 bits unused. + // This is not the same as the plotutils PNG format. This information is transferred by the + // function GetPixelFormat. The pixel format is dealt with by the reciever. + m_cSurface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, + m_iWidth, + m_iHeight); + m_cCr = cairo_create (m_cSurface); + cairo_scale(m_cCr, (float)m_iWidth, (float)m_iHeight); + // Now setup things for this plotter. + cairo_select_font_face(m_cCr, + m_pParam->GetString("output.img.fontname"), + CAIRO_FONT_SLANT_NORMAL, + CAIRO_FONT_WEIGHT_BOLD); + cairo_set_font_size (m_cCr, 0.015); + return true; } void GraphicsOutputDeviceCairo::CloseFile() { - // And the output file - if (m_bOutputFile) { - cairo_surface_write_to_png(m_cSurface, image_filename_.c_str()); - m_bOutputFile = false; - } - cairo_set_source_rgb (m_cCr, 0.0, 0.0, 0.0); - cairo_paint (m_cCr); - //cairo_destroy(m_cCr); - //cairo_surface_destroy(m_cSurface); + // Plotting library + if (m_iPlotHandle>0) { + cairo_destroy(m_cCr); + m_iPlotHandle = 0; + } + // And the output file + if (m_bOutputFile) { + cairo_surface_write_to_png(m_cSurface, m_sFilename); + m_bOutputFile = false; + } + cairo_surface_destroy(m_cSurface); } GraphicsOutputDeviceCairo::~GraphicsOutputDeviceCairo() { - AIM_ASSERT(!m_iPlotHandle); - CloseFile(); + AIM_ASSERT(!m_iPlotHandle); + CloseFile(); } void GraphicsOutputDeviceCairo::gGrab() { // Open file. - if (!OpenFile(m_iFileNumber)) { - return; + if (!OpenFile(m_iFileNumber)) { + return; } - // Setup plotting area. - cairo_set_line_width (m_cCr, 0.001f); - gColor3f (0.0f, 0.0f, 0.0f); + // Setup plotting area. + cairo_set_line_width (m_cCr, 0.001f); + gColor3f (0.0f, 0.0f, 0.0f); cairo_paint (m_cCr); gColor3f(1.0f, 1.0f, 0.0f); } @@ -213,85 +181,80 @@ } void GraphicsOutputDeviceCairo::gBeginLineStrip() { - m_bIsFirstVertex = true; - m_iVertexType = VertexTypeLine; - //! \todo Make line width user-settable - cairo_set_line_width (m_cCr, 0.001f); + m_bIsFirstVertex = true; + m_iVertexType = VertexTypeLine; + //! \todo Make line width user-settable + cairo_set_line_width (m_cCr, 0.001f); } void GraphicsOutputDeviceCairo::gBeginQuadStrip() { - m_bIsFirstVertex = true; - m_iVertexType = VertexTypeQuad; - m_iPrevVertexCount = 0; + m_bIsFirstVertex = true; + m_iVertexType = VertexTypeQuad; + m_iPrevVertexCount = 0; cairo_set_line_width (m_cCr, 0.001f); } void GraphicsOutputDeviceCairo::gColor3f(float r, float g, float b) { if (m_bInvertColors) { - r = 1.0 - r; - g = 1.0 - g; - b = 1.0 - b; - } + r = 1-r; + g = 1-g; + b = 1-b; + } cairo_set_source_rgb (m_cCr, r, g, b); } void GraphicsOutputDeviceCairo::gVertex3f(float x, float y, float z) { - switch(m_iVertexType) { - case VertexTypeLine: - if (m_bIsFirstVertex) { - m_bIsFirstVertex = false; - //pl_fmove(x, y); - cairo_move_to(m_cCr, x, 1.0 - y); - } else { - //pl_fcont(x, y); - cairo_line_to(m_cCr, x, 1.0 - y); - } - break; - case VertexTypeQuad: - /* Store vertices until we have four in a row. - * The order of vertices when processing quads is: - * 1-----3-----5 - * | | | - * 0-----2-----4 - */ - if (m_iPrevVertexCount >= 3) { - // Plot this quad - //cairo_set_source_rgb(m_cCr, 0.2, 1 - m_aPrevY[0], m_aPrevX[0]); - cairo_rectangle (m_cCr, m_aPrevX[2], - 1 - m_aPrevY[2], m_aPrevX[2] - m_aPrevX[0], - y - m_aPrevY[2]); - cairo_fill (m_cCr); + switch(m_iVertexType) { + case VertexTypeLine: + if (m_bIsFirstVertex) { + m_bIsFirstVertex = false; + //pl_fmove(x, y); + cairo_move_to(m_cCr, x, 1-y); + } else { + //pl_fcont(x, y); + cairo_line_to(m_cCr, x, 1-y); + } + break; + case VertexTypeQuad: + /* Store vertices until we got four in a row. + * The order of vertices when processing quads is: + * 1-----3-----5 + * | | | + * 0-----2-----4 + */ + if (m_iPrevVertexCount >= 3) { + // Plot this quad + cairo_move_to(m_cCr, m_aPrevX[0], 1-m_aPrevY[0]); + cairo_line_to(m_cCr, m_aPrevX[1], 1-m_aPrevY[1]); + cairo_line_to(m_cCr, x, y); + cairo_line_to(m_cCr, m_aPrevX[2], 1-m_aPrevY[2]); + cairo_close_path (m_cCr); - /*cairo_move_to(m_cCr, , ); - cairo_line_to(m_cCr, , 1 - m_aPrevY[1]); - cairo_line_to(m_cCr, x, y); - cairo_line_to(m_cCr, m_aPrevX[2], 1 - m_aPrevY[2]);*/ - - // Last vertices of this quad are the first of the next - m_aPrevX[0] = m_aPrevX[2]; - m_aPrevY[0] = m_aPrevY[2]; - m_aPrevX[1] = x; - m_aPrevY[1] = y; - m_iPrevVertexCount = 2; - } else { - // Not at the fourth, keep storing - m_aPrevX[m_iPrevVertexCount] = x; - m_aPrevY[m_iPrevVertexCount] = y; - m_iPrevVertexCount++; - } - break; - default: - // Should not happen - AIM_ASSERT(0); - } + // Last vertices of this quad are the first of the next + m_aPrevX[0] = m_aPrevX[2]; + m_aPrevY[0] = m_aPrevY[2]; + m_aPrevX[1] = x; + m_aPrevY[1] = y; + m_iPrevVertexCount = 2; + } else { + // Not at the fourth, keep storing + m_aPrevX[m_iPrevVertexCount] = x; + m_aPrevY[m_iPrevVertexCount] = y; + m_iPrevVertexCount++; + } + break; + default: + // Should not happen + AIM_ASSERT(0); + } } void GraphicsOutputDeviceCairo::gEnd() { - if(m_iVertexType==VertexTypeLine) + if(m_iVertexType==VertexTypeLine) cairo_stroke (m_cCr); else cairo_fill (m_cCr); - m_iVertexType = VertexTypeNone; + m_iVertexType = VertexTypeNone; } void GraphicsOutputDeviceCairo::gText3f(float x, @@ -299,23 +262,22 @@ float z, const char *sStr, bool bRotated) { - //cairo_text_extents_t te; - if (bRotated) { - cairo_rotate(m_cCr, M_PI/2); - //cairo_move_to(m_cCr, x ,1-y); - cairo_show_text(m_cCr, sStr); - //cairo_identity_matrix(m_cCr); - cairo_rotate(m_cCr, -M_PI/2); - } else { - cairo_move_to(m_cCr, x ,1-y); - cairo_show_text(m_cCr, sStr); - } + cairo_text_extents_t te; + if (bRotated) { + cairo_rotate(m_cCr, M_PI/2); + cairo_move_to(m_cCr, x ,1-y); + cairo_show_text(m_cCr, sStr); + //cairo_identity_matrix(m_cCr); + cairo_rotate(m_cCr, -M_PI/2); + } else { + cairo_move_to(m_cCr, x ,1-y); + cairo_show_text(m_cCr, sStr); + } } void GraphicsOutputDeviceCairo::gRelease() { - AIM_ASSERT(m_iPlotHandle>0); - CloseFile(); - // Finished this one, up to the next! - m_iFileNumber++; + AIM_ASSERT(m_iPlotHandle>0); + CloseFile(); + // Finished this one, up to the next! + m_iFileNumber++; } -} // namespace aimc