void NodeRenderer::icon(const Cairo::RefPtr<Cairo::Context>& cr, AssetCache& cache) { // path to icon not set if (s->icon_image.str().size() == 0 || s->icon_width == 0.0 || s->icon_height == 0.0) return; cr->save(); Cairo::RefPtr<Cairo::ImageSurface> image = cache.getImage(s->icon_image.str()); double width = s->icon_width < 0 ? image->get_width() : s->icon_width; double height = s->icon_height < 0 ? image->get_height() : s->icon_height; double x0 = floor(location.x - width/2.0); double y0 = floor(location.y - height/2.0); cr->translate(x0, y0); cr->scale(width / image->get_width(), height / image->get_height()); cr->set_source(image, 0, 0); if (s->icon_opacity < 1.0) cr->paint_with_alpha(s->icon_opacity); else cr->paint(); cr->restore(); }
TexturePtr TextSurface::create_opengl_texture(Cairo::RefPtr<Cairo::ImageSurface> surface) { assert(surface); TexturePtr texture = Texture::create_handle(GL_TEXTURE_2D); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->get_width()); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture->get_id()); assert_gl("Texture failure"); // flip RGBA to BGRA for(int y = 0; y < surface->get_height(); ++y) { uint8_t* pixels = surface->get_data() + surface->get_stride() * y; for(int x = 0; x < surface->get_width()*4; x += 4) { uint8_t r = pixels[x+0]; uint8_t g = pixels[x+1]; uint8_t b = pixels[x+2]; uint8_t a = pixels[x+3]; // removing pre-multiplayed alpha if (a != 0) { pixels[x+0] = static_cast<uint8_t>(b * 255 / a); pixels[x+1] = static_cast<uint8_t>(g * 255 / a); pixels[x+2] = static_cast<uint8_t>(r * 255 / a); } // debug foobar //if (pixels[x+3] == 0) // pixels[x+3] = 32; } } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface->get_width(), surface->get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->get_data()); assert_gl("Texture failure"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); return texture; }
Cairo::RefPtr<Cairo::ImageSurface> ImagesStorage::loadFrenchCard(Cairo::RefPtr<Cairo::ImageSurface> sourceImages, Preference::Card card) { Cairo::RefPtr<Cairo::ImageSurface> cardImage = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, sourceImages->get_width() / 13.0, sourceImages->get_height() / 5.0); Cairo::RefPtr<Cairo::Context> cardsImagesDrawer = Cairo::Context::create( cardImage ); cardsImagesDrawer->set_source_rgb(1, 1, 1); double x = getFrenchCardCoord(card, CT_X, sourceImages->get_width()); double y = getFrenchCardCoord(card, CT_Y, sourceImages->get_height()); cardsImagesDrawer->set_source(sourceImages, -x, -y); cardsImagesDrawer->rectangle(0, 0, sourceImages->get_width() / 13.0, sourceImages->get_height() / 5.0); cardsImagesDrawer->clip(); cardsImagesDrawer->paint(); return cardImage; }
Image::Image(const Cairo::RefPtr<Cairo::ImageSurface>& image) : m_width(image->get_width()), m_height(image->get_height()) { unsigned char* data = image->get_data(); size_t length = image->get_width() * image->get_height(); for(size_t i = 0; i < length; ++i) { m_blue.push_back(static_cast<double>(data[i * 4])); m_green.push_back(static_cast<double>(data[i * 4 + 1])); m_red.push_back(static_cast<double>(data[i * 4 + 2])); } }
void glDrawCairoSurface(const Cairo::RefPtr<Cairo::ImageSurface> surface, const Vector2d &min, const Vector2d &max, const double z) { if (surface==0) return; int w = surface->get_width(); int h = surface->get_height(); unsigned char * data = surface->get_data(); GLuint texture; glGenTextures( 1, &texture ); glBindTexture( GL_TEXTURE_2D, texture ); // http://www.nullterminator.net/gltexture.html // select modulate to mix texture with color for shading glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); // when texture area is small, bilinear filter the closest mipmap glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); // when texture area is large, bilinear filter the original glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // build our texture mipmaps gluBuild2DMipmaps( GL_TEXTURE_2D, GL_ALPHA, w, h, GL_ALPHA, GL_UNSIGNED_BYTE, data ); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glTexCoord2d(0.0,0.0); glVertex3d(min.x(),min.y(),z); glTexCoord2d(1.0,0.0); glVertex3d(max.x(),min.y(),z); glTexCoord2d(1.0,1.0); glVertex3d(max.x(),max.y(),z); glTexCoord2d(0.0,1.0); glVertex3d(min.x(),max.y(),z); glEnd(); glDisable(GL_TEXTURE_2D); glDeleteTextures( 1, &texture ); }
std::shared_ptr<TextSurface> TextSurface::create(const std::string& text, const TextProperties& text_props) { Cairo::TextExtents text_extents; Cairo::FontExtents font_extents; Cairo::RefPtr<Cairo::ImageSurface> surface = create_cairo_surface(text, text_props, text_extents, font_extents); int width = surface->get_width(); int height = surface->get_height(); TexturePtr texture = create_opengl_texture(surface); MaterialPtr material = std::make_shared<Material>(); material->set_program(Program::create(Shader::from_file(GL_VERTEX_SHADER, "src/basic_texture.vert"), Shader::from_file(GL_FRAGMENT_SHADER, "src/basic_texture.frag"))); material->enable(GL_BLEND); material->blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); material->set_texture(0, texture); material->set_uniform("texture_diff", 0); material->set_uniform("MVP", UniformSymbol::ModelViewProjectionMatrix); return std::make_shared<TextSurface>(material, width, height, text_extents, font_extents); }
int main() { Cairo::RefPtr<Cairo::ImageSurface> surface = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, 600, 400); 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, surface->get_width(), surface->get_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(surface->get_width() / 2.0, surface->get_height() / 2.0, surface->get_height() / 4.0, 0.0, 2.0 * M_PI); cr->stroke(); // draw a diagonal line cr->move_to(surface->get_width() / 4.0, surface->get_height() / 4.0); cr->line_to(surface->get_width() * 3.0 / 4.0, surface->get_height() * 3.0 / 4.0); cr->stroke(); cr->restore(); #ifdef CAIRO_HAS_PNG_FUNCTIONS std::string filename = "image.png"; surface->write_to_png(filename); std::cout << "Wrote png file \"" << filename << "\"" << std::endl; #else std::cout << "You must compile cairo with PNG support for this example to work." << std::endl; #endif }
RefPtr<Gdk::Pixbuf> GetAsPixbuf(Cairo::RefPtr<Cairo::ImageSurface> sur) { ASSERT( sur->get_format() == Cairo::FORMAT_ARGB32 ); return Gdk::Pixbuf::create_from_data((const guint8*)sur->get_data(), Gdk::COLORSPACE_RGB, true, 8, sur->get_width(), sur->get_height(), sur->get_stride()); }
void CardWidget::Draw(Cairo::RefPtr<Cairo::Context> cr, int x, int y) { bool highlight = highlightOnHover && isMouseInArea; Cairo::RefPtr<Cairo::ImageSurface> image = PrefSlots::getImagesStorage().GetCardImage(card); cr->save(); cr->translate(x, y); cr->scale(1.0 * width / image->get_width(), 1.0 * height / image->get_height()); cr->rectangle(0, 0, image->get_width(), image->get_height()); cr->clip(); if( highlight ) { cr->save(); cr->set_source_rgb(0.1, 0.8, 0.1); cr->paint(); cr->restore(); } cr->set_source(image, 0, 0); cr->paint_with_alpha( highlight ? 0.7 : 1.0 ); cr->restore(); }
/** Post-process files. Only valid for PNGs. */ void postprocess() { printf("Post-processing PNG files, resizing to %fx%f\n", maxwidth, maxheight); struct dirent *d; DIR *output_dir = opendir(outdir.c_str()); while ((d = readdir(output_dir)) != NULL) { if (fnmatch("*.png", d->d_name, FNM_PATHNAME | FNM_PERIOD) == 0) { infile = outdir + "/" + d->d_name; Cairo::RefPtr<Cairo::ImageSurface> imgs = Cairo::ImageSurface::create_from_png(infile); if ( (imgs->get_height() != maxheight) || (imgs->get_width() != maxwidth)) { // need to re-create char *tmpout = strdup((outdir + "/tmpXXXXXX").c_str()); FILE *f = fdopen(mkstemp(tmpout), "w"); outfile = tmpout; free(tmpout); Cairo::RefPtr<Cairo::ImageSurface> outs = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, (int)ceilf(maxwidth), (int)ceilf(maxheight)); double tx = (maxwidth - imgs->get_width()) / 2.0; double ty = (maxheight - imgs->get_height()) / 2.0; printf("Re-creating %s for post-processing, " "resizing from %ix%i, tx=%f, ty=%f\n", infile.c_str(), imgs->get_width(), imgs->get_height(), tx, ty); Cairo::RefPtr<Cairo::Context> cc = Cairo::Context::create(outs); if (white_bg) { cc->set_source_rgb(1, 1, 1); cc->paint(); } cc->set_source(imgs, tx, ty); cc->paint(); outs->write_to_png(&SkillGuiBatchRenderer::write_func, f); imgs.clear(); cc.clear(); outs.clear(); fclose(f); rename(outfile.c_str(), infile.c_str()); } } } closedir(output_dir); }
int getCairoSurfaceDatapoint(const Cairo::RefPtr<Cairo::ImageSurface> surface, const Vector2d &min, const Vector2d &max, const Vector2d &p) { if (surface==0) return 0; const int w = surface->get_stride(); const int h = surface->get_height(); const unsigned char * data = surface->get_data(); const Vector2d diag = max - min; const Vector2d relp = p - min; const int ipx = (int)(relp.x() / diag.x() * (double)w); const int ipy = (int)(relp.y() / diag.y() * (double)h); int value = data[ipy*w + ipx]; return value; }
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 FourdThumbnailer::receive_frame(Cairo::RefPtr<Cairo::ImageSurface> img, gint64 pos) { if (!m_buffer) { m_buffer = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, img->get_width() * 10, img->get_height()); } Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(m_buffer); int slice_width = m_buffer->get_width() / m_slices; cr->rectangle((slice_width * m_count), 0, slice_width, m_buffer->get_height()); cr->clip(); cr->begin_new_path(); cr->set_source(img, m_count * (m_buffer->get_width() - img->get_width()) / (m_slices-1), 0); cr->paint(); m_count += 1; }
void level_editor::tileset_display::update_tileset(const std::string& level_name) { // find the main tileset and draw it first, then the others level_editor::tileset_list_type::iterator main_iter; level_editor::tileset_list_type::iterator iter, end; end = m_preferences.tilesets.end(); main_iter = m_preferences.tilesets.end(); for (iter = m_preferences.tilesets.begin(); iter != end; iter ++) { // prefix matches level name if (iter->main && iter->active && level_name.find(iter->prefix) != std::string::npos) { // prefer tilesets with a longer prefix if (main_iter == end || main_iter->prefix.size() < iter->prefix.size()) { main_iter = iter; } } } Cairo::RefPtr<Cairo::ImageSurface> main; if (main_iter == m_preferences.tilesets.end()) { // No matching main tileset, use default image and display error // TODO: actually display an error box here //std::cerr << // "No valid tileset found, please add atleast one main tileset to the " // "tileset list that matches the current level." << std::endl; main = m_image_cache.get_image("internal/no_img.png"); } else { main = m_image_cache.get_image(main_iter->name); } //std::cout << "creating surface" << std::endl; const int main_width = main->get_width(); const int main_height = main->get_height(); m_surface = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, main_width, main_height); Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create(m_surface); cr->set_source(main, 0, 0); cr->paint(); // now draw the rest end = m_preferences.tilesets.end(); for (iter = m_preferences.tilesets.begin(); iter != end; iter ++) { // prefix matches level name if (level_name.find(iter->prefix) != std::string::npos && !iter->main) { Cairo::RefPtr<Cairo::ImageSurface> ts = m_image_cache.get_image(iter->name); // Ignore other matching main tilesets if (!iter->main && iter->active) { cr->set_source(ts, iter->x, iter->y); } cr->paint(); } } set_size_request(main_width, main_height); queue_draw(); // Fire signal to users m_signal_tileset_updated(m_surface); }