Пример #1
0
  void PrintNotesNoteAddin::on_begin_print(const Glib::RefPtr<Gtk::PrintContext>& context)
  {
    m_timestamp_footer = create_layout_for_timestamp(context);
    // Create and initialize the page margins
    m_margin_top = cm_to_pixel (1.5, context->get_dpi_y());
    m_margin_left = cm_to_pixel (1, context->get_dpi_x());
    m_margin_right = cm_to_pixel (1, context->get_dpi_x());
    m_margin_bottom = 0;
    double max_height = pango_units_from_double(context->get_height()
                                                - m_margin_top - m_margin_bottom
                                                - compute_footer_height(context));

    DBG_OUT("margins = %d %d %d %d", m_margin_top, m_margin_left,
            m_margin_right, m_margin_bottom);

    m_page_breaks.clear();

    Gtk::TextIter position;
    Gtk::TextIter end_iter;
    get_buffer()->get_bounds (position, end_iter);

    double page_height = 0;
    bool done = position.compare (end_iter) >= 0;
    while (!done) {
      Gtk::TextIter line_end = position;
      if (!line_end.ends_line ()) {
        line_end.forward_to_line_end ();
      }

      int paragraph_number = position.get_line();
      int indentation = 0;
      Glib::RefPtr<Pango::Layout> layout = create_layout_for_paragraph(
        context, position, line_end, indentation);

      Pango::Rectangle ink_rect;
      Pango::Rectangle logical_rect;
      for(int line_in_paragraph = 0;  line_in_paragraph < layout->get_line_count();
          line_in_paragraph++) {
        Glib::RefPtr<Pango::LayoutLine> line = layout->get_line(line_in_paragraph);
        line->get_extents (ink_rect, logical_rect);

        if ((page_height + logical_rect.get_height()) >= max_height) {
          PageBreak(paragraph_number, line_in_paragraph);
          m_page_breaks.push_back (PageBreak(paragraph_number, line_in_paragraph));
          page_height = 0;
        }

        page_height += logical_rect.get_height();

      }
      position.forward_line ();
      done = position.compare (end_iter) >= 0;
    }

    m_print_op->set_n_pages(m_page_breaks.size() + 1);
  }
Пример #2
0
  Glib::RefPtr<Pango::Layout> 
  PrintNotesNoteAddin::create_layout_for_paragraph(const Glib::RefPtr<Gtk::PrintContext> & context, 
                                                   Gtk::TextIter p_start,
                                                   Gtk::TextIter p_end,
                                                   int & indentation)
  {
    Glib::RefPtr<Pango::Layout> layout = context->create_pango_layout();

    layout->set_font_description(
      get_window()->editor()->get_pango_context()->get_font_description());
    int start_index = p_start.get_line_index();
    indentation = 0;

    double dpiX = context->get_dpi_x();
    {
      Pango::AttrList attr_list;

      Gtk::TextIter segm_start = p_start;
      Gtk::TextIter segm_end;

      while (segm_start.compare (p_end) < 0) {
        segm_end = segm_start;
        std::list<Pango::Attribute> attrs;
        get_paragraph_attributes (layout, dpiX, indentation,
                                  segm_end, p_end, attrs);

        guint si = (guint) (segm_start.get_line_index() - start_index);
        guint ei = (guint) (segm_end.get_line_index() - start_index);

        for(std::list<Pango::Attribute>::iterator iter = attrs.begin();
            iter != attrs.end(); ++iter) {
          
          Pango::Attribute & a(*iter);
          a.set_start_index(si);
          a.set_end_index(ei);
          attr_list.insert(a);
        }
        segm_start = segm_end;
      }

      layout->set_attributes(attr_list);
    }

    gnote::DepthNoteTag::Ptr depth = get_buffer()->find_depth_tag(p_start);
    if(depth) {
        indentation += ((int) (dpiX / 3)) * depth->get_depth();
    }
    layout->set_width(pango_units_from_double((int)context->get_width() -
                                              m_margin_left - m_margin_right - indentation));
    layout->set_wrap (Pango::WRAP_WORD_CHAR);
    layout->set_text (get_buffer()->get_slice (p_start, p_end, false));
    return layout;
  }
Пример #3
0
  void PrintNotesNoteAddin::on_draw_page(const Glib::RefPtr<Gtk::PrintContext>& context, guint page_nr)
  {
    Cairo::RefPtr<Cairo::Context> cr = context->get_cairo_context();
    cr->move_to (m_margin_left, m_margin_top);

    PageBreak start;
    if (page_nr != 0) {
      start = m_page_breaks [page_nr - 1];
    }

    PageBreak end(-1, -1);
    if (m_page_breaks.size() > page_nr) {
      end = m_page_breaks [page_nr];
    }

    Gtk::TextIter position;
    Gtk::TextIter end_iter;
    get_buffer()->get_bounds (position, end_iter);

    // Fast-forward to the starting line
    while (position.get_line() < start.get_paragraph()) {
      position.forward_line ();
    }

    bool done = position.compare (end_iter) >= 0;
    while (!done) {
      Gtk::TextIter line_end = position;
      if (!line_end.ends_line ()) {
        line_end.forward_to_line_end ();
      }


      int paragraph_number = position.get_line();
      int indentation;

      {
        Glib::RefPtr<Pango::Layout> layout =
          create_layout_for_paragraph (context,position, line_end, indentation);

        for(int line_number = 0;
            line_number < layout->get_line_count() && !done;
            line_number++) {
          // Skip the lines up to the starting line in the
          // first paragraph on this page
          if ((paragraph_number == start.get_paragraph()) &&
              (line_number < start.get_line())) {
            continue;
          }
          // Break as soon as we hit the end line
          if ((paragraph_number == end.get_paragraph()) &&
              (line_number == end.get_line())) {
            done = true;
            break;
          }



          Glib::RefPtr<Pango::LayoutLine> line = layout->get_line(line_number);
          
          Pango::Rectangle ink_rect;
          Pango::Rectangle logical_rect;
          line->get_extents (ink_rect, logical_rect);

          double curX, curY;
          cr->get_current_point(curX, curY);
          cr->move_to (m_margin_left + indentation, curY);
          int line_height = pango_units_to_double(logical_rect.get_height());

          double x, y;
          x = m_margin_left + indentation;
          cr->get_current_point(curX, curY);
          y = curY + line_height;
          pango_cairo_show_layout_line(cr->cobj(), line->gobj());
          cr->move_to(x, y);
        }
      }

      position.forward_line ();
      done = done || (position.compare (end_iter) >= 0);
    }

    // Print the footer
    int total_height = context->get_height();
    int total_width = context->get_width();
    int footer_height = 0;

    double footer_anchor_x, footer_anchor_y;

    {
      Glib::RefPtr<Pango::Layout> pages_footer 
        = create_layout_for_pagenumbers (context, page_nr + 1, 
                                         m_page_breaks.size() + 1);

      Pango::Rectangle ink_footer_rect;
      Pango::Rectangle logical_footer_rect;
      pages_footer->get_extents(ink_footer_rect, logical_footer_rect);
      
      footer_anchor_x = cm_to_pixel(0.5, context->get_dpi_x());
      footer_anchor_y = total_height - m_margin_bottom;
      footer_height = pango_units_to_double(logical_footer_rect.get_height());
      
      cr->move_to(total_width - pango_units_to_double(logical_footer_rect.get_width()) - cm_to_pixel(0.5, context->get_dpi_x()), footer_anchor_y);
                                                      
      pango_cairo_show_layout_line(cr->cobj(), 
                                   (pages_footer->get_line(0))->gobj());

    }

    cr->move_to(footer_anchor_x, footer_anchor_y);
    pango_cairo_show_layout_line(cr->cobj(), 
                                 (m_timestamp_footer->get_line(0))->gobj());

    cr->move_to(cm_to_pixel(0.5, context->get_dpi_x()), 
                total_height - m_margin_bottom - footer_height);
    cr->line_to(total_width - cm_to_pixel(0.5, context->get_dpi_x()),
                total_height - m_margin_bottom - footer_height);
    cr->stroke();
  }