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); }
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; }
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(); } }
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; }
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 }
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); }
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 }
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 }
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(); }
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; }
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 }
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); } }
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()); }
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(); } }
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(); }
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; }
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 } }