Back to index

nux  3.0.0
Public Types | Public Member Functions | Private Attributes
nux::CairoGraphics Class Reference

A cairo graphics container. More...

#include <CairoGraphics.h>

Collaboration diagram for nux::CairoGraphics:
Collaboration graph
[legend]

List of all members.

Public Types

enum  Alignment { ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_JUSTIFY }
 Enum used to specify horizontal alignment. More...
enum  VAlignment { VALIGN_TOP, VALIGN_MIDDLE, VALIGN_BOTTOM }
 Enum used to specify vertical alignment. More...
enum  Trimming {
  TRIMMING_NONE, TRIMMING_CHARACTER, TRIMMING_WORD, TRIMMING_CHARACTER_ELLIPSIS,
  TRIMMING_WORD_ELLIPSIS, TRIMMING_PATH_ELLIPSIS
}
 Enum used to specify trimming type. More...
enum  TextFlag { TEXT_FLAGS_NONE = 0, TEXT_FLAGS_UNDERLINE = 1, TEXT_FLAGS_STRIKEOUT = 2, TEXT_FLAGS_WORDWRAP = 4 }
 Enum used to specify text flags. More...

Public Member Functions

 CairoGraphics (cairo_format_t format, int width, int height)
 ~CairoGraphics ()
cairo_t * GetContext ()
 Return a cairo context to the encapsulated surface.
cairo_t * GetInternalContext ()
 Return an internal cairo context to the encapsulated surface. Should not be destroyed.
cairo_surface_t * GetSurface ()
NBitmapDataGetBitmap ()
 Create a NBitmapData pointer to a 2D texture data.
int GetWidth () const
int GetHeight () const
bool PushState ()
bool PopState ()
bool ClearCanvas ()
bool ClearRect (double x, double y, double w, double h)
bool DrawLine (double x0, double y0, double x1, double y1, double width, const Color &c)
void TranslateCoordinates (double dx, double dy)
bool DrawFilledRect (double x, double y, double w, double h, const Color &c)
bool DrawCanvas (double x, double y, CairoGraphics *cg)
bool DrawRoundedRectangle (cairo_t *cr, double aspect, double x, double y, double cornerRadius, double width, double height, bool align=false)
bool BlurSurface (unsigned int radius, cairo_surface_t *surf=NULL)
bool IntersectRectClipRegion (double x, double y, double w, double h)
bool IntersectGeneralClipRegion (std::list< Rect > &region)

Private Attributes

cairo_format_t m_surface_format
 Cairo surface format.
cairo_surface_t * _cairo_surface
 Cairo surface.
cairo_t * _cr
int _width
 Surface width.
int _height
 Surface height.
double _zoom
float _opacity
std::stack< float > _opacity_stack

Detailed Description

A cairo graphics container.

CairoGraphics encapsulates a cairo surface and context.

Definition at line 60 of file CairoGraphics.h.


Member Enumeration Documentation

Enum used to specify horizontal alignment.

Enumerator:
ALIGN_LEFT 
ALIGN_CENTER 
ALIGN_RIGHT 
ALIGN_JUSTIFY 

Definition at line 124 of file CairoGraphics.h.

Enum used to specify text flags.

Enumerator:
TEXT_FLAGS_NONE 
TEXT_FLAGS_UNDERLINE 
TEXT_FLAGS_STRIKEOUT 
TEXT_FLAGS_WORDWRAP 

Definition at line 155 of file CairoGraphics.h.

Enum used to specify trimming type.

Enumerator:
TRIMMING_NONE 
TRIMMING_CHARACTER 
TRIMMING_WORD 
TRIMMING_CHARACTER_ELLIPSIS 
TRIMMING_WORD_ELLIPSIS 
TRIMMING_PATH_ELLIPSIS 

Definition at line 143 of file CairoGraphics.h.

Enum used to specify vertical alignment.

Enumerator:
VALIGN_TOP 
VALIGN_MIDDLE 
VALIGN_BOTTOM 

Definition at line 134 of file CairoGraphics.h.


Constructor & Destructor Documentation

nux::CairoGraphics::CairoGraphics ( cairo_format_t  format,
int  width,
int  height 
)

Definition at line 31 of file CairoGraphics.cpp.

    :   _width(0)
    ,   _height(0)
  {
    nuxAssert(width >= 0);
    nuxAssert(height >= 0);

    _width = width;
    _height = height;

    if (_width <= 0)
      _width = 1;

    if (_height <= 0)
      _height = 1;

    _cairo_surface = cairo_image_surface_create(format, _width, _height);
    m_surface_format = format;

    _cr = cairo_create(_cairo_surface);
    if (cairo_status(_cr) == CAIRO_STATUS_NO_MEMORY)
    {
      // If memory cannot be allocated, a special cairo_t object will be returned
      // on which cairo_status() returns CAIRO_STATUS_NO_MEMORY.
      // You can use this object normally, but no drawing will be done. 
      nuxAssertMsg(0, "[CairoGraphics::GetContext] Cairo context error.");
    }

    _opacity = 1.0f;
    _zoom = 1.0;
  }

Definition at line 63 of file CairoGraphics.cpp.

  {
    if (_cr)
    {
      cairo_destroy(_cr);
    }
    cairo_surface_destroy(_cairo_surface);
  }

Member Function Documentation

bool nux::CairoGraphics::BlurSurface ( unsigned int  radius,
cairo_surface_t *  surf = NULL 
)

Definition at line 563 of file CairoGraphics.cpp.

  {
    cairo_surface_t* surface;
    guchar*          pixels;
    guint            width;
    guint            height;
    cairo_format_t   format;

    if (surf)
      surface = surf;
    else
      surface = cairo_get_target(_cr);

    // don't do anything if we're not dealing with an image-surface
      if (cairo_surface_get_type(surface) != CAIRO_SURFACE_TYPE_IMAGE)
      return false;

    // before we mess with the surface execute any pending drawing
    cairo_surface_flush(surface);

    pixels = cairo_image_surface_get_data(surface);
    width  = cairo_image_surface_get_width(surface);
    height = cairo_image_surface_get_height(surface);
    format = cairo_image_surface_get_format(surface);

    switch(format)
    {
      case CAIRO_FORMAT_ARGB32:
        _expblur(pixels, width, height, 4, radius, 16, 7);
      break;

      case CAIRO_FORMAT_RGB24:
        _expblur(pixels, width, height, 3, radius, 16, 7);
      break;

      case CAIRO_FORMAT_A8:
        _expblur(pixels, width, height, 1, radius, 16, 7);
      break;

      default :
        // do nothing
      break;
    }

    // inform cairo we altered the surfaces contents
    cairo_surface_mark_dirty(surface);

    return true;
  }

Here is the call graph for this function:

Definition at line 210 of file CairoGraphics.cpp.

  {
    // Clear the surface.
    nuxAssert(_cr);
    cairo_operator_t op = cairo_get_operator(_cr);
    cairo_set_operator(_cr, CAIRO_OPERATOR_CLEAR);
    cairo_paint(_cr);
    cairo_set_operator(_cr, op);

    // Set the clip region to an infinitely large shape containing the target.
    cairo_reset_clip(_cr);

    _opacity = 1.0f;
    _opacity_stack = std::stack<float>();

    cairo_restore(_cr);
    cairo_save(_cr);

    return true;
  }

Here is the caller graph for this function:

bool nux::CairoGraphics::ClearRect ( double  x,
double  y,
double  w,
double  h 
)

Definition at line 231 of file CairoGraphics.cpp.

  {
    nuxAssert(_cr);
    cairo_rectangle(_cr, x, y, w, h);
    cairo_operator_t op = cairo_get_operator(_cr);
    cairo_set_operator(_cr, CAIRO_OPERATOR_CLEAR);
    cairo_fill(_cr);
    cairo_set_operator(_cr, op);
    return true;
  }

Here is the caller graph for this function:

bool nux::CairoGraphics::DrawCanvas ( double  x,
double  y,
CairoGraphics cg 
)

Definition at line 280 of file CairoGraphics.cpp.

  {
    if (cg == 0) return false;

    cairo_surface_t *s = cg->GetSurface();
    double src_zoom = cg->_zoom;
    double inv_zoom = 1.0 / src_zoom;

    cairo_save(_cr);

    IntersectRectClipRegion(x, y, cg->GetWidth(), cg->GetHeight());

    cairo_scale(_cr, inv_zoom, inv_zoom);
    cairo_set_source_surface(_cr, s, x * src_zoom, y * src_zoom);

    cairo_pattern_set_extend(cairo_get_source(_cr), CAIRO_EXTEND_PAD);

    cairo_paint_with_alpha(_cr, _opacity);
    cairo_restore(_cr);

    return true;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool nux::CairoGraphics::DrawFilledRect ( double  x,
double  y,
double  w,
double  h,
const Color &  c 
)

Definition at line 266 of file CairoGraphics.cpp.

  {
    nuxAssert(_cr);
    if (w <= 0.0 || h <= 0.0) {
      return false;
    }

    cairo_set_source_rgba(_cr, c.red, c.green, c.blue, _opacity);
    cairo_rectangle(_cr, x, y, w, h);
    cairo_fill(_cr);
    return true;
  }
bool nux::CairoGraphics::DrawLine ( double  x0,
double  y0,
double  x1,
double  y1,
double  width,
const Color &  c 
)

Definition at line 242 of file CairoGraphics.cpp.

  {
    nuxAssert(_cr);
    if (width < 0.0)
    {
      return false;
    }

    cairo_set_line_width(_cr, width);
    cairo_set_source_rgba(_cr, c.red, c.green, c.blue, _opacity);
    cairo_move_to(_cr, x0, y0);
    cairo_line_to(_cr, x1, y1);
    cairo_stroke(_cr);

    return true;
  }

Here is the caller graph for this function:

bool nux::CairoGraphics::DrawRoundedRectangle ( cairo_t *  cr,
double  aspect,
double  x,
double  y,
double  cornerRadius,
double  width,
double  height,
bool  align = false 
)

Definition at line 315 of file CairoGraphics.cpp.

  {
    double radius = cornerRadius / aspect;

    if (align)
    {
      // top-left, right of the corner
      cairo_move_to(cr, _align(x + radius), _align(y));

      // top-right, left of the corner
      cairo_line_to(cr, _align(x + width - radius), _align(y));

      // top-right, below the corner
      cairo_arc(cr,
                 _align(x + width - radius),
                 _align(y + radius),
                 radius,
                 -90.0f * G_PI / 180.0f,
                 0.0f * G_PI / 180.0f);

      // bottom-right, above the corner
      cairo_line_to(cr, _align(x + width), _align(y + height - radius));

      // bottom-right, left of the corner
      cairo_arc(cr,
                 _align(x + width - radius),
                 _align(y + height - radius),
                 radius,
                 0.0f * G_PI / 180.0f,
                 90.0f * G_PI / 180.0f);

      // bottom-left, right of the corner
      cairo_line_to(cr, _align(x + radius), _align(y + height));

      // bottom-left, above the corner
      cairo_arc(cr,
                 _align(x + radius),
                 _align(y + height - radius),
                 radius,
                 90.0f * G_PI / 180.0f,
                 180.0f * G_PI / 180.0f);

      // top-left, right of the corner
      cairo_arc(cr,
                 _align(x + radius),
                 _align(y + radius),
                 radius,
                 180.0f * G_PI / 180.0f,
                 270.0f * G_PI / 180.0f);
    }
    else
    {
      // top-left, right of the corner
      cairo_move_to(cr, x + radius, y);

      // top-right, left of the corner
      cairo_line_to(cr, x + width - radius, y);

      // top-right, below the corner
      cairo_arc(cr,
                 x + width - radius,
                 y + radius,
                 radius,
                 -90.0f * G_PI / 180.0f,
                 0.0f * G_PI / 180.0f);

      // bottom-right, above the corner
      cairo_line_to(cr, x + width, y + height - radius);

      // bottom-right, left of the corner
      cairo_arc(cr,
                 x + width - radius,
                 y + height - radius,
                 radius,
                 0.0f * G_PI / 180.0f,
                 90.0f * G_PI / 180.0f);

      // bottom-left, right of the corner
      cairo_line_to(cr, x + radius, y + height);

      // bottom-left, above the corner
      cairo_arc(cr,
                 x + radius,
                 y + height - radius,
                 radius,
                 90.0f * G_PI / 180.0f,
                 180.0f * G_PI / 180.0f);

      // top-left, right of the corner
      cairo_arc(cr,
                 x + radius,
                 y + radius,
                 radius,
                 180.0f * G_PI / 180.0f,
                 270.0f * G_PI / 180.0f);
    }

    return true;
  }

Here is the call graph for this function:

Create a NBitmapData pointer to a 2D texture data.

The returned data must be destroyed with delete.

Returns:
A pointer to a 2D texture data.

Definition at line 95 of file CairoGraphics.cpp.

  {
    if ((_width <= 0) || (_height <= 0))
    {
      nuxDebugMsg("[CairoGraphics::GetBitmap] Invalid surface.");
    }

    NUX_RETURN_VALUE_IF_NULL(_width, 0);
    NUX_RETURN_VALUE_IF_NULL(_height, 0);

    BitmapFormat bitmap_format = BITFMT_UNKNOWN;

    if (m_surface_format == CAIRO_FORMAT_ARGB32)
    {
      // Each pixel is a 32-bit quantity, with alpha in the upper 8 bits,
      // then red, then green, then blue. The 32-bit quantities are stored native-endian.
      // Pre-multiplied alpha is used. (That is, 50% transparent red is 0x80800000, not 0x80ff0000.)
      bitmap_format = BITFMT_B8G8R8A8;
    }

    if (m_surface_format == CAIRO_FORMAT_RGB24)
    {
      // Each pixel is a 32-bit quantity, with the upper 8 bits unused.
      // Red, Green, and Blue are stored in the remaining 24 bits in that order.
      bitmap_format = BITFMT_B8G8R8A8;
    }

    if (m_surface_format == CAIRO_FORMAT_A8)
    {
      // Each pixel is a 8-bit quantity holding an alpha value.
      bitmap_format = BITFMT_A8;
    }

    if (m_surface_format == CAIRO_FORMAT_A1)
      bitmap_format = BITFMT_A8;

    NTextureData *bitmap_data = new NTextureData(bitmap_format, _width, _height, 1);
    unsigned char *ptr = cairo_image_surface_get_data(_cairo_surface);
    int stride = cairo_image_surface_get_stride(_cairo_surface);

    if (ptr == NULL || stride == 0)
    {
      // _cairo_surface is not a valid surface
      nuxError("[CairoGraphics::GetBitmap] Invalid surface");
      return bitmap_data; // just returns because we will segfault otherwise
    }

    if (m_surface_format == CAIRO_FORMAT_A1)
    {
      unsigned char *temp = new unsigned char[bitmap_data->GetSurface(0).GetPitch() ];

      for (int j = 0; j < _height; j++)
      {
        for (int i = 0; i < _width; i++)
        {
          // Get the byte
          int a = ptr[j * stride + i/8];
          // Get the position in the byte
          int b = (i - 8 * (i / 8));
          // Shift the byte and get the last bit
          int c = (a >> b) & 0x1;
          // If the last bit is set, put 1, otherwise put 0
          temp[i] = c ? 0xFF : 0x0;
        }

        Memcpy( bitmap_data->GetSurface(0).GetPtrRawData() + j * bitmap_data->GetSurface(0).GetPitch(),
                 (const void *) (&temp[0]),
                 _width);
      }
    }
    else
    {
      for (int j = 0; j < _height; j++)
      {
        Memcpy(bitmap_data->GetSurface(0).GetPtrRawData() + j * bitmap_data->GetSurface(0).GetPitch(),
                (const void *) (&ptr[j * stride]),
                _width * GPixelFormats[bitmap_format].NumComponents);
      }
    }

    return bitmap_data;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Return a cairo context to the encapsulated surface.

Return the cairo context of this object. Call cairo_destroy to destroy the context when you are done with it.

Returns:
A cairo context.

Definition at line 72 of file CairoGraphics.cpp.

  { 
    cairo_t *cr = cairo_create(_cairo_surface);
    if (cairo_status(cr) == CAIRO_STATUS_NO_MEMORY)
    {
      // If memory cannot be allocated, a special cairo_t object will be returned
      // on which cairo_status() returns CAIRO_STATUS_NO_MEMORY.
      // You can use this object normally, but no drawing will be done. 
      nuxAssertMsg(0, "[CairoGraphics::GetContext] Cairo context error.");
    }
    return cr;
  }

Here is the caller graph for this function:

Definition at line 183 of file CairoGraphics.cpp.

  {
    return _height;
  }

Here is the caller graph for this function:

Return an internal cairo context to the encapsulated surface. Should not be destroyed.

Return the cairo context of this object. This cairo context should not be destroyed with cairo_destroy.

Returns:
A cairo context.

Definition at line 85 of file CairoGraphics.cpp.

  { 
    return _cr;
  }

Here is the caller graph for this function:

cairo_surface_t * nux::CairoGraphics::GetSurface ( )

Definition at line 90 of file CairoGraphics.cpp.

  {
    return _cairo_surface;
  }

Here is the caller graph for this function:

Definition at line 178 of file CairoGraphics.cpp.

  {
    return _width;
  }

Here is the caller graph for this function:

bool nux::CairoGraphics::IntersectGeneralClipRegion ( std::list< Rect > &  region)

Definition at line 627 of file CairoGraphics.cpp.

  {
    bool do_clip = false;
    cairo_antialias_t pre = cairo_get_antialias(_cr);
    cairo_set_antialias(_cr, CAIRO_ANTIALIAS_NONE);
    
    std::list<Rect>::iterator it;
    for (it = region.begin(); it != region.end(); it++)
    {
      Rect rect = (*it);

      if (!rect.IsNull())
      {
        cairo_rectangle(_cr, rect.x, rect.y, rect.width, rect.height);
        do_clip = true;
      }
    }

    if (do_clip)
    {
      cairo_clip(_cr);
    }

    cairo_set_antialias(_cr, pre);
    return true;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool nux::CairoGraphics::IntersectRectClipRegion ( double  x,
double  y,
double  w,
double  h 
)

Definition at line 613 of file CairoGraphics.cpp.

  {
    if (w <= 0.0 || h <= 0.0) {
      return false;
    }

    cairo_antialias_t pre = cairo_get_antialias(_cr);
    cairo_set_antialias(_cr, CAIRO_ANTIALIAS_NONE);
    cairo_rectangle(_cr, x, y, w, h);
    cairo_clip(_cr);
    cairo_set_antialias(_cr, pre);
    return true;
  }

Here is the caller graph for this function:

Definition at line 196 of file CairoGraphics.cpp.

  {
    nuxAssert(_cr);
    if (_opacity_stack.empty())
    {
      return false;
    }

    _opacity = _opacity_stack.top();
    _opacity_stack.pop();
    cairo_restore(_cr);
    return true;
  }

Here is the caller graph for this function:

Definition at line 188 of file CairoGraphics.cpp.

  {
    nuxAssert(_cr);
    _opacity_stack.push(_opacity);
    cairo_save(_cr);
    return true;
  }

Here is the caller graph for this function:

void nux::CairoGraphics::TranslateCoordinates ( double  dx,
double  dy 
)

Definition at line 260 of file CairoGraphics.cpp.

  {
    nuxAssert(_cr);
    cairo_translate(_cr, tx, ty);
  }

Member Data Documentation

cairo_surface_t* nux::CairoGraphics::_cairo_surface [private]

Cairo surface.

Definition at line 166 of file CairoGraphics.h.

cairo_t* nux::CairoGraphics::_cr [private]

Definition at line 168 of file CairoGraphics.h.

Surface height.

Definition at line 170 of file CairoGraphics.h.

Definition at line 173 of file CairoGraphics.h.

std::stack<float> nux::CairoGraphics::_opacity_stack [private]

Definition at line 174 of file CairoGraphics.h.

Surface width.

Definition at line 169 of file CairoGraphics.h.

double nux::CairoGraphics::_zoom [private]

Definition at line 172 of file CairoGraphics.h.

cairo_format_t nux::CairoGraphics::m_surface_format [private]

Cairo surface format.

Definition at line 164 of file CairoGraphics.h.


The documentation for this class was generated from the following files: