#include "../include/GtkScaledImage.hpp" #include namespace dchat { GtkScaledImage::GtkScaledImage(const boost::filesystem::path &filepath) { try { auto pixbuf = Gdk::Pixbuf::create_from_file(filepath.string()); Cairo::Format format = pixbuf->get_has_alpha() ? Cairo::Format::FORMAT_ARGB32 : Cairo::Format::FORMAT_RGB24; surface = Cairo::ImageSurface::create(format, pixbuf->get_width(), pixbuf->get_height()); unsigned char *pixels = surface->get_data(); surface->flush(); char *p = (char*)pixbuf->get_pixels(); // TODO: Optimize this if(format == Cairo::Format::FORMAT_ARGB32) { for(int i = 0; i < surface->get_stride() * surface->get_height(); i += 4) { pixels[i + 0] = p[i + 2]; pixels[i + 1] = p[i + 1]; pixels[i + 2] = p[i + 0]; pixels[i + 3] = p[i + 3]; } } else { for(int i = 0; i < surface->get_stride() * surface->get_height(); i += 3) { pixels[i + 0] = p[i + 2]; pixels[i + 1] = p[i + 1]; pixels[i + 2] = p[i + 0]; } } //memcpy(pixels, textureData, surface->get_stride() * surface->get_height()); surface->mark_dirty(); } catch(std::exception &e) { std::string errMsg = "Failed to create scaled image, reason: "; errMsg += e.what(); throw GtkScaledImageException(errMsg); } } void GtkScaledImage::draw(const Cairo::RefPtr &cairo, int width, int height, bool circularMask) { if(circularMask) { int minSize = std::min(width/2, height/2); cairo->arc(width/2, height/2, minSize, 0.0, 2.0 * M_PI); cairo->clip(); } double scaleX = (double)width / (double)surface->get_width(); double scaleY = (double)height / (double)surface->get_height(); cairo->scale(scaleX, scaleY); cairo->set_source(surface, 0.0, 0.0); cairo->mask(surface, 0.0, 0.0); } }