diff options
Diffstat (limited to 'task1/cairodocument.cpp')
| -rw-r--r-- | task1/cairodocument.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/task1/cairodocument.cpp b/task1/cairodocument.cpp new file mode 100644 index 0000000..fb9b20e --- /dev/null +++ b/task1/cairodocument.cpp | |||
| @@ -0,0 +1,124 @@ | |||
| 1 | /** | ||
| 2 | * $Id: cairodocument.cpp 2 2009-10-31 02:48:23Z l0728348 $ | ||
| 3 | * | ||
| 4 | * Copyright 2009 | ||
| 5 | * | ||
| 6 | * @author Manuel Mausz (0728348) | ||
| 7 | * @brief implements some classes to better use cairomm. | ||
| 8 | * however, the design is however crappy. | ||
| 9 | * maybe try using papyrus. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include "cairodocument.h" | ||
| 13 | |||
| 14 | using namespace std; | ||
| 15 | using namespace Cairo; | ||
| 16 | |||
| 17 | static const double mmpt = 25.4/72; | ||
| 18 | |||
| 19 | void CairoObject::apply(const Cairo::RefPtr<Cairo::Context> context) | ||
| 20 | { | ||
| 21 | if (m_objects.size()) | ||
| 22 | context->save(); | ||
| 23 | prepareObject(context); | ||
| 24 | for(CairoObjectList::iterator it = m_objects.begin(); it != m_objects.end(); ++it) | ||
| 25 | (*it)->apply(context); | ||
| 26 | applyObject(context); | ||
| 27 | if (m_objects.size()) | ||
| 28 | context->restore(); | ||
| 29 | } | ||
| 30 | |||
| 31 | /*----------------------------------------------------------------------------*/ | ||
| 32 | |||
| 33 | void CairoFont::applyObject(const Cairo::RefPtr<Cairo::Context> context) | ||
| 34 | { | ||
| 35 | context->set_font_size(m_size); | ||
| 36 | context->select_font_face(m_family, m_slant, m_weight); | ||
| 37 | } | ||
| 38 | /*----------------------------------------------------------------------------*/ | ||
| 39 | |||
| 40 | double CairoFont::height() | ||
| 41 | { | ||
| 42 | if (m_height >= 0) | ||
| 43 | return m_height; | ||
| 44 | Cairo::RefPtr<Cairo::Surface> surface = Cairo::ImageSurface::create(FORMAT_RGB24, 1, 1); | ||
| 45 | Cairo::RefPtr<Cairo::Context> context = Cairo::Context::create(surface); | ||
| 46 | Cairo::FontExtents fextents; | ||
| 47 | applyObject(context); | ||
| 48 | context->get_font_extents(fextents); | ||
| 49 | m_height = fextents.height * mmpt; | ||
| 50 | return m_height; | ||
| 51 | } | ||
| 52 | |||
| 53 | /*----------------------------------------------------------------------------*/ | ||
| 54 | |||
| 55 | void CairoColor::applyObject(const Cairo::RefPtr<Cairo::Context> context) | ||
| 56 | { | ||
| 57 | context->set_source_rgba(m_red, m_green, m_blue, m_alpha); | ||
| 58 | } | ||
| 59 | |||
| 60 | /*----------------------------------------------------------------------------*/ | ||
| 61 | |||
| 62 | void CairoRectangle::applyObject(const Cairo::RefPtr<Cairo::Context> context) | ||
| 63 | { | ||
| 64 | context->set_line_width(m_linewidth / mmpt); | ||
| 65 | context->rectangle(m_x / mmpt, m_y / mmpt, m_width / mmpt, m_height / mmpt); | ||
| 66 | context->stroke(); | ||
| 67 | } | ||
| 68 | |||
| 69 | /*----------------------------------------------------------------------------*/ | ||
| 70 | |||
| 71 | CairoTextBox& CairoTextBox::addBorder(const double linewidth, CairoObject *obj) | ||
| 72 | { | ||
| 73 | CairoRectangle *rectangle = new CairoRectangle(m_x, m_y, m_width, m_height, linewidth); | ||
| 74 | m_rectangles.push_back(rectangle); | ||
| 75 | if (obj != NULL) | ||
| 76 | rectangle->add(*obj); | ||
| 77 | add(*rectangle); | ||
| 78 | return *this; | ||
| 79 | } | ||
| 80 | |||
| 81 | /*----------------------------------------------------------------------------*/ | ||
| 82 | |||
| 83 | void CairoTextBox::applyObject(const Cairo::RefPtr<Cairo::Context> context) | ||
| 84 | { | ||
| 85 | Cairo::FontExtents fextents; | ||
| 86 | context->get_font_extents(fextents); | ||
| 87 | size_t cut; | ||
| 88 | int x = 1; | ||
| 89 | string text = m_text.str(); | ||
| 90 | while((cut = text.find_first_of('\n')) != string::npos) | ||
| 91 | { | ||
| 92 | context->move_to(m_x / mmpt, (m_y + m_padding) / mmpt + x * fextents.height); | ||
| 93 | context->show_text(text.substr(0, cut)); | ||
| 94 | text = text.substr(cut + 1); | ||
| 95 | ++x; | ||
| 96 | } | ||
| 97 | context->move_to(m_x / mmpt, (m_y + m_padding) / mmpt + x * fextents.height); | ||
| 98 | context->show_text(text); | ||
| 99 | } | ||
| 100 | |||
| 101 | /*----------------------------------------------------------------------------*/ | ||
| 102 | |||
| 103 | bool CairoDocument::save(const std::string& filename, const OutputFormat format) | ||
| 104 | { | ||
| 105 | Cairo::RefPtr<Cairo::Surface> surface; | ||
| 106 | switch(format) | ||
| 107 | { | ||
| 108 | #ifdef CAIRO_HAS_PDF_SURFACE | ||
| 109 | case PDF: | ||
| 110 | surface = PdfSurface::create(filename, m_width / mmpt, m_height / mmpt); | ||
| 111 | break; | ||
| 112 | #endif | ||
| 113 | default: | ||
| 114 | return false; | ||
| 115 | } | ||
| 116 | |||
| 117 | Cairo::RefPtr<Cairo::Context> context = Cairo::Context::create(surface); | ||
| 118 | apply(context); | ||
| 119 | surface->finish(); | ||
| 120 | |||
| 121 | return true; | ||
| 122 | } | ||
| 123 | |||
| 124 | /* vim: set et sw=2 ts=2: */ | ||
