void CharacterRenderer::render(const Cairo::RefPtr<Cairo::Context> &cr) { unsigned int sprite_index = 0; if (first_render_) { first_render_ = false; last_x_ = position_.x(); } std::vector<Glib::RefPtr<Gdk::Pixbuf> > *images; if (std::abs(last_x_ - position_.x()) > THRESHOLD) { sprite_index = ((sprite_step_ / 6) % sprites_moving_size()) + 1; if (last_x_ - position_.x() > 0.0) { right_direction_ = false; } else { right_direction_ = true; } } if (last_x_ - position_.x() > THRESHOLD) { images = &images_left_; } else if ((last_x_ - position_.x()) < -THRESHOLD) { images = &images_right_; } else { if (right_direction_) { images = &images_right_; } else { images = &images_left_; } } cr->translate(position_.x(), position_.y()); cr->scale(1.0 / (*images)[sprite_index]->get_width(), 1.0 / (*images)[sprite_index]->get_height()); cr->translate(-(*images)[sprite_index]->get_width() / 2, -(*images)[sprite_index]->get_height() / 2); Gdk::Cairo::set_source_pixbuf(cr, (*images)[sprite_index], 0, 0); cr->paint(); sprite_step_++; last_x_ = position_.x(); }
/** Expose event handler. * @param event event info structure. * @return signal return value */ bool LaserDrawingArea::on_expose_event(GdkEventExpose* event) #endif { // This is where we draw on the window Glib::RefPtr<Gdk::Window> window = get_window(); if(window) { Gtk::Allocation allocation = get_allocation(); if(__first_draw) { __first_draw = false; const int width = allocation.get_width(); const int height = allocation.get_height(); // coordinates for the center of the window __xc = width / 2; __yc = height / 2; } #if GTK_VERSION_LT(3,0) Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context(); #endif cr->set_line_width(1.0); cr->set_source_rgb(1, 1, 1); #if GTK_VERSION_LT(3,0) // clip to the area indicated by the expose event so that we only // redraw the portion of the window that needs to be redrawn cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height); cr->fill_preserve(); cr->clip(); #else cr->paint(); #endif cr->set_source_rgb(0, 0, 0); //cr->set_source_rgba(0,0,0,1); // __last_xc += __translation_x; // __last_yc += __translation_y; cr->translate(__xc, __yc); cr->save(); if (! __connected) { Cairo::TextExtents te; std::string t = "Not connected to BlackBoard"; cr->set_source_rgb(1, 0, 0); cr->set_font_size(20); cr->get_text_extents(t, te); cr->move_to(- te.width / 2, -te.height / 2); cr->show_text(t); } else if ( __laser_ifs.empty() ) { Cairo::TextExtents te; std::string t = "No interface opened"; cr->set_source_rgb(1, 0, 0); cr->set_font_size(20); cr->get_text_extents(t, te); cr->move_to(- te.width / 2, -te.height / 2); cr->show_text(t); } else if (! all_laser_ifs_have_writer() ) { Cairo::TextExtents te; std::string t = "No writer for "; for (std::list<InterfaceColorPair>::const_iterator it = __laser_ifs.begin(); it != __laser_ifs.end(); ++it) { fawkes::Interface* itf = it->first; if (!itf->has_writer()) { t += itf->uid(); t += ' '; } } cr->set_source_rgb(1, 0, 0); cr->set_font_size(20); cr->get_text_extents(t, te); cr->move_to(- te.width / 2, -te.height / 2); cr->show_text(t); } else { if (! __break_drawing) { for (std::list<InterfaceColorPair>::const_iterator it = __laser_ifs.begin(); it != __laser_ifs.end(); ++it) { fawkes::Interface* laser_if = it->first; laser_if->read(); } } for (std::list<InterfaceColorPair>::const_iterator it = __laser_ifs.begin(); it != __laser_ifs.end(); ++it) { const fawkes::Interface* laser_if = it->first; const Color& color = it->second; cr->save(); cr->set_source_rgb(color.r, color.g, color.b); draw_beams(laser_if, window, cr); cr->restore(); } if (__robot_drawer) __robot_drawer->draw_robot(window, cr); for (std::list<InterfaceColorPair>::const_iterator it = __laser_ifs.begin(); it != __laser_ifs.end(); ++it) { const fawkes::Interface* laser_if = it->first; const Color& color = it->second; cr->save(); cr->set_source_rgb(color.r, color.g, color.b); draw_segments(laser_if, window, cr); cr->restore(); } draw_persons_legs(window, cr); if(__switch_if != NULL && __switch_if->has_writer()){ SwitchInterface::EnableSwitchMessage *esm = new SwitchInterface::EnableSwitchMessage(); __switch_if->msgq_enqueue(esm); } } cr->restore(); cr->save(); cr->rotate(0.5 * M_PI + __rotation); cr->scale(-__zoom_factor, __zoom_factor); cr->set_line_width(1. / __zoom_factor); if (__visdisp_if) { __visdisp->process_messages(); __visdisp->draw(cr); } const float radius = 0.01; if (__line_if) { __line_if->read(); if (__line_if->has_writer() && __line_if->is_valid() && __line_if->is_visible()) { cr->set_source_rgb(1, 0, 0); /* std::vector<double> dashes(1); dashes[0] = 0.1; cr->set_dash(dashes, 0); */ cr->rectangle(__line_if->world_x() - radius * 0.5, __line_if->world_y() - radius * 0.5, radius, radius); cr->rectangle(__line_if->relative_x() - radius * 0.5, __line_if->relative_y() - radius * 0.5, radius, radius); cr->fill_preserve(); cr->stroke(); cr->move_to(__line_if->world_x(), __line_if->world_y()); cr->line_to(__line_if->relative_x(), __line_if->relative_y()); cr->stroke(); } } cr->restore(); } return true; }
bool MonitorInterface::graficar(GdkEventExpose* event){ /* genero ejes de coordenadas ^ <<offsetx>> | |--------> ^ o f y ^ */ Glib::RefPtr<Gdk::Window> ventana= draw_area->get_window(); if (!ventana) { return false; } Gtk::Allocation allocation = draw_area->get_allocation(); const int width = allocation.get_width(); const int height = allocation.get_height(); Cairo::RefPtr < Cairo::Context > cr = ventana->create_cairo_context(); // dibujo TEXTO en el grefico EJE Y double distacia_y = height/double(CANT_DIVISIONES); syslog(LOG_DEBUG, "Distacia_y: %f", distacia_y); double valor =0; for(size_t i=1;i<CANT_DIVISIONES-2;++i){ stringstream aux; string auxaux; // el -10 es por el tamaño de la letra, ya que se empieza a dibujar desde la pos arriba a la izquierda cr->move_to(width*0.02,height -i*distacia_y -offset_y*height -8); valor+=(max_medida/(CANT_DIVISIONES)); aux<<std::setprecision(2)<<fixed<<(valor); aux>>auxaux; Glib::RefPtr<Pango::Layout> pl = draw_area->create_pango_layout(auxaux); //Glib::RefPtr<Pango::FontDescription >desc = pango_font_description_from_string("Sans Bold 8"); //pango_layout_set_font_description(pl, desc); pl->show_in_cairo_context(cr); } // fin del dibujo del TEXTO EJE Y // dibujo eje x double distancia_x = width/double(CANT_DIVISIONES); int valor_x =-16; for(size_t i=0;i<CANT_DIVISIONES;++i){ stringstream aux_x; string auxaux_x; cr->move_to(distancia_x*i+ width*offset_x-10, height-offset_y*height+4); aux_x<<std::setprecision(2)<<fixed<<(valor_x); aux_x>>auxaux_x; Glib::RefPtr<Pango::Layout> pl = draw_area->create_pango_layout(auxaux_x); pl->show_in_cairo_context(cr); valor_x++; } // fin dibujo ejex cr->move_to(width*0.015, height-offset_y*height); Glib::RefPtr<Pango::Layout> pl = draw_area->create_pango_layout("MB/seg"); pl->show_in_cairo_context(cr); cr->scale(width, height); this->dibujar_ejes(cr); this->dibujar_division_x(cr, CANT_DIVISIONES, offset_x, offset_y); this->dibujar_division_y(cr, CANT_DIVISIONES, offset_y, offset_x); double espacio = 1 / double(medidas.size()); double x = 0; // genero linea de graficos cr->set_line_width(0.009); cr->set_source_rgba(0.337, 0.612, 0.117, 0.9); list<double>::iterator it; it = medidas.begin(); cr->move_to(0 + offset_x, 1 - (*it / max_medida) - offset_y); it++; for (; it != medidas.end(); ++it) { x += espacio; cr->line_to(x+offset_x, 1 - (*it / max_medida) -offset_y); } cr->stroke(); return true; }
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 scale2__(Glib::ustring& x,Glib::ustring& y){ cr_->scale(s2f__(x), s2f__(y)); }
void scale__(Glib::ustring& w,Glib::ustring& h){ cr_->scale(s2i__(w), s2i__(h)); }
void Thing::RestoreContext(Cairo::RefPtr<Cairo::Context> myCr) const { myCr->rotate_degrees(-orientationAngle); myCr->translate(-position[0], -position[1]); myCr->scale(1/scalingFactor, 1/scalingFactor); }
void cairo::draw_window( const Cairo::RefPtr<Cairo::Context>& cr, const Window& window, const rgba_color_ref_t& color ) { const ps_t ps = window.pseudosource(); cairo_coord_t B0( window.bound<LEFT>(), 0 ); cairo_coord_t B1( window.bound<RIGHT>(), 0 ); cairo_coord_t PS( ps[0], ps[1] ); cr->save(); cr->set_source_rgba( color[0], color[1], color[2], color[3] ); cr->move_to( B0[0], B0[1] + cr->get_line_width() ); cr->line_to( B1[0], B1[1] + cr->get_line_width() ); cr->stroke(); std::vector<double> dashes(2); dashes[0] = 2. * user_unit_distance( cr ).length(); dashes[1] = 10. * user_unit_distance( cr ).length(); cr->set_dash( dashes, 0. ); cr->set_source_rgba( color[0], color[1], color[2], color[3]*.5 ); cr->move_to( B1[0], B1[1] ); cr->line_to( PS[0], PS[1] ); cr->line_to( B0[0], B0[1] ); cr->stroke(); cr->restore(); cr->save(); cr->set_font_size( 8. * user_unit_distance( cr ).length() ); cr->set_source_rgba( color[0], color[1], color[2], 1. ); std::ostringstream nrss; nrss << window.id; cairo_coord_t pos = (B0+B1)*.5; pos[1] += 5.*user_unit_distance( cr ).length(); cr->translate( pos[0], pos[1] ); cr->scale( 1., -1. ); draw_centered_text( cr, nrss.str() ); cr->restore(); #if defined DBG_FLAT_MMP_VISUALIZER_DRAW_WINDOW std::clog << "mmp::visualizer::draw_window\t|" << window << std::endl << "\t\t\t\t\t|" << " color " << color << " bounds " << bb << std::endl; #endif }
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 }
bool ClockDrawArea::on_draw(const Cairo::RefPtr<Cairo::Context>& context){ //Get the drawing area auto allocation = get_allocation(); const int width = allocation.get_width(); const int height = allocation.get_height(); //Set the scale to a unit square context->scale(width, height); //Set (0.5, 0.5) to (0, 0). convenient to draw with arc. context->translate(0.5, 0.5); //Paint the background of the window; context->save(); context->set_source_rgba(0.337, 0.612, 0.117, 0.9); context->paint(); context->restore(); //Draw the outer edge of the clock context->set_line_width(3 * m_LineWidth); context->arc(0, 0, m_Radius, 0, 2 * M_PI); //Paint the background color of the clock context->save(); context->set_source_rgba(1.0, 1.0, 1.0, 0.8); context->fill_preserve(); context->restore(); //Draw a center point for good looking context->stroke(); context->arc(0, 0, 0.05 * m_Radius, 0, 2 * M_PI); context->stroke(); //Draw ticks context->save(); double l = 1; for(int i = 0; i <= 11; i++){ if((i % 3) == 0) { l = m_Radius * 0.8; }else{ l = m_Radius * 0.9; } context->move_to(l * cos(i * 2* M_PI /12), l * sin(i * 2 * M_PI /12)); context->line_to(m_Radius * cos(i * 2 * M_PI /12), m_Radius * sin(i * 2 * M_PI /12)); } context->stroke(); context->restore(); //Get the current time from system and save info to a timeinfo struct time_t rawTime; time(&rawTime); struct tm * timeinfo = localtime(&rawTime); //Calculate the angle of hands of the clock auto radSeconds = (timeinfo->tm_sec * 2 * M_PI /60) - M_PI/2; auto radMinutes = (timeinfo->tm_min * 2 * M_PI /60) - M_PI/2; auto radHours = (timeinfo->tm_hour * 2 * M_PI /12) - M_PI/2 + timeinfo->tm_min * 2 * M_PI /(60 * 12); //Draw the hands of the clock context->save(); //The hand of seconds context->set_source_rgba(0.823, 0.322, 0.155, 0.9); context->set_line_width(m_LineWidth); l = 0.9 * m_Radius; context->move_to(0,0); context->line_to(l * cos(radSeconds), l * sin(radSeconds)); context->stroke(); //The hand of minutes context->set_source_rgba(0.632, 0.802, 0.266, 0.9); context->set_line_width(2 * m_LineWidth); l = 0.8 * m_Radius; context->move_to(0,0); context->line_to(l * cos(radMinutes), l * sin(radMinutes)); context->stroke(); //The hand of hours context->set_source_rgba(0.104, 0.582, 0.723, 0.9); context->set_line_width(3 * m_LineWidth); l = 0.65 * m_Radius; context->move_to(0,0); context->line_to(l * cos(radHours), l * sin(radHours)); context->stroke(); context->restore(); return true; }
static void skillgui_cairo_render_begin_page(GVJ_t *job) { #ifdef USE_GVPLUGIN_TIMETRACKER __tt.ping_start(__ttc_page); __tt.ping_start(__ttc_beginpage); #endif SkillGuiCairoRenderInstructor *cri = (SkillGuiCairoRenderInstructor *)job->context; obj_state_t *obj = job->obj; if (obj && obj->type == ROOTGRAPH_OBJTYPE) { __fontname = agget(obj->u.g, (char *)"fontname"); } float bbwidth = job->bb.UR.x - job->bb.LL.x; float bbheight = job->bb.UR.y - job->bb.LL.y; cri->set_bb(bbwidth, bbheight); cri->set_pad(job->pad.x, job->pad.y); Cairo::RefPtr<Cairo::Context> cairo = cri->get_cairo(); double pad_x, pad_y; cri->get_pad(pad_x, pad_y); // For internal calculations we need to care about the padding //bbwidth += 2 * pad_x; //bbheight += 2 * pad_y; double avwidth, avheight; cri->get_dimensions(avwidth, avheight); float translate_x = 0; float translate_y = 0; if ( cri->scale_override() ) { float zoom = cri->get_scale(); float zwidth = bbwidth * zoom; float zheight = bbheight * zoom; translate_x += (avwidth - zwidth ) / 2.; translate_y += (avheight - zheight) / 2.; double translate_x, translate_y; cri->get_translation(translate_x, translate_y); cairo->translate(translate_x, translate_y); cairo->scale(zoom, zoom); } else { float zoom_w = avwidth / bbwidth; float zoom_h = avheight / bbheight; float zoom = std::min(zoom_w, zoom_h); if (bbwidth > avwidth || bbheight > avheight) { float zwidth = bbwidth * zoom; float zheight = bbheight * zoom; translate_x += (avwidth - zwidth ) / 2.; translate_y += (avheight - zheight) / 2. + zheight; } else { zoom = 1.0; translate_x += (avwidth - bbwidth) / 2.; translate_y += (avheight - bbheight) / 2. + bbheight; } cri->set_scale(zoom); cri->set_translation(translate_x, translate_y); cairo->translate(translate_x + pad_x * zoom, translate_y - pad_y * zoom); cairo->scale(zoom, zoom); } #ifdef USE_GVPLUGIN_TIMETRACKER __num_ellipse = 0; __num_bezier = 0; __num_polygon = 0; __num_polyline = 0; __num_text = 0; __tt.ping_end(__ttc_beginpage); #endif }
void ImageDrawable::drawImage(const Cairo::RefPtr<Cairo::Context> &cr, const Gtk::Allocation &allocation) { auto image = images->current(); auto surface = image->getPrimary(); int rwidth, rheight; double rscale; double rx, ry; //cout << "image " << iwidth << "x" << iheight << " " << iorientation.first << "," << iorientation.second << endl; calcRenderedImage(image, allocation, rwidth, rheight, rscale, rx, ry); cr->translate(rx, ry); cr->scale(rscale, rscale); waiting = !surface; if (image->isPrimaryFailed()) { // TODO display fancy failed indicator cr->set_source_rgb(0.75, 0.5, 0.5); cr->rectangle(0, 0, rwidth, rheight); cr->clip(); cr->paint(); return; } else if (!surface) { // TODO display fancy loading animation cr->set_source_rgb(0.5, 0.75, 0.5); cr->rectangle(0, 0, rwidth, rheight); cr->clip(); cr->paint(); return; } switch (image->getOrientation().first) { case Image::Rotate::ROTATE_NONE: break; case Image::Rotate::ROTATE_90: cr->translate(image->height(), 0); cr->rotate_degrees(90); break; case Image::Rotate::ROTATE_180: cr->translate(image->width(), image->height()); cr->rotate_degrees(180); break; case Image::Rotate::ROTATE_270: cr->translate(0, image->width()); cr->rotate_degrees(270); break; } if (image->getOrientation().second) { cr->translate(image->width(), 0); cr->scale(-1, 1); } auto pattern = Cairo::SurfacePattern::create(surface); pattern->set_filter(Cairo::Filter::FILTER_FAST); cr->set_source(pattern); //auto start = chrono::steady_clock::now(); cr->paint(); //auto stop = chrono::steady_clock::now(); //cout << "paint " << chrono::duration_cast<chrono::milliseconds>(stop - start).count() << "ms" << endl; if (afPoints) { //start = chrono::steady_clock::now(); auto properties = image->getProperties(); valarray<double> dashes(5.0 / rscale, 5.0 / rscale); cr->save(); cr->set_operator(static_cast<Cairo::Operator>(CAIRO_OPERATOR_DIFFERENCE)); for (auto &rect : properties.focusPoints) { if (properties.focusPointsActive.find(rect) != properties.focusPointsActive.cend()) { cr->set_source_rgb(1, 0, 1); cr->set_line_width(4.0 / rscale); cr->unset_dash(); } else if (properties.focusPointsSelected.find(rect) != properties.focusPointsSelected.cend()) { cr->set_source_rgb(1, 0, 0); cr->set_line_width(2.0 / rscale); cr->unset_dash(); } else { cr->set_source_rgb(1, 1, 1); cr->set_line_width(1.0 / rscale); cr->set_dash(dashes, 0); } cr->rectangle(rect.x, rect.y, rect.width, rect.height); cr->stroke(); } cr->restore(); //stop = chrono::steady_clock::now(); //cout << "afpaint " << chrono::duration_cast<chrono::milliseconds>(stop - start).count() << "ms" << endl; } }
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(); }
/** Draw Beams of an interface. * Draws the beams as lines, circles or hull, depending on draw mode. * @param itf either Laser360Interface or Laser720Interface * @param window Gdk window * @param cr Cairo context to draw to. It is assumed that possible transformations * have been setup before. */ void LaserDrawingArea::draw_beams(const fawkes::Interface *itf, Glib::RefPtr<Gdk::Window> &window, const Cairo::RefPtr<Cairo::Context> &cr) { float *distances; size_t nd; bool clockwise; const fawkes::Laser360Interface* itf360 = NULL; const fawkes::Laser720Interface* itf720 = NULL; if ((itf360 = dynamic_cast<const fawkes::Laser360Interface*>(itf))) { distances = itf360->distances(); nd = itf360->maxlenof_distances(); clockwise = itf360->is_clockwise_angle(); } else if ((itf720 = dynamic_cast<const fawkes::Laser720Interface*>(itf))) { distances = itf720->distances(); nd = itf720->maxlenof_distances(); clockwise = itf720->is_clockwise_angle(); } else { throw fawkes::Exception("Interface is neither Laser360Interface nor Laser720Interface"); } const float nd_factor = 360.0 / nd; float *revdists = NULL; if (! clockwise) { // re-arrange to clockwise revdists = (float *)new float[nd]; for (size_t i = 0; i < nd; ++i) { revdists[nd - i] = distances[i]; } distances = revdists; } cr->scale(__zoom_factor, __zoom_factor); cr->rotate(__rotation); cr->set_line_width(1. / __zoom_factor); draw_scalebox(window, cr); if ( __draw_mode == MODE_LINES ) { for (size_t i = 0; i < nd; i += __resolution) { if ( distances[i] == 0 || ! std::isfinite(distances[i]) ) continue; const float anglerad = deg2rad(i * nd_factor); cr->move_to(0, 0); cr->line_to(distances[i] * sin(anglerad), distances[i] * -cos(anglerad)); } cr->stroke(); } else if ( __draw_mode == MODE_POINTS ) { const float radius = 4 / __zoom_factor; for (size_t i = 0; i < nd; i += __resolution) { if ( distances[i] == 0 ) continue; float anglerad = deg2rad(i * nd_factor); float x = distances[i] * sin(anglerad); float y = distances[i] * -cos(anglerad); // circles replaced by rectangles, they are a *lot* faster //cr->move_to(x, y); //cr->arc(x, y, radius, 0, 2*M_PI); cr->rectangle(x, y, radius, radius); } cr->fill_preserve(); cr->stroke(); } else { cr->move_to(0, - distances[0]); for (size_t i = __resolution; i <= nd + __resolution; i += __resolution) { if ( distances[i] == 0 ) continue; const float anglerad = normalize_rad(deg2rad(i * nd_factor)); cr->line_to(distances[i % nd] * sin(anglerad), distances[i % nd] * -cos(anglerad)); } cr->stroke(); } if (revdists) delete[] revdists; }
void MyWidget::drawWidget() { Painter p(this); if (m_color) { p.setSourceRGB(1.0, 0, 0); } else { p.setSourceRGB(0, 0, 0); } p.translate(minimumSize().width() / 2.0, minimumSize().height() / 2.0); p.setLineWidth(m_lineWidth); p.arc(0, 0, m_radius, 0, 2 * M_PI); p.save(); p.setSourceRGBA(1.0, 1.0, 1.0, 0.8); p.fillPreserve(); p.restore(); p.strokePreserve(); p.clip(); for (int i = 0; i < 12; ++i) { double inset = 30; p.save(); p.setLineCap(Painter::RoundLineCap); if(i % 3 != 0) { inset *= 0.8; p.setLineWidth(1.0); } p.moveTo((m_radius - inset) * cos (i * M_PI / 6.0), (m_radius - inset) * sin (i * M_PI / 6.0)); p.lineTo(m_radius * cos (i * M_PI / 6.0), m_radius * sin (i * M_PI / 6.0)); p.stroke(); p.restore(); } // store the current time time_t rawtime; time(&rawtime); struct tm * timeinfo = localtime (&rawtime); // compute the angles of the indicators of our clock double minutes = timeinfo->tm_min * M_PI / 30; double hours = timeinfo->tm_hour * M_PI / 6; double seconds= timeinfo->tm_sec * M_PI / 30; p.save(); p.setLineCap(Painter::RoundLineCap); // draw the seconds hand p.save(); p.setLineWidth(m_lineWidth); p.setSourceRGBA(0.7, 0.7, 0.7, 0.8); p.moveTo(0, 0); p.lineTo(sin(seconds) * (m_radius * 0.9), -cos(seconds) * (m_radius * 0.9)); p.stroke(); p.restore(); // draw the minutes hand p.setSourceRGBA(0.117, 0.337, 0.612, 0.9); p.moveTo(0, 0); p.lineTo(sin(minutes + seconds / 60.0) * (m_radius * 0.8), -cos(minutes + seconds / 60.0) * (m_radius * 0.8)); p.stroke(); // draw the hours hand p.setSourceRGBA(0.337, 0.612, 0.117, 0.9); p.moveTo(0, 0); p.lineTo(sin(hours + minutes / 12.0) * (m_radius * 0.5), -cos(hours + minutes / 12.0) * (m_radius * 0.5)); p.stroke(); p.restore(); p.setSourceRGBA(1, 0, 0, 0.5); p.arc(0, 0, m_lineWidth * 2.0, 0, 2.0 * M_PI); p.fill(); #if 0 // This is where we draw on the window 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(); Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context(); if(event) { // clip to the area indicated by the expose event so that we only // redraw the portion of the window that needs to be redrawn cr->rectangle(event->area.x, event->area.y, event->area.width, event->area.height); cr->clip(); } // background gradient { Cairo::RefPtr<Cairo::LinearGradient> pat = Cairo::LinearGradient::create(0.0, 0.0, 0.0, height); pat->add_color_stop_rgb(1.0, 1.0, 1.0, 1.0); pat->add_color_stop_rgb(0.0, 0.0, 0.0, 0.0); cr->rectangle(0, 0, width, height); cr->set_source(pat); cr->fill(); } // scale to unit square and translate (0, 0) to be (0.5, 0.5), i.e. // the center of the window cr->scale(width, height); cr->translate(0.5, 0.5); cr->set_line_width(m_line_width); cr->arc(0, 0, m_radius, 0, 2 * M_PI); cr->save(); cr->set_source_rgba(1.0, 1.0, 1.0, 0.8); cr->fill_preserve(); cr->restore(); cr->stroke_preserve(); cr->clip(); //clock ticks for (int i = 0; i < 12; i++) { double inset = 0.05; cr->save(); cr->set_line_cap(Cairo::LINE_CAP_ROUND); if(i % 3 != 0) { inset *= 0.8; cr->set_line_width(0.03); } cr->move_to( (m_radius - inset) * cos (i * M_PI / 6), (m_radius - inset) * sin (i * M_PI / 6)); cr->line_to ( m_radius * cos (i * M_PI / 6), m_radius * sin (i * M_PI / 6)); cr->stroke(); cr->restore(); /* stack-pen-size */ } // store the current time time_t rawtime; time(&rawtime); struct tm * timeinfo = localtime (&rawtime); // compute the angles of the indicators of our clock double minutes = timeinfo->tm_min * M_PI / 30; double hours = timeinfo->tm_hour * M_PI / 6; double seconds= timeinfo->tm_sec * M_PI / 30; cr->save(); cr->set_line_cap(Cairo::LINE_CAP_ROUND); // draw the seconds hand cr->save(); cr->set_line_width(m_line_width / 3); cr->set_source_rgba(0.7, 0.7, 0.7, 0.8); // gray cr->move_to(0, 0); cr->line_to(sin(seconds) * (m_radius * 0.9), -cos(seconds) * (m_radius * 0.9)); cr->stroke(); cr->restore(); // draw the minutes hand cr->set_source_rgba(0.117, 0.337, 0.612, 0.9); // blue cr->move_to(0, 0); cr->line_to(sin(minutes + seconds / 60) * (m_radius * 0.8), -cos(minutes + seconds / 60) * (m_radius * 0.8)); cr->stroke(); // draw the hours hand cr->set_source_rgba(0.337, 0.612, 0.117, 0.9); // green cr->move_to(0, 0); cr->line_to(sin(hours + minutes / 12.0) * (m_radius * 0.5), -cos(hours + minutes / 12.0) * (m_radius * 0.5)); cr->stroke(); cr->restore(); // draw a little dot in the middle cr->arc(0, 0, m_line_width / 3.0, 0, 2 * M_PI); cr->fill(); } #endif }
void guiRenderer2D::drawMatrices(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height, bool screenshot) { cr->scale(m_scaleFactor, m_scaleFactor); // Scale sensor to fit the active window cr->translate(m_offsetX, m_offsetY); // Center figure on drawable/surface cr->set_line_width(0.25); for(uint m = 0; m < m_frameManager->getNumMatrices(); m++) { matrixInfo &matrix = m_frameManager->getMatrixInfo(m); // TSFrame* tsFrame = m_frameManager->getCurrentFrame(); TSFrame* tsFrame = m_frameManager->getCurrentFilteredFrame(); for(uint y = 0; y < matrix.cells_y; y++) { for(uint x = 0; x < matrix.cells_x; x++) { bool maskedStatic = m_frameManager->getStaticMask(m, x, y); bool maskedDynamic = m_frameManager->getDynamicMask(m, x, y); uint cellID = matrix.texel_offset + y * matrix.cells_x + x; float value = tsFrame->cells[cellID]; if(maskedStatic) { RGB color = determineColor(value); // Draw sensor cell rectangle cr->rectangle(m_rectangleTopLeftX[cellID], m_rectangleTopLeftY[cellID], m_rectangleWidth[cellID], m_rectangleHeight[cellID]); cr->set_source_rgb(0.0, 0.0, 0.0); cr->stroke_preserve(); // Cell outline if(maskedDynamic) { if(value > 0.0) { cr->set_source_rgb(color.r, color.g, color.b); // Active cells } else { cr->set_source_rgb(1.0, 1.0, 1.0); // Inactive cells } } else { cr->set_source_rgb(0.8, 0.8, 0.8); // Disabled cells } cr->fill(); } // Highlight selected cells if(m_frameManager->isSelected(cellID)) { cr->rectangle(m_rectangleTopLeftX[cellID], m_rectangleTopLeftY[cellID], m_rectangleWidth[cellID], m_rectangleHeight[cellID]); cr->set_source_rgba(0.0, 1.0, 0.0, 0.5); // Fill active cells cr->fill(); } if(screenshot) { if(maskedStatic) { // Print values Cairo::RefPtr<Cairo::ToyFontFace> font = Cairo::ToyFontFace::create("LMSans10", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL); cr->set_font_face(font); cr->set_font_size(matrix.texel_width/3); std::ostringstream ss; ss << value; std::string valueStr = ss.str(); Cairo::TextExtents te; cr->get_text_extents(valueStr, te); cr->move_to(m_matrixCellCenterX[cellID]-te.width/2, m_matrixCellCenterY[cellID]+te.height/2); cr->set_source_rgb(0.0, 0.0, 0.0); cr->show_text(valueStr); } } } } if(!screenshot) { { // Print Matrix IDs Cairo::RefPtr<Cairo::ToyFontFace> font = Cairo::ToyFontFace::create("LMSans10", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL); cr->set_font_face(font); cr->set_font_size(matrix.cells_x*matrix.texel_width); std::ostringstream ss; ss << m; std::string idString = ss.str(); Cairo::TextExtents te; cr->get_text_extents(idString, te); cr->move_to(m_newCenterX[m]-te.width/2, m_newCenterY[m]+te.height/2); cr->set_source_rgba(0.3, 0.3, 0.3, 0.3); cr->show_text(idString); } } } }
void area___::test__(){ int width, height; width=da_->get_allocation().get_width(); height=da_->get_allocation().get_height(); double m_radius=0.42; double m_line_width=0.05; // scale to unit square and translate (0, 0) to be (0.5, 0.5), i.e. // the center of the window cr_->scale(width, height); cr_->translate(0.5, 0.5); cr_->set_line_width(m_line_width); cr_->save(); cr_->set_source_rgba(0.337, 0.612, 0.117, 0.9); // green cr_->paint(); cr_->restore(); cr_->arc(0, 0, m_radius, 0, 2 * M_PI); cr_->save(); cr_->set_source_rgba(1.0, 1.0, 1.0, 0.8); cr_->fill_preserve(); cr_->restore(); cr_->stroke_preserve(); cr_->clip(); //clock ticks for (int i = 0; i < 12; i++) { double inset = 0.05; cr_->save(); cr_->set_line_cap(Cairo::LINE_CAP_ROUND); if(i % 3 != 0) { inset *= 0.8; cr_->set_line_width(0.03); } cr_->move_to( (m_radius - inset) * cos (i * M_PI / 6), (m_radius - inset) * sin (i * M_PI / 6)); cr_->line_to ( m_radius * cos (i * M_PI / 6), m_radius * sin (i * M_PI / 6)); cr_->stroke(); cr_->restore(); // stack-pen-size } // store the current time time_t rawtime; time(&rawtime); struct tm * timeinfo = localtime (&rawtime); // compute the angles of the indicators of our clock double minutes = timeinfo->tm_min * M_PI / 30; double hours = timeinfo->tm_hour * M_PI / 6; double seconds= timeinfo->tm_sec * M_PI / 30; cout<<timeinfo->tm_min<<","<<timeinfo->tm_hour<<","<<timeinfo->tm_sec<<endl; cr_->save(); cr_->set_line_cap(Cairo::LINE_CAP_ROUND); // draw the seconds hand cr_->save(); cr_->set_line_width(m_line_width / 3); cr_->set_source_rgba(0.7, 0.7, 0.7, 0.8); // gray cr_->move_to(0, 0); cr_->line_to(sin(seconds) * (m_radius * 0.9), -cos(seconds) * (m_radius * 0.9)); cr_->stroke(); cr_->restore(); // draw the minutes hand cr_->set_source_rgba(0.117, 0.337, 0.612, 0.9); // blue cr_->move_to(0, 0); cr_->line_to(sin(minutes + seconds / 60) * (m_radius * 0.8), -cos(minutes + seconds / 60) * (m_radius * 0.8)); cr_->stroke(); // draw the hours hand cr_->set_source_rgba(0.337, 0.612, 0.117, 0.9); // green cr_->move_to(0, 0); cr_->line_to(sin(hours + minutes / 12.0) * (m_radius * 0.5), -cos(hours + minutes / 12.0) * (m_radius * 0.5)); cr_->stroke(); cr_->restore(); // draw a little dot in the middle cr_->arc(0, 0, m_line_width / 3.0, 0, 2 * M_PI); cr_->fill(); }
void cairo::draw_triangle( const Cairo::RefPtr<Cairo::Context>& cr, const Geodesics::edge_handle& e0 ) { const rgba_color_t color( .8, .8, .8, .3); // get edge-free pair const Geodesics::edge_handle e1 ( e0.next() ); const Geodesics::edge_handle e2 ( e1.next() ); const coord_t e0l= e0.length(); const coord_t e1l= e1.length(); const coord_t e2l= e2.length(); // coordinates of C - using circle-circle intersection ( intersect circle (w.b0,w.d0) with (w.b1,w.d1) ) cairo_coord_t A(0.,0.); cairo_coord_t B(e0l,0.); cairo_coord_t C; boost::tie(C[0],C[1]) = utk::triangulate( e0l, e2l, e1l ); //C[1] = - C[1]; const coord2_t centroid = ( ( coord2_t(e0l, 0) += C ) /= coord_t(3) ); cr->save(); //cr->set_operator( Cairo::OPERATOR_DEST_OVER ); cr->set_source_rgba( color[0], color[1], color[2], color[3] ); cr->save(); // shrink slightly towards centroid cr->translate( centroid[0], centroid[1] ); cr->scale( .95, .95 ); cr->translate( -centroid[0], -centroid[1] ); //draw triangle cr->set_line_width( 1. * user_unit_distance( cr ).length() ); draw_half_arrow( cr, A, B ); draw_half_arrow( cr, B, C ); draw_half_arrow( cr, C, A ); cr->restore(); cr->stroke(); cr->restore(); // draw text cr->save(); cr->user_to_device( A[0], A[1] ); cr->user_to_device( B[0], B[1] ); cr->user_to_device( C[0], C[1] ); cr->set_identity_matrix(); //cr->select_font_face( "Purisa", Cairo::FONT_SLANT_NORMAL, Cairo::FONT_WEIGHT_NORMAL ); cr->set_source_rgba( 0., 0., 0.,.5 ); cr->set_font_size( 8. /* user_unit_distance( cr ).length()*/ ); std::ostringstream nrss; nrss << e0.source().descriptor(); draw_centered_text( cr, nrss.str(), A ); nrss.str(""); nrss << e1.source().descriptor(); draw_centered_text( cr, nrss.str(), B ); nrss.str(""); nrss << e2.source().descriptor(); draw_centered_text( cr, nrss.str(), C ); cr->restore(); }
void Thing::TransformContext(Cairo::RefPtr<Cairo::Context> myCr) const { myCr->scale(scalingFactor, scalingFactor); myCr->translate(position[0], position[1]); myCr->rotate_degrees(-orientationAngle); }