[gnote] Fix print formatting issues. (Tomboy bug #572024) (tb-backport)
- From: Hubert Figuière <hub src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnote] Fix print formatting issues. (Tomboy bug #572024) (tb-backport)
- Date: Fri, 17 Jul 2009 23:44:42 +0000 (UTC)
commit bfbd7507957fbe87dfa1691dd83d6ee01927c7f3
Author: Hubert Figuiere <hub figuiere net>
Date: Thu Jul 16 21:23:28 2009 -0400
Fix print formatting issues. (Tomboy bug #572024) (tb-backport)
src/addins/printnotes/printnotesnoteaddin.cpp | 253 +++++++++++++------------
src/addins/printnotes/printnotesnoteaddin.hpp | 51 +++--
2 files changed, 157 insertions(+), 147 deletions(-)
---
diff --git a/src/addins/printnotes/printnotesnoteaddin.cpp b/src/addins/printnotes/printnotesnoteaddin.cpp
index bf905ab..67bcc79 100644
--- a/src/addins/printnotes/printnotesnoteaddin.cpp
+++ b/src/addins/printnotes/printnotesnoteaddin.cpp
@@ -60,7 +60,7 @@ namespace printnotes {
}
const char * PrintNotesModule::version() const
{
- return "0.3";
+ return "0.4";
}
void PrintNotesNoteAddin::initialize()
@@ -140,11 +140,14 @@ namespace printnotes {
void PrintNotesNoteAddin::get_paragraph_attributes(const Glib::RefPtr<Pango::Layout> & layout,
double dpiX,
- PrintMargins & margins,
+ int & indentation,
Gtk::TextIter & position,
- Gtk::TextIter & limit,
+ const Gtk::TextIter & limit,
std::list<Pango::Attribute> & attributes)
{
+ attributes.clear();
+ indentation = 0;
+
Glib::SListHandle<Glib::RefPtr<Gtk::TextTag> > tags = position.get_tags();
position.forward_to_tag_toggle(Glib::RefPtr<Gtk::TextTag>(NULL));
if (position.compare (limit) > 0) {
@@ -175,10 +178,10 @@ namespace printnotes {
layout->set_indent(tag->property_indent());
}
if (tag->property_left_margin_set()) {
- margins.left = (int)(tag->property_left_margin() / screen_dpiX * dpiX);
+ indentation = (int)(tag->property_left_margin() / screen_dpiX * dpiX);
}
if (tag->property_right_margin_set()) {
- margins.right = (int)(tag->property_right_margin() / screen_dpiX * dpiX);
+ indentation = (int)(tag->property_right_margin() / screen_dpiX * dpiX);
}
// if (tag->property_font_desc()) {
attributes.push_back(
@@ -231,13 +234,14 @@ namespace printnotes {
PrintNotesNoteAddin::create_layout_for_paragraph(const Glib::RefPtr<Gtk::PrintContext> & context,
Gtk::TextIter p_start,
Gtk::TextIter p_end,
- PrintMargins & margins)
+ int & indentation)
{
Glib::RefPtr<Pango::Layout> layout = context->create_pango_layout();
layout->set_font_description(
get_window()->editor()->get_style()->get_font());
int start_index = p_start.get_line_index();
+ indentation = 0;
{
Pango::AttrList attr_list;
@@ -250,7 +254,7 @@ namespace printnotes {
while (segm_start.compare (p_end) < 0) {
segm_end = segm_start;
std::list<Pango::Attribute> attrs;
- get_paragraph_attributes (layout, dpiX, margins,
+ get_paragraph_attributes (layout, dpiX, indentation,
segm_end, p_end, attrs);
guint si = (guint) (segm_start.get_line_index() - start_index);
@@ -271,8 +275,8 @@ namespace printnotes {
}
layout->set_width(pango_units_from_double((int)context->get_width() -
- margins.horizontal_margins() -
- m_page_margins.horizontal_margins()));
+ 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;
}
@@ -302,6 +306,8 @@ namespace printnotes {
Glib::RefPtr<Pango::Layout>
PrintNotesNoteAddin::create_layout_for_timestamp(const Glib::RefPtr<Gtk::PrintContext> & context)
{
+ std::string timestamp = sharp::DateTime::now().to_string ("%c");
+
Glib::RefPtr<Pango::Layout> layout = context->create_pango_layout ();
Pango::FontDescription font_desc = get_window()->editor()->get_style()->get_font();
font_desc.set_style(Pango::STYLE_NORMAL);
@@ -310,40 +316,36 @@ namespace printnotes {
layout->set_width(pango_units_from_double((int) context->get_width()));
layout->set_alignment(Pango::ALIGN_RIGHT);
- layout->set_text (m_timestamp);
+ layout->set_text (timestamp);
return layout;
}
+ int PrintNotesNoteAddin::compute_footer_height(const Glib::RefPtr<Gtk::PrintContext> & context)
+ {
+ Glib::RefPtr<Pango::Layout> layout = create_layout_for_timestamp(context);
+ Pango::Rectangle ink_rect;
+ Pango::Rectangle logical_rect;
+ layout->get_extents(ink_rect, logical_rect);
+ return pango_units_to_double(ink_rect.get_height())
+ + cm_to_pixel(0.5, context->get_dpi_y());
+ }
+
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_page_margins.top = cm_to_pixel (1.5, context->get_dpi_y());
- m_page_margins.left = cm_to_pixel (1, context->get_dpi_x());
- m_page_margins.right = cm_to_pixel (1, context->get_dpi_x());
- m_page_margins.bottom = 0;
-
- DBG_OUT("margins = %d %d %d %d", m_page_margins.top, m_page_margins.left,
- m_page_margins.right, m_page_margins.bottom);
-
- // Compute the footer height to define the bottom margin
- m_timestamp = sharp::DateTime::now().to_string ("%c");
- Glib::RefPtr<Pango::Layout> date_time_footer;
- date_time_footer = create_layout_for_timestamp (context);
- Pango::Rectangle footer_ink_rect;
- Pango::Rectangle footer_logical_rect;
- date_time_footer->get_extents (footer_ink_rect, footer_logical_rect);
-
- m_footer_offset = cm_to_pixel (0.5, context->get_dpi_y());
-
- /* Set the bottom margin to the height of the footer + a constant
- * offset for the separation line */
- m_page_margins.bottom += pango_units_to_double(footer_logical_rect.get_height()) + m_footer_offset;
-
- double height = pango_units_from_double ((int) context->get_height()
- - m_page_margins.vertical_margins ());
- double page_height = 0;
+ 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();
@@ -351,32 +353,35 @@ namespace printnotes {
Gtk::TextIter end_iter;
get_buffer()->get_bounds (position, end_iter);
+ double page_height = 0;
bool done = position.compare (end_iter) >= 0;
while (!done) {
- int line_number = position.get_line();
-
Gtk::TextIter line_end = position;
if (!line_end.ends_line ()) {
line_end.forward_to_line_end ();
}
- PrintMargins margins;
-
+ int paragraph_number = position.get_line();
+ int indentation = 0;
Glib::RefPtr<Pango::Layout> layout = create_layout_for_paragraph(
- context, position, line_end, margins);
+ context, position, line_end, indentation);
Pango::Rectangle ink_rect;
Pango::Rectangle logical_rect;
- layout->get_extents (ink_rect, logical_rect);
-
- if ((page_height + logical_rect.get_height()) > height) {
- m_page_breaks.push_back (line_number);
- page_height = 0;
- }
-
- page_height += logical_rect.get_height();
+ 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;
}
@@ -385,106 +390,65 @@ namespace printnotes {
}
- void PrintNotesNoteAddin::print_footer(const Glib::RefPtr<Gtk::PrintContext> & context,
- guint page_nr)
- {
- int total_height = pango_units_from_double ((int)context->get_height());
- int total_width = pango_units_from_double ((int)context->get_width());
-
- Cairo::RefPtr<Cairo::Context> cr = context->get_cairo_context();
- cr->move_to(cm_to_pixel(0.5, context->get_dpi_x()),
- pango_units_to_double(total_height)
- - m_page_margins.bottom + m_footer_offset);
- cr->line_to(pango_units_to_double(total_width)
- - cm_to_pixel(0.5, context->get_dpi_x()),
- pango_units_to_double(total_height) - m_page_margins.bottom
- + m_footer_offset);
- cr->stroke ();
-
- Glib::RefPtr<Pango::Layout> date_time_footer = create_layout_for_timestamp (context);
-
- DBG_ASSERT(date_time_footer, "layout is NULL");
-
- Pango::Rectangle ink_rect;
- Pango::Rectangle logical_rect;
- date_time_footer->get_extents (ink_rect, logical_rect);
-
- double x,y;
- x = cm_to_pixel(0.5, context->get_dpi_x());
- y = pango_units_to_double (total_height) - m_page_margins.bottom
- + m_footer_offset + pango_units_to_double(logical_rect.get_height());
-
- cr->move_to(pango_units_to_double(total_width
- - logical_rect.get_width())
- - cm_to_pixel (0.5, context->get_dpi_x()), y);
-
- pango_cairo_show_layout_line(cr->cobj(),
- (*date_time_footer->get_lines().begin())->gobj());
-
- cr->move_to(x, y);
-
- Glib::RefPtr<Pango::Layout> pages_footer
- = create_layout_for_pagenumbers (context, page_nr + 1,
- m_page_breaks.size() + 1);
- pango_cairo_show_layout_line(cr->cobj(),
- (*pages_footer->get_lines().begin())->gobj());
- }
-
-
-
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_page_margins.left, m_page_margins.top);
+ cr->move_to (m_margin_left, m_margin_top);
- int start_line = 0;
+ PageBreak start;
if (page_nr != 0) {
- start_line = m_page_breaks [page_nr - 1];
+ start = m_page_breaks [page_nr - 1];
}
- int last_line = -1;
+ PageBreak end(-1, -1);
if (m_page_breaks.size() > page_nr) {
- last_line = m_page_breaks [page_nr] - 1;
+ end = m_page_breaks [page_nr];
}
Gtk::TextIter position;
Gtk::TextIter end_iter;
get_buffer()->get_bounds (position, end_iter);
- bool done = position.compare (end_iter) >= 0;
- int line_number = position.get_line();
-
// Fast-forward to the starting line
- while (!done && line_number < start_line) {
- Gtk::TextIter line_end = position;
- if (!line_end.ends_line ()) {
- line_end.forward_to_line_end ();
- }
-
+ while (position.get_line() < start.get_paragraph()) {
position.forward_line ();
- done = position.compare (end_iter) >= 0;
- line_number = position.get_line();
}
- // Print the current page's content
- while (!done && ((last_line == -1) || (line_number < last_line))) {
- line_number = position.get_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 ();
}
- PrintMargins margins;
+
+ int paragraph_number = position.get_line();
+ int indentation;
+
{
Glib::RefPtr<Pango::Layout> layout =
- create_layout_for_paragraph (context,position, line_end, margins);
- Pango::SListHandle_LayoutLine lines(layout->get_lines());
- for(Pango::SListHandle_LayoutLine::const_iterator iter = lines.begin();
- iter != lines.end(); ++iter) {
-
- Glib::RefPtr<Pango::LayoutLine> line = *iter;
+ 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;
@@ -492,10 +456,11 @@ namespace printnotes {
double curX, curY;
cr->get_current_point(curX, curY);
- cr->move_to (margins.left + m_page_margins.left, curY);
+ cr->move_to (m_margin_left + indentation, curY);
int line_height = pango_units_to_double(logical_rect.get_height());
+
double x, y;
- x = margins.left + m_page_margins.left;
+ x = m_margin_left + indentation;
cr->get_current_point(curX, curY);
y = curY + line_height;
pango_cairo_show_layout_line(cr->cobj(), line->gobj());
@@ -504,17 +469,53 @@ namespace printnotes {
}
position.forward_line ();
- done = position.compare (end_iter) >= 0;
+ done = done || (position.compare (end_iter) >= 0);
}
// Print the footer
- print_footer (context, page_nr);
+ 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();
}
void PrintNotesNoteAddin::on_end_print(const Glib::RefPtr<Gtk::PrintContext>&)
{
m_page_breaks.clear ();
+ // clear the RefPtr<>
+ m_timestamp_footer.clear();
}
}
diff --git a/src/addins/printnotes/printnotesnoteaddin.hpp b/src/addins/printnotes/printnotesnoteaddin.hpp
index e329d04..25a8072 100644
--- a/src/addins/printnotes/printnotesnoteaddin.hpp
+++ b/src/addins/printnotes/printnotesnoteaddin.hpp
@@ -52,31 +52,33 @@ public:
DECLARE_MODULE(PrintNotesModule);
-struct PrintMargins
+class PageBreak
{
- int top;
- int left;
- int right;
- int bottom;
-
- PrintMargins()
- : top(0), left(0), right(0), bottom(0)
+public:
+ PageBreak(int paragraph, int line)
+ : m_break_paragraph(paragraph)
+ , m_break_line(line)
{
}
- void clear()
+ PageBreak()
+ : m_break_paragraph(0)
+ , m_break_line(0)
{
- top = left = right = bottom = 0;
}
- int vertical_margins()
+ int get_paragraph() const
{
- return top + bottom;
+ return m_break_paragraph;
}
- int horizontal_margins()
+ int get_line() const
{
- return left + right;
+ return m_break_line;
}
+private:
+ int m_break_paragraph;
+ int m_break_line;
};
+
class PrintNotesNoteAddin
: public gnote::NoteAddin
{
@@ -93,19 +95,24 @@ public:
{
return (int) (cm * dpi / 2.54);
}
+ static int inch_to_pixel(double inch, double dpi)
+ {
+ return (int) (inch * dpi);
+ }
private:
void get_paragraph_attributes(const Glib::RefPtr<Pango::Layout> & layout,
- double dpiX, PrintMargins & margins,
+ double dpiX, int & indentation,
Gtk::TextIter & position,
- Gtk::TextIter & limit,
+ const Gtk::TextIter & limit,
std::list<Pango::Attribute> & attributes);
Glib::RefPtr<Pango::Layout> create_layout_for_paragraph(const Glib::RefPtr<Gtk::PrintContext> & context,
Gtk::TextIter p_start,
Gtk::TextIter p_end,
- PrintMargins & margins);
+ int & indentation);
Glib::RefPtr<Pango::Layout> create_layout_for_pagenumbers(const Glib::RefPtr<Gtk::PrintContext> & context, int page_number, int total_pages);
Glib::RefPtr<Pango::Layout> create_layout_for_timestamp(const Glib::RefPtr<Gtk::PrintContext> & context);
+ int compute_footer_height(const Glib::RefPtr<Gtk::PrintContext> & context);
void on_begin_print(const Glib::RefPtr<Gtk::PrintContext>&);
void print_footer(const Glib::RefPtr<Gtk::PrintContext>&, guint);
@@ -114,11 +121,13 @@ private:
/////
void print_button_clicked();
Gtk::ImageMenuItem * m_item;
- PrintMargins m_page_margins;
- int m_footer_offset;
- std::vector<int> m_page_breaks;
+ int m_margin_top;
+ int m_margin_left;
+ int m_margin_right;
+ int m_margin_bottom;
+ std::vector<PageBreak> m_page_breaks;
Glib::RefPtr<Gtk::PrintOperation> m_print_op;
- std::string m_timestamp;
+ Glib::RefPtr<Pango::Layout> m_timestamp_footer;
};
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]