Example #1
0
  void LinearGradient::render(Context& cairo) const
  {
    Cairo::RefPtr<Cairo::LinearGradient> gradient;
    Vector v = m_vector;
    double fx0, fy0, fx1, fy1, w, h;
    
    if ( v.has_percent() )
    {
      if ( cairo.is_flag_set(RENDER_HINT_STROKE) )
        cairo->get_stroke_extents( fx0, fy0, fx1, fy1 );
      else
        cairo->get_fill_extents( fx0, fy0, fx1, fy1 );
      w = fx1 - fx0;
      h = fy1 - fy0;
      if ( v[0].quantity_x==PERCENT ) v[0].x = fx0 + w * v[0].x;
      if ( v[0].quantity_y==PERCENT ) v[0].y = fy0 + h * v[0].y;
      if ( v[1].quantity_x==PERCENT ) v[1].x = fx0 + w * v[1].x;
      if ( v[1].quantity_y==PERCENT ) v[1].y = fy0 + h * v[1].y;
    }
    
    // Get the units using the accessor to potentially climb the parent chain
//     GradientUnits units = this->units();
//     switch ( units )
//     {
//       case GRADIENT_UNITS_NONE:
//       case GRADIENT_UNITS_OBJECT:
//           std::cout << "Gradient fill extents: " << fx0 << ", " << fy0 << ", " << fx1 << ", " << fy1 << std::endl;
//           break;
//       case GRADIENT_UNITS_USER_SPACE:
//           break;
//     }
    
    gradient = Cairo::LinearGradient::create( v[0].x, v[0].y, v[1].x, v[1].y );
    
    // Get the stops reference using the accessor to potentially climb the parent chain
    const Stops& stops = this->stops();
    Stops::const_iterator siter;
    
    for ( siter = stops.begin(); siter != stops.end(); siter++ )
    {
      cairo_pattern_add_color_stop_rgba( gradient->cobj(), siter->offset(), siter->red(), siter->green(), siter->blue(), siter->alpha() );
    }
    
    // Get the spread using the accessor to potentially climb the parent chain
    GradientSpread spread = this->spread();
    
    if ( spread == GRADIENT_SPREAD_NONE )
      cairo_pattern_set_extend( gradient->cobj(), (cairo_extend_t)GRADIENT_SPREAD_PAD );
    else
      cairo_pattern_set_extend( gradient->cobj(), (cairo_extend_t)spread );
    
    cairo->set_source(gradient);
  }
Example #2
0
bool CircuitWidget::on_expose_event(GdkEventExpose* event)
{

    (void)event; // placate compiler..
    Glib::RefPtr<Gdk::Window> window = get_window();
    if(window) {
        Gtk::Allocation allocation = get_allocation();
        const int width = allocation.get_width();
        const int height = allocation.get_height();
        double xc = width/2.0;
        double yc = height/2.0;

        Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
        circuitDrawer.renderCairo(cr->cobj());
        cr->rectangle(event->area.x, event->area.y,
                      event->area.width, event->area.height);
        cr->clip();
        cr->rectangle (0, 0, width, height);
        cr->set_source_rgb (1,1,1);
        cr->fill ();
        cr->translate (xc-ext.width/2.0-cx*scale, yc-ext.height/2.0-cy*scale);
        if (circuit) {
            rects = circuitDrawer.draw(*circuit, drawarch, drawparallel, ext, wirestart, wireend, scale, selections, ft_default, wirelabels);
            generate_layout_rects ();
        }
    }

    return true;
}
Example #3
0
void
Renderer_BBox::render_vfunc(
	const Glib::RefPtr<Gdk::Window>& drawable,
	const Gdk::Rectangle& /*expose_area*/
)
{
	assert(get_work_area());
	if(!get_work_area())
		return;

	Cairo::RefPtr<Cairo::Context> cr = drawable->create_cairo_context();

	const synfig::Vector::value_type window_startx(get_work_area()->get_window_tl()[0]);
	const synfig::Vector::value_type window_starty(get_work_area()->get_window_tl()[1]);
	const float pw(get_pw()),ph(get_ph());

	const synfig::Point curr_point(get_bbox().get_min());
	const synfig::Point drag_point(get_bbox().get_max());
	if(get_bbox().area()<10000000000000000.0 && get_bbox().area()>0.00000000000000001)
	{
		Point tl(std::min(drag_point[0],curr_point[0]),std::min(drag_point[1],curr_point[1]));
		Point br(std::max(drag_point[0],curr_point[0]),std::max(drag_point[1],curr_point[1]));

		tl[0]=(tl[0]-window_startx)/pw;
		tl[1]=(tl[1]-window_starty)/ph;
		br[0]=(br[0]-window_startx)/pw;
		br[1]=(br[1]-window_starty)/ph;
		if(tl[0]>br[0])
			swap(tl[0],br[0]);
		if(tl[1]>br[1])
			swap(tl[1],br[1]);

		cr->save();
		cr->set_line_cap(Cairo::LINE_CAP_BUTT);
		cr->set_line_join(Cairo::LINE_JOIN_MITER);

		cr->set_line_width(1.0);
		cr->set_source_rgb(1.0,1.0,1.0);

		// Operator difference was added in Cairo 1.9.4
		// It currently isn't supported by Cairomm
#if CAIRO_VERSION >= 10904
		cairo_set_operator(cr->cobj(), CAIRO_OPERATOR_DIFFERENCE);
#else
		// Fallback: set color to black
        cr->set_source_rgb(0,0,0);
#endif

		cr->rectangle(
			int(tl[0])+0.5,
			int(tl[1])+0.5,
			int(br[0]-tl[0]+1),
			int(br[1]-tl[1]+1)
		);
		cr->stroke();

		cr->restore();
	}
}
Example #4
0
bool MyPaintBox::on_expose_event(GdkEventExpose *event) {
    call_paint_func(event);
    Cairo::RefPtr<Cairo::Context> cr = Glib::wrap(event->window, true)->create_cairo_context();
    gdk_cairo_region(cr->cobj(), event->region);
    cr->clip();
    cr->set_source_rgba(0.0, 0.0, 0.0, 1-background_adj->get_value());
    cr->paint();
    foreach(sigc::bind(sigc::mem_fun(this, &MyPaintBox::propagate_expose), event));
    return true;
}
Example #5
0
bool Liveplay::window_expose_event(GdkEventExpose *event) {
    Cairo::RefPtr<Cairo::Context> cr = Glib::wrap(event->window, true)->create_cairo_context();
    Gtk::Allocation a = liveplay_canvas->get_allocation();
    Gdk::Region region(a);
    region.intersect(Glib::wrap(event->region, true));
    Gdk::Cairo::add_region_to_path(cr, region);
    cr->clip();
    cr->set_operator(Cairo::OPERATOR_SOURCE);
    cr->set_source_rgb(0,0,0);
    cr->paint();
    //gdk_cairo_set_source_window(cr->cobj(), liveplay_canvas->get_window()->gobj(), a.get_x(), a.get_y()); gtk 2.24
    gdk_cairo_set_source_pixmap(cr->cobj(), liveplay_canvas->get_window()->gobj(), a.get_x(), a.get_y());
    cr->paint_with_alpha(pow(brightness_adj->get_value(),2.2));
    return false;
}
int main() {
#ifdef CAIRO_HAS_PDF_SURFACE

	std::string filename = "image.pdf";
	int width = 600;
	int height = 400;
	Cairo::RefPtr<Cairo::PdfSurface> surface = Cairo::PdfSurface::create(
			filename, width, height);

	Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(surface);

	cr->save(); // save the state of the context
	cr->set_source_rgb(0.86, 0.85, 0.47);
	cr->paint(); // fill image with the color
	cr->restore(); // color is back to black now

	cr->save();
	// draw a border around the image
	cr->set_line_width(20.0); // make the line wider
	cr->rectangle(0.0, 0.0, cairo_image_surface_get_width(surface->cobj()),
			height);
	cr->stroke();

	cr->set_source_rgba(0.0, 0.0, 0.0, 0.7);
	// draw a circle in the center of the image
	cr->arc(width / 2.0, height / 2.0, height / 4.0, 0.0, 2.0 * M_PI);
	cr->stroke();

	// draw a diagonal line
	cr->move_to(width / 4.0, height / 4.0);
	cr->line_to(width * 3.0 / 4.0, height * 3.0 / 4.0);
	cr->stroke();
	cr->restore();

	cr->show_page();

	std::cout << "Wrote PDF file \"" << filename << "\"" << std::endl;
	return 0;

#else

	std::cout << "You must compile cairo with PDF support for this example to work."
	<< std::endl;
	return 1;

#endif
}
Example #7
0
void ImagesStorage::loadFrenchDeck(RsvgHandle* rsvgCards)
{
	RsvgDimensionData dim;
	rsvg_handle_get_dimensions(rsvgCards, &dim);
	Cairo::RefPtr<Cairo::ImageSurface> allImages = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, dim.width, dim.height);
	Cairo::RefPtr<Cairo::Context> cardsImagesDrawer = Cairo::Context::create( allImages );
	cardsImagesDrawer->set_source_rgb(1, 1, 1);
	rsvg_handle_render_cairo(rsvgCards, cardsImagesDrawer->cobj());

	for( Preference::SuitForwardIterator itSuit; itSuit.HasNext(); itSuit.Next() ) { 
		for( Preference::RankForwardIterator itRank; itRank.HasNext(); itRank.Next() ) { 
			cardsImages[FrenchDeckName][Preference::CreateCard(itSuit.GetObject(), itRank.GetObject())] 
				= loadFrenchCard( allImages, Preference::CreateCard(itSuit.GetObject(), itRank.GetObject()) );
		}
	}
	cardsImages[FrenchDeckName][Preference::UnknownCard] = loadFrenchCard(allImages, Preference::UnknownCard);
}
//------------------------------------------------------------------------------
void WBPrintOperation::on_draw_page(const Glib::RefPtr<Gtk::PrintContext>& ctx, int page_nr)
{
  Cairo::RefPtr<Cairo::Context> context = ctx->get_cairo_context();
  mdc::CairoCtx cairoctx(context->cobj());

  // scaling to transform from cairo coordinates to Cocoa coordinates
  double pwidth, pheight;
  _printer->get_paper_size(pwidth, pheight);
  float xscale= ctx->get_width() / pwidth;
  float yscale= ctx->get_height() / pheight;

  // scale has to be set here, ctx->get_width() returns some different value in on_begin_print()
  _printer->set_scale(xscale, yscale);

  _printer->render_page(&cairoctx, page_nr % _xpages, page_nr / _xpages);
 
}
Example #9
0
void RegionChooser::draw_digit(const Cairo::RefPtr<Cairo::Context>& cr,
                               int key) {
    const int h = KEYBOARD_HEIGHT;
    const int w = get_width() - 1;
    Glib::RefPtr<Pango::Layout> layout =
        Pango::Layout::create(get_pango_context());
    char buf[30];
    sprintf(buf, "<span size=\"8000\">%d</span>", key / 12 - 1);
    layout->set_markup(buf);
    Pango::Rectangle rectangle = layout->get_logical_extents();
    double text_w = double(rectangle.get_width()) / Pango::SCALE;
    double text_h = double(rectangle.get_height()) / Pango::SCALE;
    double x = w * (key + 0.75) / 128.0;
    Gdk::Cairo::set_source_rgba(cr, black);
    cr->move_to(int(x - text_w / 2 + 1), int(h1 + h - text_h + 0.5));
#if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
    pango_cairo_show_layout(cr->cobj(), layout->gobj());
#else
    layout->show_in_cairo_context(cr);
#endif
}
Example #10
0
void GerberImporter::render(Cairo::RefPtr<Cairo::ImageSurface> surface, const guint dpi, const double min_x, const double min_y) throw (import_exception)
{
    gerbv_render_info_t render_info;

    render_info.scaleFactorX = dpi;
    render_info.scaleFactorY = dpi;
    render_info.lowerLeftX = min_x;
    render_info.lowerLeftY = min_y;
    render_info.displayWidth = surface->get_width();
    render_info.displayHeight = surface->get_height();
    render_info.renderType = GERBV_RENDER_TYPE_CAIRO_NORMAL;

    GdkColor color_saturated_white = { 0xFFFFFFFF, 0xFFFF, 0xFFFF, 0xFFFF };
    project->file[0]->color = color_saturated_white;

    cairo_t* cr = cairo_create(surface->cobj());
    gerbv_render_layer_to_cairo_target(cr, project->file[0], &render_info);

    cairo_destroy(cr);

    /// @todo check wheter importing was successful
}
Example #11
0
 void Fader(Cairo::RefPtr<Cairo::Context> cr, float x, float y, float value, float rms, float falloff)
 {
   // draw invisible from the last widget
   cr->set_source_rgba(0,0,0,0);
   cr->move_to( x, y );
   cr->stroke();
   
   x = x + 4; // global move widget relative to positioning
   
   // Create the linear gradient diagonal
   //Cairo::RefPtr< Cairo::LinearGradient > linGrad = Cairo::LinearGradient::create (x, y, 100, 100);
   
   // Set grandient colors
   //linGrad->add_color_stop_rgb (0, 10 / 255.f, 246 / 255.f, 98 / 255.f );
   //linGrad->add_color_stop_rgb (1, 192 / 255.f, 246 / 255.f, 98 / 255.f );
   
   // Draw rectangle and fill with gradient
   cairo_pattern_t *pat;
   pat = cairo_pattern_create_linear (0.0, 0.0,  0.0, 400.0);
   cairo_pattern_add_color_stop_rgb(pat, 0,   0 / 255.f, 153 / 255.f, 255 / 255.f );
   cairo_pattern_add_color_stop_rgb(pat, 1,  26 / 255.f,  26 / 255.f,  26 / 255.f );
   cr->rectangle   (x, y, 12, 94);
   cairo_set_source(cr->cobj(), pat);
   cairo_fill      (cr->cobj());
   cairo_pattern_destroy (pat);
   
   // red area on top of fader graphic
   cr->rectangle ( x, y, 12, 25 );
   setColour(cr, COLOUR_ORANGE_1 );
   cr->fill();
   
   float tmpRms = (1-rms);
   
   //std::cout << "Falloff: " << falloff << " RMS " << rms << std::endl;
   
   if ( falloff > rms )
   {
     //std::cout << "Falloff > RMS" << std::endl;
     tmpRms = (1-falloff);
     falloff -= 0.1;
   }
   else
   {
     falloff = rms;
   }
   
   //std::cout << " tmpRms " << tmpRms << "  drawPx:  " << tmpRms * 94 << std::endl;
   
   cr->rectangle ( x, y, 12, 94 * tmpRms );
   setColour(cr, COLOUR_GREY_2 );
   cr->fill();
   
   // draw fader  <|
   float playheadX = x + 12;
   float playheadY = y + (92 * ( 1.f - value));
   
   setColour(cr, COLOUR_ORANGE_1 );
   cr->set_line_width(0.8);
   cr->move_to( playheadX, playheadY );
   cr->line_to( playheadX + 10, playheadY + 5.5 );
   cr->line_to( playheadX + 10, playheadY - 5.5 );
   cr->close_path();
   cr->fill_preserve();
   
   // draw fader |>
   cr->move_to( x, playheadY );
   cr->line_to( x - 10, playheadY + 5.5 );
   cr->line_to( x - 10, playheadY - 5.5 );
   cr->close_path();
   cr->fill_preserve();
   cr->stroke();
   
   // line between fader markers |> --- <|
   setColour(cr, COLOUR_GREY_4 );
   cr->set_line_width(2);
   cr->move_to( x, playheadY );
   cr->line_to( x + 12, playheadY );
   cr->stroke();
 }
Example #12
0
bool studio::Widget_Preview::redraw(GdkEventExpose */*heh*/)
{
	//And render the drawing area
	Glib::RefPtr<Gdk::Pixbuf> pxnew, px = currentbuf;
	cairo_surface_t* cs;
	bool use_cairo= preview->get_use_cairo();
	if(use_cairo)
	{
		if(current_surface)
			cs=cairo_surface_reference(current_surface);
		else
			return true;
	}
	
	int dw = draw_area.get_width();
	int dh = draw_area.get_height();
	
	if(use_cairo && !cs)
		return true;
	else if(!use_cairo && !px)
		return true;
	//made not need this line
	//if ( draw_area.get_height() == 0 || px->get_height() == 0 || px->get_width() == 0)
	//	return true;

	//figure out the scaling factors...
	float sx, sy;
	float q = 1 / preview->get_zoom();
	int nw, nh;
	int w,h;
	
	// grab the source dimensions
	if(use_cairo)
	{
		w=cairo_image_surface_get_width(cs);
		h=cairo_image_surface_get_height(cs);
	}
	else
	{
		w=px->get_width();
		h=px->get_height();
	}

	Gtk::Entry* entry = zoom_preview.get_entry();
	String str(entry->get_text());
	Glib::ustring text = str;
	locale_from_utf8 (text);
	const char *c = text.c_str();

	if (text == _("Fit") || text == "fit")
	{
		sx = dw / (float)w;
		sy = dh/ (float)h;

		//synfig::info("widget_preview redraw: now to scale the bitmap: %.3f x %.3f",sx,sy);

		//round to smallest scale (fit entire thing in window without distortion)
		if(sx > sy) sx = sy;

		//cleanup previous size request
		draw_area.set_size_request();
	}

	//limit zoom level from 0.01 to 10 times
	else if (atof(c) > 1000)
	{
		sx = sy = 10 * q;
	}

	else if (atof(c) <= 0 )
	{
		sx = sy = 0 ;
		draw_area.set_size_request(0, 0);
	}

	else sx = sy = atof(c) / 100 * q;

	//scale to a new pixmap and then copy over to the window
	nw = (int)(w * sx);
	nh = (int)(h * sx);

	if(nw == 0 || nh == 0)return true;

	if(!use_cairo)
		pxnew = px->scale_simple(nw, nh, Gdk::INTERP_NEAREST);

	//except "Fit" or "fit", we need to set size request for scrolled window
	if (text != _("Fit") && text != "fit")
	{
		draw_area.set_size_request(nw, nh);
		dw = draw_area.get_width();
		dh = draw_area.get_height();
	}

	//synfig::info("Now to draw to the window...");
	//copy to window
	Glib::RefPtr<Gdk::Window>	wind = draw_area.get_window();
	Cairo::RefPtr<Cairo::Context> cr = wind->create_cairo_context();

	if(!wind) synfig::warning("The destination window is broken...");

	if(!use_cairo)
	{
		/* Options for drawing...
			1) store with alpha, then clear and render with alpha every frame
				- more time consuming
				+ more expandable
			2) store with just pixel info
				- less expandable
				+ faster
				+ better memory footprint
		*/
		//px->composite(const Glib::RefPtr<Gdk::Pixbuf>& dest, int dest_x, int dest_y, int dest_width, int dest_height, double offset_x, double offset_y, double scale_x, double scale_y, InterpType interp_type, int overall_alpha) const

		cr->save();
		Gdk::Cairo::set_source_pixbuf(
			cr, //cairo context
			pxnew, //pixbuf
			//coordinates to place center of the preview window
			(dw - nw) / 2, (dh - nh) / 2
			);
		cr->paint();
		cr->restore();
	}
	else
	{
		cr->save();
		cr->scale(sx, sx);
		cairo_set_source_surface(cr->cobj(), cs, (dw - nw)/(2*sx), (dh - nh)/(2*sx));
		cairo_pattern_set_filter(cairo_get_source(cr->cobj()), CAIRO_FILTER_NEAREST);
		cairo_surface_destroy(cs);
		cr->paint();
		cr->restore();
	}

	//synfig::warning("Refresh the draw area");
	//make sure the widget refreshes

	return false;
}
Example #13
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();
  }
bool studio::Widget_NavView::on_drawto_draw(const Cairo::RefPtr<Cairo::Context> &cr)
{
#ifdef SINGLE_THREADED
	// don't redraw if the previous redraw is still running single-threaded
	// or we end up destroying the renderer that's rendering it
	if (App::single_threaded && renderer && renderer->updating)
		return false;
#endif

	//draw the good stuff
	on_start_render();

	//if we've got a preview etc. display it...
	if(get_canvas_view())
	{
		//axis transform from units to pixel coords
		float xaxis = 0, yaxis = 0;

		int canvw = get_canvas_view()->get_canvas()->rend_desc().get_w();
		int w, h;
	
		float pw = get_canvas_view()->get_canvas()->rend_desc().get_pw();
		float ph = get_canvas_view()->get_canvas()->rend_desc().get_ph();
		if(prev && !studio::App::navigator_uses_cairo)
		{
			w = prev->get_width();
			h = prev->get_height();
		}
		if(studio::App::navigator_uses_cairo)
		{
			w=cairo_image_surface_get_width(cairo_surface);
			h=cairo_image_surface_get_height(cairo_surface);
		}

		//scale up/down to the nearest pixel ratio...
		//and center in center
		float offx=0, offy=0;

		float sx, sy;
		int nw,nh;

		sx = drawto.get_width() / (float)w;
		sy = drawto.get_height() / (float)h;

		//round to smallest scale (fit entire thing in window without distortion)
		if(sx > sy) sx = sy;
		//else sy = sx;

		//scaling and stuff
		// the point to navpixel space conversion should be:
		//		(navpixels / canvpixels) * (canvpixels / canvsize)
		//	or (navpixels / prevpixels) * (prevpixels / navpixels)
		xaxis = sx * w / (float)canvw;
		yaxis = xaxis/ph;
		xaxis /= pw;

		//scale to a new pixmap and then copy over to the window
		nw = (int)(w*sx);
		nh = (int)(h*sx);

		//must now center to be cool
		offx = (drawto.get_width() - nw)/2;
		offy = (drawto.get_height() - nh)/2;

		//trivial escape
		if(nw == 0 || nh == 0)return true;

		//draw to drawing area
		if(prev && !studio::App::navigator_uses_cairo)
		{
			Glib::RefPtr<Gdk::Pixbuf> scalepx = prev->scale_simple(nw,nh,Gdk::INTERP_NEAREST);

			cr->save();

			//synfig::warning("Nav: Drawing scaled bitmap");
			Gdk::Cairo::set_source_pixbuf(
				cr, //cairo context
				scalepx, //pixbuf
				(int)offx, (int)offy //coordinates to place upper left corner of pixbuf
				);
			cr->paint();
			cr->restore();
		}
		if(studio::App::navigator_uses_cairo)
		{
			cr->save();
			cr->scale(sx, sx);
			cairo_set_source_surface(cr->cobj(), cairo_surface, offx/sx, offy/sx);
			cairo_pattern_set_filter(cairo_get_source(cr->cobj()), CAIRO_FILTER_NEAREST);
			cr->paint();
			cr->restore();	
		}
		cr->save();
		//draw fancy red rectangle around focus point
		const Point &wtl = get_canvas_view()->work_area->get_window_tl(),
					&wbr = get_canvas_view()->work_area->get_window_br();

		//it must be clamped to the drawing area though
		int l=0,rw=0,t=0,rh=0;
		const Point fp = -get_canvas_view()->work_area->get_focus_point();

		//get focus point in normal space
		rw = (int)(abs((wtl[0]-wbr[0])*xaxis));
		rh = (int)(abs((wtl[1]-wbr[1])*yaxis));

		//transform into pixel space
		l = (int)(drawto.get_width()/2 + fp[0]*xaxis - rw/2);
		t = (int)(drawto.get_height()/2 + fp[1]*yaxis - rh/2);

		//coord system:
		// tl : (offx,offy)
		// axis multipliers = xaxis,yaxis

		cr->set_line_width(2.0);
		cr->set_line_cap(Cairo::LINE_CAP_BUTT);
		cr->set_line_join(Cairo::LINE_JOIN_MITER);
		cr->set_antialias(Cairo::ANTIALIAS_NONE);
		// Visually distinguish when using Cairo on Navigator or not.
		if(!studio::App::navigator_uses_cairo)
			cr->set_source_rgb(1,0,0);
		else
			cr->set_source_rgb(0,1,0);
		cr->rectangle(l,t,rw,rh);
		cr->stroke();

		cr->restore();
	}
	return false; //draw everything else too
}
Example #15
0
static void
draw_page (GtkPrintOperation */*operation*/,
           GtkPrintContext   *context,
           gint               /*page_nr*/,
           gpointer           user_data)
{
    struct workaround_gtkmm *junk = (struct workaround_gtkmm*)user_data;
    //printf("%s %d\n",__FUNCTION__, page_nr);

    if (junk->_tab->as_bitmap()) {
        // Render as exported PNG
        gdouble width = sp_document_width(junk->_doc);
        gdouble height = sp_document_height(junk->_doc);
        gdouble dpi = junk->_tab->bitmap_dpi();
        std::string tmp_png;
        std::string tmp_base = "inkscape-print-png-XXXXXX";

        int tmp_fd;
        if ( (tmp_fd = Inkscape::IO::file_open_tmp (tmp_png, tmp_base)) >= 0) {
            close(tmp_fd);

            guint32 bgcolor = 0x00000000;
            Inkscape::XML::Node *nv = sp_repr_lookup_name (junk->_doc->rroot, "sodipodi:namedview");
            if (nv && nv->attribute("pagecolor"))
                bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00);
            if (nv && nv->attribute("inkscape:pageopacity"))
                bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0));

            sp_export_png_file(junk->_doc, tmp_png.c_str(), 0.0, 0.0,
                width, height,
                (unsigned long)(width * dpi / PX_PER_IN),
                (unsigned long)(height * dpi / PX_PER_IN),
                dpi, dpi, bgcolor, NULL, NULL, true, NULL);

            // This doesn't seem to work:
            //context->set_cairo_context ( Cairo::Context::create (Cairo::ImageSurface::create_from_png (tmp_png) ), dpi, dpi );
            //
            // so we'll use a surface pattern blat instead...
            //
            // but the C++ interface isn't implemented in cairomm:
            //context->get_cairo_context ()->set_source_surface(Cairo::ImageSurface::create_from_png (tmp_png) );
            //
            // so do it in C:
            {
                Cairo::RefPtr<Cairo::ImageSurface> png = Cairo::ImageSurface::create_from_png (tmp_png);
                cairo_t *cr = gtk_print_context_get_cairo_context (context);
		cairo_matrix_t m;
		cairo_get_matrix(cr, &m);
		cairo_scale(cr, PT_PER_IN / dpi, PT_PER_IN / dpi);
                // FIXME: why is the origin offset??
                cairo_set_source_surface(cr, png->cobj(), -16.0, -16.0);
		cairo_paint(cr);
		cairo_set_matrix(cr, &m);
            }

            // Clean up
            unlink (tmp_png.c_str());
        }
        else {
            g_warning(_("Could not open temporary PNG for bitmap printing"));
        }
    }
    else {
        // Render as vectors
        Inkscape::Extension::Internal::CairoRenderer renderer;
        Inkscape::Extension::Internal::CairoRenderContext *ctx = renderer.createContext();

        // ctx->setPSLevel(CAIRO_PS_LEVEL_3);
        ctx->setTextToPath(false);
        ctx->setFilterToBitmap(true);
        ctx->setBitmapResolution(72);

        cairo_t *cr = gtk_print_context_get_cairo_context (context);
        cairo_surface_t *surface = cairo_get_target(cr);


/**
	Call cairo_win32_printing_surface directly as a workaround until GTK uses this call.
	When GTK uses cairo_win32_printing_surface this automatically reverts.
*/
#ifdef WIN32
        if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_WIN32) {
        HDC dc = cairo_win32_surface_get_dc (surface);
        surface = _cairo_win32_printing_surface_create (dc);
        }
#endif

        bool ret = ctx->setSurfaceTarget (surface, true);        if (ret) {
            ret = renderer.setupDocument (ctx, junk->_doc, TRUE, NULL);
            if (ret) {
                renderer.renderItem(ctx, junk->_base);
                ret = ctx->finish();
            }
            else {
                g_warning(_("Could not set up Document"));
            }
        }
        else {
            g_warning(_("Failed to set CairoRenderContext"));
        }

        // Clean up
        renderer.destroyContext(ctx);
    }

}
Example #16
0
	virtual void write(const Cairo::RefPtr<Cairo::Surface>& surface)
	{
		surface->flush();
		//surface->write_to_png_stream(sigc::mem_fun(*this, &Renderer::PNGWriter::cairoWriter));
		cairo_surface_write_to_png_stream(surface->cobj(), cairoWriter, (void*) buffer.get());
	}
Example #17
0
void
Renderer_Ducks::render_vfunc(
	const Glib::RefPtr<Gdk::Drawable>& drawable,
	const Gdk::Rectangle& /*expose_area*/
)
{
	assert(get_work_area());
	if(!get_work_area())
		return;

	const synfig::Point window_start(get_work_area()->get_window_tl());
	const float pw(get_pw()),ph(get_ph());

	const bool solid_lines(get_work_area()->solid_lines);
	bool alternative = get_work_area()->get_alternative_mode();

	const std::list<etl::handle<Duckmatic::Bezier> >& bezier_list(get_work_area()->bezier_list());
	const std::list<handle<Duckmatic::Stroke> >& stroke_list(get_work_area()->stroke_list());
	Glib::RefPtr<Pango::Layout> layout(Pango::Layout::create(get_work_area()->get_pango_context()));

	Cairo::RefPtr<Cairo::Context> cr = drawable->create_cairo_context();

	cr->save();
	cr->set_line_cap(Cairo::LINE_CAP_BUTT);
	cr->set_line_join(Cairo::LINE_JOIN_MITER);

	// Render the strokes
	for(std::list<handle<Duckmatic::Stroke> >::const_iterator iter=stroke_list.begin();iter!=stroke_list.end();++iter)
	{
		cr->save();

		std::list<synfig::Point>::iterator iter2;
		for(iter2=(*iter)->stroke_data->begin();iter2!=(*iter)->stroke_data->end();++iter2)
		{
			cr->line_to(
				((*iter2)[0]-window_start[0])/pw,
				((*iter2)[1]-window_start[1])/ph
				);
		}

		cr->set_line_width(1.0);
		cr->set_source_rgb(
			colorconv_synfig2gdk((*iter)->color).get_red_p(),
			colorconv_synfig2gdk((*iter)->color).get_green_p(),
			colorconv_synfig2gdk((*iter)->color).get_blue_p()
			);
		cr->stroke();

		cr->restore();
	}



	// Render the beziers
	for(std::list<handle<Duckmatic::Bezier> >::const_iterator iter=bezier_list.begin();iter!=bezier_list.end();++iter)
	{
		Point p1((*iter)->p1->get_trans_point()-window_start);
		Point p2((*iter)->p2->get_trans_point()-window_start);
		Point c1((*iter)->c1->get_trans_point()-window_start);
		Point c2((*iter)->c2->get_trans_point()-window_start);
		p1[0]/=pw;p1[1]/=ph;
		p2[0]/=pw;p2[1]/=ph;
		c1[0]/=pw;c1[1]/=ph;
		c2[0]/=pw;c2[1]/=ph;

		cr->save();

		cr->move_to(p1[0], p1[1]);
		cr->curve_to(c1[0], c1[1], c2[0], c2[1], p2[0], p2[1]);

/*
		if (solid_lines)
		{
			cr->set_source_rgb(0,0,0); // DUCK_COLOR_BEZIER_1
			cr->set_line_width(3.0);
			cr->stroke_preserve();

			cr->set_source_rgb(175.0/255.0,175.0/255.0,175.0/255.0); //DUCK_COLOR_BEZIER_2
			cr->set_line_width(1.0);
			cr->stroke();
		}
		else
*/
		{
			//Solid line background
			cr->set_line_width(1.0);
			cr->set_source_rgb(0,0,0); // DUCK_COLOR_BEZIER_1
			cr->stroke_preserve();

			//Dashes
			cr->set_source_rgb(175.0/255.0,175.0/255.0,175.0/255.0); //DUCK_COLOR_BEZIER_2
			std::valarray<double> dashes(2);
			dashes[0]=5.0;
			dashes[1]=5.0;
			cr->set_dash(dashes, 0);
			cr->stroke();
		}
		cr->restore();
	}


	const DuckList duck_list(get_work_area()->get_duck_list());

	std::list<ScreenDuck> screen_duck_list;
	const float radius((abs(pw)+abs(ph))*4);

	etl::handle<Duck> hover_duck(get_work_area()->find_duck(get_work_area()->get_cursor_pos(),radius, get_work_area()->get_type_mask()));

	// Render the ducks
	for(std::list<handle<Duck> >::const_iterator iter=duck_list.begin();iter!=duck_list.end();++iter)
	{

		// If this type of duck has been masked, then skip it
		if(!(*iter)->get_type() || (!(get_work_area()->get_type_mask() & (*iter)->get_type())))
			continue;

		Point sub_trans_point((*iter)->get_sub_trans_point());
		Point sub_trans_origin((*iter)->get_sub_trans_origin());

		if (App::restrict_radius_ducks &&
			(*iter)->is_radius())
		{
			if (sub_trans_point[0] < sub_trans_origin[0])
				sub_trans_point[0] = sub_trans_origin[0];
			if (sub_trans_point[1] < sub_trans_origin[1])
				sub_trans_point[1] = sub_trans_origin[1];
		}

		Point point((*iter)->get_transform_stack().perform(sub_trans_point));
		Point origin((*iter)->get_transform_stack().perform(sub_trans_origin));

		point[0]=(point[0]-window_start[0])/pw;
		point[1]=(point[1]-window_start[1])/ph;

		bool has_connect = (*iter)->get_tangent()
		                || ((*iter)->get_type()&( Duck::TYPE_ANGLE
		                					   | Duck::TYPE_SKEW
		        		                       | Duck::TYPE_SCALE_X
		        		                       | Duck::TYPE_SCALE_Y ));
		if((*iter)->get_connect_duck())
		{
			has_connect=true;
			origin=(*iter)->get_connect_duck()->get_trans_point();
		}

		origin[0]=(origin[0]-window_start[0])/pw;
		origin[1]=(origin[1]-window_start[1])/ph;

		bool selected(get_work_area()->duck_is_selected(*iter));
		bool hover(*iter==hover_duck || (*iter)->get_hover());

		if(get_work_area()->get_selected_value_node())
		{
			synfigapp::ValueDesc value_desc((*iter)->get_value_desc());
			if (value_desc.is_valid() &&
				((value_desc.is_value_node()		&& get_work_area()->get_selected_value_node() == value_desc.get_value_node()) ||
				 (value_desc.parent_is_value_node()	&& get_work_area()->get_selected_value_node() == value_desc.get_parent_value_node())))
			{
				cr->save();

				cr->rectangle(
					round_to_int(point[0]-5),
					round_to_int(point[1]-5),
					10,
					10
					);

				cr->set_line_width(2.0);
				cr->set_source_rgb(1, 0, 0); //DUCK_COLOR_SELECTED
				cr->stroke();

				cr->restore();
			}

		}

		if((*iter)->get_box_duck())
		{
			Point boxpoint((*iter)->get_box_duck()->get_trans_point());
			boxpoint[0]=(boxpoint[0]-window_start[0])/pw;
			boxpoint[1]=(boxpoint[1]-window_start[1])/ph;
			Point tl(min(point[0],boxpoint[0]),min(point[1],boxpoint[1]));

			cr->save();

			cr->rectangle(
				round_to_int(tl[0]),
				round_to_int(tl[1]),
				round_to_int(abs(boxpoint[0]-point[0])),
				round_to_int(abs(boxpoint[1]-point[1]))
				);

			// Solid white box
			cr->set_line_width(1.0);
			cr->set_source_rgb(1,1,1); //DUCK_COLOR_BOX_1
			cr->stroke_preserve();

			// Dashes
			cr->set_source_rgb(0,0,0); //DUCK_COLOR_BOX_2
			std::valarray<double> dashes(2);
			dashes[0]=5.0;
			dashes[1]=5.0;
			cr->set_dash(dashes, 0);
			cr->stroke();

			cr->restore();
		}

		if((*iter)->is_axes_tracks())
		{
			Point pos((*iter)->get_point());
			Point points[] = {
				(*iter)->get_sub_trans_origin(),
				(*iter)->get_sub_trans_point(Point(pos[0],0)),
				(*iter)->get_sub_trans_point(),
				(*iter)->get_sub_trans_point(Point(0,pos[1])),
				(*iter)->get_sub_trans_origin()
			};

			cr->save();

			for(int i = 0; i < 5; i++) {
				Point p((*iter)->get_transform_stack().perform(points[i]));
				Real x = (p[0]-window_start[0])/pw;
				Real y = (p[1]-window_start[1])/ph;
				if (i == 0) cr->move_to(x, y); else cr->line_to(x, y);
			}

			// Solid white box
			cr->set_line_width(1.0);
			cr->set_source_rgb(1,1,1); //DUCK_COLOR_BOX_1
			cr->stroke_preserve();

			// Dashes
			cr->set_source_rgb(0,0,0); //DUCK_COLOR_BOX_2
			std::valarray<double> dashes(2);
			dashes[0]=5.0;
			dashes[1]=5.0;
			cr->set_dash(dashes, 0);
			cr->stroke();

			cr->restore();
		}

		ScreenDuck screen_duck;
		screen_duck.pos=point;
		screen_duck.selected=selected;
		screen_duck.hover=hover;
		screen_duck.has_alternative=(*iter)->get_alternative_value_desc().is_valid();

		if(!(*iter)->get_editable(alternative))
			screen_duck.color=(DUCK_COLOR_NOT_EDITABLE);
		else if((*iter)->get_tangent())
			if(0){
				// Tangents have different color depending on the split state (disabled for now)
				//
				// Check if we can reach the canvas and set the time to
				// evaluate the split value accordingly
				synfig::Canvas::Handle canvas_h(get_work_area()->get_canvas());
				synfig::Time time(canvas_h?canvas_h->get_time():synfig::Time(0));
				// Retrieve the split value of the bline point.
				const synfigapp::ValueDesc& v_d((*iter)->get_value_desc());
				synfig::LinkableValueNode::Handle parent;
				if(v_d.parent_is_linkable_value_node())
				{
					parent=v_d.get_parent_value_node();
					bool split;
					synfig::ValueNode::Handle child(parent->get_link("split"));
					if(synfig::ValueNode_Animated::Handle::cast_dynamic(child))
					{
						synfig::ValueNode_Animated::Handle animated_child(synfig::ValueNode_Animated::Handle::cast_dynamic(child));
						split=animated_child->new_waypoint_at_time(time).get_value(time).get(split);
					}
					else if(synfig::ValueNode_Const::Handle::cast_dynamic(child))
					{
						synfig::ValueNode_Const::Handle const_child(synfig::ValueNode_Const::Handle::cast_dynamic(child));
						split=(const_child->get_value()).get(split);
					}
					screen_duck.color=(split? DUCK_COLOR_TANGENT_2 : DUCK_COLOR_TANGENT_1);
				}
				else
					screen_duck.color=DUCK_COLOR_TANGENT_1;
			} else {
				// All tangents are the same color
				screen_duck.color=((*iter)->get_scalar()<0 ? DUCK_COLOR_TANGENT_1 : DUCK_COLOR_TANGENT_1);
			}
		else if((*iter)->get_type()&Duck::TYPE_VERTEX)
			screen_duck.color=DUCK_COLOR_VERTEX;
		else if((*iter)->get_type()&Duck::TYPE_RADIUS)
			screen_duck.color=((*iter)->is_linear() ? DUCK_COLOR_LINEAR : DUCK_COLOR_RADIUS);
		else if((*iter)->get_type()&Duck::TYPE_WIDTH)
			screen_duck.color=DUCK_COLOR_WIDTH;
		else if((*iter)->get_type()&Duck::TYPE_ANGLE)
			screen_duck.color=(DUCK_COLOR_ANGLE);
		else if((*iter)->get_type()&Duck::TYPE_WIDTHPOINT_POSITION)
			screen_duck.color=(DUCK_COLOR_WIDTHPOINT_POSITION);
		else
			screen_duck.color=DUCK_COLOR_OTHER;

		screen_duck_list.push_front(screen_duck);

		if(has_connect)
		{
			cr->save();

			cr->move_to(origin[0], origin[1]);
			cr->line_to(point[0], point[1]);

			if(solid_lines)
			{
				// Outside
				cr->set_line_width(3.0);
				cr->set_source_rgb(0,0,0); //DUCK_COLOR_CONNECT_OUTSIDE
				cr->stroke_preserve();

				// Inside
				cr->set_line_width(1.0);
				cr->set_source_rgb(159.0/255,239.0/255,239.0/255); //DUCK_COLOR_CONNECT_INSIDE
				cr->stroke();
			}
			else
			{
				// White background
				cr->set_line_width(1.0);
				cr->set_source_rgb(0,0,0); //DUCK_COLOR_CONNECT_OUTSIDE
				cr->stroke_preserve();

				// Dashes on top of the background
				cr->set_source_rgb(159.0/255,239.0/255,239.0/255); //DUCK_COLOR_CONNECT_INSIDE
				std::valarray<double> dashes(2);
				dashes[0]=5.0;
				dashes[1]=5.0;
				cr->set_dash(dashes, 0);
				cr->stroke();
			}

			cr->restore();
		}

		if((*iter)->is_radius())
		{
			if (!(*iter)->is_linear())
			{
				const Real mag((point-origin).mag());

				cr->save();

				cr->arc(
					origin[0],
					origin[1],
					mag,
					0,
					M_PI*2
					);

				if(solid_lines)
				{
					cr->set_line_width(3.0);
					cr->set_source_rgb(0,0,0);
					cr->stroke_preserve();

					cr->set_source_rgb(175.0/255.0,175.0/255.0,175.0/255.0);
				}
				else
				{
					cr->set_source_rgb(1.0,1.0,1.0);

					// Operator difference was added in Cairo 1.9.4
					// It currently isn't supported by Cairomm
	#if CAIRO_VERSION >= 10904
					cairo_set_operator(cr->cobj(), CAIRO_OPERATOR_DIFFERENCE);
	#else
					// Fallback: set color to black
					cr->set_source_rgb(0,0,0);
	#endif

				}

				cr->set_line_width(1.0);
				cr->stroke();

				cr->restore();
			}

			if(hover)
			{
				Real mag;
				if ((*iter)->get_exponential()){
					mag = log((*iter)->get_point().mag());
				}
				else if (App::restrict_radius_ducks)
				{
					Point sub_trans_point((*iter)->get_sub_trans_point());
					Point sub_trans_origin((*iter)->get_sub_trans_origin());

					if (sub_trans_point[0] < sub_trans_origin[0])
						sub_trans_point[0] = sub_trans_origin[0];
					if (sub_trans_point[1] < sub_trans_origin[1])
						sub_trans_point[1] = sub_trans_origin[1];

					Point point((*iter)->get_transform_stack().perform(sub_trans_point));
					Point origin((*iter)->get_transform_stack().perform(sub_trans_origin));

					mag = (point-origin).mag();
				}
				else
					mag = ((*iter)->get_trans_point()-(*iter)->get_trans_origin()).mag();

				Distance real_mag(mag, Distance::SYSTEM_UNITS);
				if (!(*iter)->get_exponential())
					real_mag.convert(App::distance_system,get_work_area()->get_rend_desc());

				cr->save();

				layout->set_text(real_mag.get_string());

				cr->set_source_rgb(0,0,0); // DUCK_COLOR_WIDTH_TEXT_1
				cr->move_to(
					point[0]+1+6,
					point[1]+1-8
					);
				layout->show_in_cairo_context(cr);
				cr->stroke();


				cr->set_source_rgb(1,0,1); // DUCK_COLOR_WIDTH_TEXT_2
				cr->move_to(
					point[0]+6,
					point[1]-8
					);
				layout->show_in_cairo_context(cr);
				cr->stroke();

				cr->restore();
			}

		}

		if((*iter)->get_type()&&Duck::TYPE_WIDTHPOINT_POSITION)
		{
			if(hover)
			{
				synfig::Canvas::Handle canvas_h(get_work_area()->get_canvas());
				synfig::Time time(canvas_h?canvas_h->get_time():synfig::Time(0));
				synfigapp::ValueDesc value_desc((*iter)->get_value_desc());
				synfig::ValueNode_WPList::Handle wplist=NULL;
				ValueNode_Composite::Handle wpoint_composite=NULL;
				Real radius=0.0;
				Real new_value;
				Point p(sub_trans_point-sub_trans_origin);
				if(value_desc.parent_is_value_node())
					wplist=synfig::ValueNode_WPList::Handle::cast_dynamic(value_desc.get_parent_value_node());
				if(wplist)
				{
					bool wplistloop(wplist->get_loop());
					synfig::ValueNode_BLine::Handle bline(synfig::ValueNode_BLine::Handle::cast_dynamic(wplist->get_bline()));
					wpoint_composite=ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node());
					if(bline && wpoint_composite)
					{
						bool blineloop(bline->get_loop());
						bool homogeneous=false;
						// Retrieve the homogeneous layer parameter
						std::set<Node*>::iterator iter;
						for(iter=wplist->parent_set.begin();iter!=wplist->parent_set.end();++iter)
							{
								Layer::Handle layer;
								layer=Layer::Handle::cast_dynamic(*iter);
								if(layer && layer->get_name() == "advanced_outline")
								{
									homogeneous=layer->get_param("homogeneous").get(bool());
									break;
								}
							}
						WidthPoint wp((*wpoint_composite)(time).get(WidthPoint()));
						if(wplistloop)
						{
							// The wplist is looped. This may require a position parameter
							// outside the range of 0-1, so make sure that the position doesn't
							// change drastically.
							// First normalise the current position
							Real value_old(wp.get_norm_position(wplistloop));
							Real value_old_b(wp.get_bound_position(wplistloop));
							// If it is homogeneous then convert it to standard
							value_old=homogeneous?hom_to_std((*bline)(time), value_old, wplistloop, blineloop):value_old;
							// grab a new position given by duck's position on the bline
							Real value_new = synfig::find_closest_point((*bline)(time), p , radius, blineloop);
							// calculate the difference between old and new positions
							Real difference = fmod( fmod(value_new - value_old, 1.0) + 1.0 , 1.0);
							//fmod is called twice to avoid negative values
							if (difference > 0.5)
								difference=difference-1.0;
							// calculate a new value for the position
							new_value=value_old+difference;
							// restore the homogeneous value if needed
							new_value = homogeneous?std_to_hom((*bline)(time), new_value, wplistloop, blineloop):new_value;
							// this is the difference between the new value and the old value inside the boundaries
							Real bound_diff((wp.get_lower_bound() + new_value*(wp.get_upper_bound()-wp.get_lower_bound()))-value_old_b);
							// add the new diff to the current value
							new_value = wp.get_position() + bound_diff;
						}
						else
						{
							// grab a new position given by duck's position on the bline
							new_value = synfig::find_closest_point((*bline)(time), p , radius, blineloop);
							// if it is homogeneous then convert to it
							new_value=homogeneous?std_to_hom((*bline)(time), new_value, wplistloop, blineloop):new_value;
							// convert the value inside the boundaries
							new_value = wp.get_lower_bound()+new_value*(wp.get_upper_bound()-wp.get_lower_bound());
						}
						cr->save();
						layout->set_text(strprintf("%2.3f", new_value));

						cr->set_source_rgb(0,0,0); // DUCK_COLOR_WIDTH_TEXT_1
						cr->move_to(
							point[0]+1+6,
							point[1]+1-18
							);
						layout->show_in_cairo_context(cr);
						cr->stroke();


						cr->set_source_rgb(1,0,1); // DUCK_COLOR_WIDTH_TEXT_2
						cr->move_to(
							point[0]+6,
							point[1]-18
							);
						layout->show_in_cairo_context(cr);
						cr->stroke();

						cr->restore();
					}
				}
			}
		}

	}

	for(;screen_duck_list.size();screen_duck_list.pop_front())
	{
		Gdk::Color color(screen_duck_list.front().color);
		double radius = 4;
		double outline = 1;
		bool duck_alternative = alternative && screen_duck_list.front().has_alternative;

		// Draw the hovered duck last (on top of everything)
		if(screen_duck_list.front().hover && !screen_duck_list.back().hover && screen_duck_list.size()>1)
		{
			screen_duck_list.push_back(screen_duck_list.front());
			continue;
		}

		cr->save();

		if(!screen_duck_list.front().selected)
		{
			color.set_red(color.get_red()*2/3);
			color.set_green(color.get_green()*2/3);
			color.set_blue(color.get_blue()*2/3);
		}

		if(screen_duck_list.front().hover)
		{
			radius += 1;
			outline += 1;
		}

		cr->arc(
			screen_duck_list.front().pos[0],
			screen_duck_list.front().pos[1],
			radius,
			0,
			M_PI*2
			);

		cr->set_source_rgba(
			color.get_red_p(),
			color.get_green_p(),
			color.get_blue_p(),
			duck_alternative ? 0.5 : 1.0
			);
		cr->fill_preserve();

		cr->set_line_width(outline);
		cr->set_source_rgba(0,0,0,1); //DUCK_COLOR_OUTLINE
		cr->stroke();

		cr->restore();
	}
}
Example #18
0
static void
draw_text (Cairo::RefPtr<Cairo::Context> cr, int wdh, int hgt)
{
    RefPtr<Pango::Layout> layout = Pango::Layout::create(cr);
    //layout->set_single_paragraph_mode(true);
    layout->set_text("MTextTextM\nAbc\nff");


    Pango::FontDescription dsc(FONT);
    layout->set_font_description(dsc);

    int t_wdh, t_hgt;
    layout->get_size(t_wdh, t_hgt);

    double t_sz = (double)dsc.get_size()/t_wdh;
    double new_sz = wdh * t_sz ;

    io::cout << "new_sz " << new_sz << io::endl;
    io::cout << "wdh " << wdh << io::endl;

    dsc.set_size( int(new_sz*PANGO_SCALE) );
    layout->set_font_description(dsc);

    layout->get_size(t_wdh, t_hgt);
    io::cout << "t_wdh " << t_wdh/(double)PANGO_SCALE << io::endl;

    // для наглядности
    cr->set_line_width(1.0);
    cr->rectangle(0, 0, wdh, hgt);
    cr->stroke();


    cr->save();

    cr->move_to(0, 0);
    cr->scale( 1.0, hgt / ((double)t_hgt/PANGO_SCALE) );
    //cr->scale( wdh / ((double)t_wdh/PANGO_SCALE), hgt / ((double)t_hgt/PANGO_SCALE) );

    layout->update_from_cairo_context(cr);

    pango_cairo_show_layout(cr->cobj(), layout->gobj());

    {
        Pango::Rectangle w_rct, s_rct;
        int cur_pos;

        cur_pos = 1;
        layout->get_cursor_pos(cur_pos, w_rct, s_rct);
        pango_extents_to_pixels(0, w_rct.gobj());

        io::cout << "curs - x, y, hgt " << w_rct.get_x() << " " << w_rct.get_y() << " " << w_rct.get_height() << io::endl;
        cr->move_to(w_rct.get_x()+5, w_rct.get_y());
        cr->line_to(w_rct.get_x()+5, w_rct.get_y()+w_rct.get_height());
        cr->stroke();


        cur_pos = 11;
        layout->get_cursor_pos(cur_pos, w_rct, s_rct);
        pango_extents_to_pixels(0, w_rct.gobj());

        io::cout << "curs - x, y, hgt " << w_rct.get_x() << " " << w_rct.get_y() << " " << w_rct.get_height() << io::endl;
        cr->move_to(w_rct.get_x()+5, w_rct.get_y());
        cr->line_to(w_rct.get_x()+5, w_rct.get_y()+w_rct.get_height());
        cr->stroke();

    }


    cr->restore();
}
Example #19
0
Cairo::RefPtr<CairoContext> CairoContext::create(Cairo::RefPtr<Cairo::Surface> const &target)
{
    cairo_t *ct = cairo_create(target->cobj());
    Cairo::RefPtr<CairoContext> ret(new CairoContext(ct, true));
    return ret;
}
Example #20
0
void RegionChooser::draw_regions(const Cairo::RefPtr<Cairo::Context>& cr,
                                 int clip_low, int clip_high) {
    const int w = get_width() - 1;

    Gdk::Cairo::set_source_rgba(cr, black);
    gig::Region* next_region;
    int x3 = -1;
    for (gig::Region* r = regions.first() ; r ; r = next_region) {
        next_region = regions.next();

        if (x3 < 0) {
            x3 = key_to_x(r->KeyRange.low, w);
            if (x3 >= clip_high) break;
        }
        if (!next_region ||
            r->KeyRange.high + 1 != next_region->KeyRange.low ||
            r == region || next_region == region) {

            int x2 = key_to_x(r->KeyRange.high + 1, w);
            if (x2 >= clip_low) {
                cr->move_to(x3, 0.5);
                cr->line_to(x2 + 0.5, 0.5);
                cr->line_to(x2 + 0.5, h1 - 0.5);
                cr->line_to(x3, h1 - 0.5);
                cr->stroke();

                Gdk::Cairo::set_source_rgba(cr, region == r ? red : white);
                cr->rectangle(x3 + 1, 1, x2 - x3 - 1, h1 - 2);
                cr->fill();
                Gdk::Cairo::set_source_rgba(cr, black);
            }
            x3 = -1;
        }
    }

    for (gig::Region* r = regions.first() ; r ; r = regions.next()) {
        int x = key_to_x(r->KeyRange.low, w);

        if (x < clip_low) continue;
        if (x >= clip_high) break;

        cr->move_to(x + 0.5, 1);
        cr->line_to(x + 0.5, h1 - 1);
        cr->stroke();
    }

    // if there is no region yet, show the user some hint text that he may
    // right click on this area to create a new region
    if (!regions.first()) {
        Glib::RefPtr<Pango::Context> context = get_pango_context();
        Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(context);
        layout->set_alignment(Pango::ALIGN_CENTER);
        layout->set_text(Glib::ustring("*** ") + _("Right click here to create a region.") + " ***");
        layout->set_width(get_width() * Pango::SCALE);
        //layout->set_height(get_height() * Pango::SCALE);
        layout->set_spacing(10);
        Gdk::Cairo::set_source_rgba(cr, red);        
        // get the text dimensions
        int text_width, text_height;
        layout->get_pixel_size(text_width, text_height);
        cr->move_to(0, (REGION_BLOCK_HEIGHT - text_height) / 2);
#if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 16) || GTKMM_MAJOR_VERSION < 2
        pango_cairo_show_layout(cr->cobj(), layout->gobj());
#else
        layout->show_in_cairo_context(cr);
#endif
    }
}