Canola  0.8.D001
lib/program_card/functor/image/pdf.cc
Go to the documentation of this file.
00001 //
00002 // canola - canon canola 1614p emulator
00003 // Copyright (C) 2011 Peter Miller
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License, version 3, as
00007 // published by the Free Software Foundation.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License along
00015 // with this program. If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 
00018 #include <lib/ac/math.h>
00019 #include <cairomm/context.h>
00020 #include <cairomm/surface.h>
00021 
00022 #include <lib/context_saver.h>
00023 #include <lib/program_card/functor/image/pdf.h>
00024 
00025 
00026 program_card_functor_image_pdf::~program_card_functor_image_pdf()
00027 {
00028 }
00029 
00030 
00031 program_card_functor_image::pointer
00032 program_card_functor_image_pdf::create(const std::string &fn)
00033 {
00034     return pointer(new program_card_functor_image_pdf(fn));
00035 }
00036 
00037 
00038 static const double page_width = 210 / 25.4 * 72;
00039 static const double page_height = 297 / 25.4 * 72; // points
00040 static const double card_width = 1360. / 600. * 72.; // points
00041 static const double card_height = 4425. / 600. * 72.;
00042 static const double gap = 72. / 4;
00043 static const double envelope_margin = 72 * (25./600);
00044 static const double envelope_flap = 72 * (250./600);
00045 
00046 
00047 program_card_functor_image_pdf::program_card_functor_image_pdf(
00048     const std::string &fn
00049 ) :
00050     filename(fn)
00051 {
00052     img = Cairo::PdfSurface::create(filename, page_width, page_height);
00053     cr = Cairo::Context::create(img);
00054 }
00055 
00056 
00057 void
00058 program_card_functor_image_pdf::operator()(unsigned card_num,
00059     unsigned card_count, const unsigned char *data, size_t data_size)
00060 {
00061     assert(card_count > 0);
00062     assert(card_num >= 1);
00063     assert(card_num <= card_count);
00064     set_position(card_num, card_count);
00065 
00066     int cards_per_page = page_height / (card_width + gap);
00067     int top_margin =
00068         (page_height - cards_per_page * (card_width + gap) + gap) / 2;
00069 
00070     if (card_num == 1)
00071     {
00072         context_saver cs(cr);
00073         double ew = 2 * (card_width + 2 * envelope_margin) + envelope_flap;
00074         double eh = card_height + envelope_margin + envelope_flap;
00075         double y = top_margin + 2 * card_width + gap;
00076         cr->translate((page_width + eh) / 2, y - ew);
00077         cr->rotate_degrees(90);
00078         draw_envelope(cr);
00079     }
00080 
00081     int card_y = (card_num + 1) % cards_per_page;
00082     if (card_y == 0)
00083         cr->show_page();
00084 
00085     double x = (page_width - card_height) / 2;
00086     double y = top_margin + card_y * (card_width + gap) + card_width;
00087 
00088     context_saver cs(cr);
00089     cr->translate(x, y);
00090     cr->rotate_degrees(-90);
00091 
00092     //
00093     // Draw the card image.
00094     //
00095     draw(cr, data, data_size);
00096 }