예제 #1
0
void Gtk::ArcballWidget::stext(int size, GLfloat x, GLfloat y, GLfloat z,const char *str)const{
  Glib::RefPtr<Pango::Context> widget_context = const_cast<Gtk::ArcballWidget*>(this)->get_pango_context(); 
  
  Pango::FontDescription font_desc=widget_context->get_font_description();

  Pango::Rectangle un,logical_rect;
  GLfloat text_w, text_h;
  GLfloat tangent_h;
  /* Font */
  font_desc.set_size(size * PANGO_SCALE);
  if(!ft2_context)ft2_context=Glib::wrap(pango_ft2_get_context(72,72));
  ft2_context->set_font_description(font_desc);

  /* Text layout */
  Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(ft2_context);
  layout->set_width(PANGO_SCALE * get_width());
  layout->set_alignment(Pango::ALIGN_CENTER);
  layout->set_text(str);

  /*** OpenGL BEGIN ***/
  layout->get_extents(un,logical_rect);
  text_w = PANGO_PIXELS (logical_rect.get_width());
  text_h = PANGO_PIXELS (logical_rect.get_height());

  tangent_h = 3 * tan (20 * G_PI / 180.0);
  tangent_h /= get_height();
  glRasterPos3f (x,y,z);

  /* Render text */
  gl_pango_ft2_render_layout (layout);

}
예제 #2
0
 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());
 }
예제 #3
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);
  }
예제 #4
0
void 
ViewDrawingArea::draw_buffer()
{
#ifdef DEBUG
std::cerr << "VA->val:"<<_vadj->get_value() <<" VA->upper:"<<_vadj->get_upper() << std::endl << std::flush;
#endif

	Feed *feed = AppContext::get().get_feed();
	if (feed == NULL) 
		return;

	if (AppContext::get().get_display_type() == FULL)
	{
		render_full_article();
		return;
	}

	// Dimensions of drawing area
	Gtk::Allocation allocation = get_allocation();
	const int width = allocation.get_width();
	const int height = allocation.get_height();

	// First determine start item
	Cairo::RefPtr<Cairo::Context> cr = _pixmap->create_cairo_context();

#ifdef DEBUG
	/// This code was meant to investigate the 500ms delay with pango
	/// at start of rendering.
	if (!_layout_prepared)
	{
Glib::Timer sw;
sw.start();
		Glib::RefPtr<Pango::Layout> pl = Pango::Layout::create (cr);
		const char *fonts[] = {"Sans 10", "Sans 14"};
		for (unsigned i = 0; i < sizeof(fonts)/sizeof(const char*); ++i)
		{
			Pango::FontDescription fdesc (fonts[i]);
			pl->set_font_description (fdesc);
			pl->set_width (10 * Pango::SCALE); // force line break
			pl->set_markup ("<b>Show Us Your Freaky Geek Costumes</b>\nHitting the streets in a scary, tech-themed outfit this Halloween? We want to see it. Find out how your Sergey Brin costume (or is it David Duchovny?) could be featured on Wired News. test\n test");
			Pango::Rectangle irect, lrect;
			pl->get_extents (irect, lrect);
		}
		_layout_prepared = true;
sw.stop();
unsigned long l;
sw.elapsed(l);
std::cerr << "Time spent rendering: " << l << " us" << std::endl << std::flush;
	}
#endif

	const item_list_t items = feed->get_items();
	item_list_t::const_iterator start_item;
	const int n_items = items.size();
	double y = 0.0;

	if (n_items == 0)
		start_item = items.end();
	else
	{
		// Set start_item and h
		int start = static_cast<int> (_vadj->get_value());
		double h = 0.0;
		if (_vadj->get_value() > 0 && _vadj->get_value() == _vadj->get_upper())
		{
			// This will give a blank page when pulling the handle
			// full down. While unusual, it might make sense with
			// an ever-growing newslist.
			y = 0.0;
			start_item = items.end();
		}
		else
		{
			start_item = items.begin();
			for (int i = 0; i < start; ++i)
				++start_item;
			if (start < 0)
				start = 0;

			double prop = _vadj->get_value() - start;
			if (prop > 0.0)
			{
				(*start_item)->make_display_unit();
				ItemDisplayUnit *du = (*start_item)->get_display_unit();
				du->layout (cr);
				h = du->get_height();
			}
			y = - h * prop;
#ifdef DEBUG
std::cerr << "prop:"<<prop <<" y:"<<y << std::endl << std::flush;
#endif

		}
	}

	// clip to the area indicated by the expose event so that we only redraw
	// the portion of the window that needs to be redrawn
	cr->reset_clip();
	cr->rectangle (0.0, 0.0, width, height);
	cr->clip();

	// Black on white
	cr->set_source_rgb (1.0, 1.0, 1.0);
	cr->paint();
	cr->set_source_rgb (0.0, 0.0, 0.0);

	// Render text
	item_list_t::const_iterator it = start_item;
	_top_item = *start_item;
	_topitem_y = y;
	int count = 0;
	for (; it != items.end() && y < height; ++it, ++count)
	{
		(*it)->make_display_unit();
		ItemDisplayUnit *du = (*it)->get_display_unit();
		du->render (cr, 0, y);
		y += du->get_height();
	}

	cr->show_page();

	// Scrollbar settings can now be specified
	_vadj->set_upper (n_items);
	//_vadj->set_page_size (count - 1 + );
	_vadj->set_step_increment (1);
	_vadj->set_page_increment (count);
	_vadj->changed();

}
예제 #5
0
static void
gl_pango_ft2_render_layout (Glib::RefPtr<Pango::Layout> layout)
{
  Pango::Rectangle unu,logical_rect;
  FT_Bitmap bitmap;
  GLvoid *pixels;
  guint32 *p;
  GLfloat color[4];
  guint32 rgb;
  GLfloat a;
  guint8 *row, *row_end;
  int i;

  layout->get_extents(unu,logical_rect);
  if (logical_rect.get_width() == 0 || logical_rect.get_height() == 0)
    return;

  bitmap.rows = PANGO_PIXELS (logical_rect.get_height());
  bitmap.width = PANGO_PIXELS (logical_rect.get_width());
  bitmap.pitch = bitmap.width;
  bitmap.buffer = (unsigned char*)g_malloc (bitmap.rows * bitmap.width);
  bitmap.num_grays = 256;
  bitmap.pixel_mode = ft_pixel_mode_grays;

  memset (bitmap.buffer, 0, bitmap.rows * bitmap.width);
  pango_ft2_render_layout (&bitmap, layout->gobj(),
                           PANGO_PIXELS (-logical_rect.get_x()), 0);

  pixels = g_malloc (bitmap.rows * bitmap.width * 4);
  p = (guint32 *) pixels;

  glGetFloatv (GL_CURRENT_COLOR, color);
#if !defined(GL_VERSION_1_2) && G_BYTE_ORDER == G_LITTLE_ENDIAN
  rgb =  ((guint32) (color[0] * 255.0))        |
        (((guint32) (color[1] * 255.0)) << 8)  |
        (((guint32) (color[2] * 255.0)) << 16);
#else
  rgb = (((guint32) (color[0] * 255.0)) << 24) |
        (((guint32) (color[1] * 255.0)) << 16) |
        (((guint32) (color[2] * 255.0)) << 8);
#endif
  a = color[3];

  row = bitmap.buffer + bitmap.rows * bitmap.width; /* past-the-end */
  row_end = bitmap.buffer;      /* beginning */

  if (a == 1.0)
    {
      do
        {
          row -= bitmap.width;
          for (i = 0; i < bitmap.width; i++)
#if !defined(GL_VERSION_1_2) && G_BYTE_ORDER == G_LITTLE_ENDIAN
            *p++ = rgb | (((guint32) row[i]) << 24);
#else
            *p++ = rgb | ((guint32) row[i]);
#endif
        }
      while (row != row_end);
    }
  else
    {
      do
        {
          row -= bitmap.width;
          for (i = 0; i < bitmap.width; i++)
#if !defined(GL_VERSION_1_2) && G_BYTE_ORDER == G_LITTLE_ENDIAN
            *p++ = rgb | (((guint32) (a * row[i])) << 24);
#else
            *p++ = rgb | ((guint32) (a * row[i]));
#endif
        }
      while (row != row_end);
    }

  glPixelStorei (GL_UNPACK_ALIGNMENT, 4);

  glEnable (GL_BLEND);
  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

#if !defined(GL_VERSION_1_2)
  glDrawPixels (bitmap.width, bitmap.rows,
                GL_RGBA, GL_UNSIGNED_BYTE,
                pixels);
#else
  glDrawPixels (bitmap.width, bitmap.rows,
                GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
                pixels);
#endif

  glDisable (GL_BLEND);

  g_free (bitmap.buffer);
  g_free (pixels);
}
예제 #6
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();
  }