/** * $Id: cairodocument.cpp 2 2009-10-31 02:48:23Z l0728348 $ * * Copyright 2009 * * @author Manuel Mausz (0728348) * @brief implements some classes to better use cairomm. * however, the design is however crappy. * maybe try using papyrus. */ #include "cairodocument.h" using namespace std; using namespace Cairo; static const double mmpt = 25.4/72; void CairoObject::apply(const Cairo::RefPtr context) { if (m_objects.size()) context->save(); prepareObject(context); for(CairoObjectList::iterator it = m_objects.begin(); it != m_objects.end(); ++it) (*it)->apply(context); applyObject(context); if (m_objects.size()) context->restore(); } /*----------------------------------------------------------------------------*/ void CairoFont::applyObject(const Cairo::RefPtr context) { context->set_font_size(m_size); context->select_font_face(m_family, m_slant, m_weight); } /*----------------------------------------------------------------------------*/ double CairoFont::height() { if (m_height >= 0) return m_height; Cairo::RefPtr surface = Cairo::ImageSurface::create(FORMAT_RGB24, 1, 1); Cairo::RefPtr context = Cairo::Context::create(surface); Cairo::FontExtents fextents; applyObject(context); context->get_font_extents(fextents); m_height = fextents.height * mmpt; return m_height; } /*----------------------------------------------------------------------------*/ void CairoColor::applyObject(const Cairo::RefPtr context) { context->set_source_rgba(m_red, m_green, m_blue, m_alpha); } /*----------------------------------------------------------------------------*/ void CairoRectangle::applyObject(const Cairo::RefPtr context) { context->set_line_width(m_linewidth / mmpt); context->rectangle(m_x / mmpt, m_y / mmpt, m_width / mmpt, m_height / mmpt); context->stroke(); } /*----------------------------------------------------------------------------*/ CairoTextBox& CairoTextBox::addBorder(const double linewidth, CairoObject *obj) { CairoRectangle *rectangle = new CairoRectangle(m_x, m_y, m_width, m_height, linewidth); m_rectangles.push_back(rectangle); if (obj != NULL) rectangle->add(*obj); add(*rectangle); return *this; } /*----------------------------------------------------------------------------*/ void CairoTextBox::applyObject(const Cairo::RefPtr context) { Cairo::FontExtents fextents; context->get_font_extents(fextents); size_t cut; int x = 1; string text = m_text.str(); while((cut = text.find_first_of('\n')) != string::npos) { context->move_to(m_x / mmpt, (m_y + m_padding) / mmpt + x * fextents.height); context->show_text(text.substr(0, cut)); text = text.substr(cut + 1); ++x; } context->move_to(m_x / mmpt, (m_y + m_padding) / mmpt + x * fextents.height); context->show_text(text); } /*----------------------------------------------------------------------------*/ bool CairoDocument::save(const std::string& filename, const OutputFormat format) { Cairo::RefPtr surface; switch(format) { #ifdef CAIRO_HAS_PDF_SURFACE case PDF: surface = PdfSurface::create(filename, m_width / mmpt, m_height / mmpt); break; #endif default: return false; } Cairo::RefPtr context = Cairo::Context::create(surface); apply(context); surface->finish(); return true; } /* vim: set et sw=2 ts=2: */