<commit_before>// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gl/gl_image_ozone_native_pixmap.h"

#define FOURCC(a, b, c, d)                                    \
  ((static_cast<uint32>(a)) | (static_cast<uint32>(b) << 8) | \
   (static_cast<uint32>(c) << 16) | (static_cast<uint32>(d) << 24))

#define DRM_FORMAT_ARGB8888 FOURCC('A', 'R', '2', '4')
#define DRM_FORMAT_XRGB8888 FOURCC('X', 'R', '2', '4')

namespace gfx {
namespace {

bool ValidInternalFormat(unsigned internalformat) {
  switch (internalformat) {
    case GL_RGB:
    case GL_BGRA_EXT:
      return true;
    default:
      return false;
  }
}

bool ValidFormat(gfx::BufferFormat format) {
  switch (format) {
    case BufferFormat::BGRA_8888:
    case BufferFormat::RGBX_8888:
      return true;
    case BufferFormat::ATC:
    case BufferFormat::ATCIA:
    case BufferFormat::DXT1:
    case BufferFormat::DXT5:
    case BufferFormat::ETC1:
    case BufferFormat::R_8:
    case BufferFormat::RGBA_4444:
    case BufferFormat::RGBA_8888:
    case BufferFormat::YUV_420:
      return false;
  }

  NOTREACHED();
  return false;
}

EGLint FourCC(gfx::BufferFormat format) {
  switch (format) {
    case BufferFormat::BGRA_8888:
      return DRM_FORMAT_ARGB8888;
    case BufferFormat::RGBX_8888:
      return DRM_FORMAT_XRGB8888;
    case BufferFormat::ATC:
    case BufferFormat::ATCIA:
    case BufferFormat::DXT1:
    case BufferFormat::DXT5:
    case BufferFormat::ETC1:
    case BufferFormat::R_8:
    case BufferFormat::RGBA_4444:
    case BufferFormat::RGBA_8888:
    case BufferFormat::YUV_420:
      NOTREACHED();
      return 0;
  }

  NOTREACHED();
  return 0;
}

}  // namespace

GLImageOzoneNativePixmap::GLImageOzoneNativePixmap(const Size& size,
                                                   unsigned internalformat)
    : GLImageEGL(size), internalformat_(internalformat) {}

GLImageOzoneNativePixmap::~GLImageOzoneNativePixmap() {
  DCHECK(!pixmap_);
}

bool GLImageOzoneNativePixmap::Initialize(ui::NativePixmap* pixmap,
                                          BufferFormat format) {
  DCHECK(!pixmap_);

  bool result = true;
  if (pixmap->GetEGLClientBuffer()) {
    EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
    result = GLImageEGL::Initialize(EGL_NATIVE_PIXMAP_KHR,
                                    pixmap->GetEGLClientBuffer(), attrs);
  } else if (pixmap->GetDmaBufFd() >= 0) {
    if (!ValidInternalFormat(internalformat_)) {
      LOG(ERROR) << "Invalid internalformat: " << internalformat_;
      return false;
    }

    if (!ValidFormat(format)) {
      LOG(ERROR) << "Invalid format: " << static_cast<int>(format);
      return false;
    }

    // Note: If eglCreateImageKHR is successful for a EGL_LINUX_DMA_BUF_EXT
    // target, the EGL will take a reference to the dma_buf.
    EGLint attrs[] = {EGL_WIDTH,
                      size_.width(),
                      EGL_HEIGHT,
                      size_.height(),
                      EGL_LINUX_DRM_FOURCC_EXT,
                      FourCC(format),
                      EGL_DMA_BUF_PLANE0_FD_EXT,
                      pixmap->GetDmaBufFd(),
                      EGL_DMA_BUF_PLANE0_OFFSET_EXT,
                      0,
                      EGL_DMA_BUF_PLANE0_PITCH_EXT,
                      pixmap->GetDmaBufPitch(),
                      EGL_NONE};
    result = GLImageEGL::Initialize(
        EGL_LINUX_DMA_BUF_EXT, static_cast<EGLClientBuffer>(nullptr), attrs);
  }

  if (result)
    pixmap_ = pixmap;
  return result;
}

unsigned GLImageOzoneNativePixmap::GetInternalFormat() {
  return internalformat_;
}

void GLImageOzoneNativePixmap::Destroy(bool have_context) {
  GLImageEGL::Destroy(have_context);
  pixmap_ = nullptr;
}

bool GLImageOzoneNativePixmap::ScheduleOverlayPlane(AcceleratedWidget widget,
                                                    int z_order,
                                                    OverlayTransform transform,
                                                    const Rect& bounds_rect,
                                                    const RectF& crop_rect) {
  DCHECK(pixmap_);
  return pixmap_->ScheduleOverlayPlane(widget, z_order, transform, bounds_rect,
                                       crop_rect);
}

}  // namespace gfx
<commit_msg>Ozone: Keep the native pixmap alive till gl_image is destroyed<commit_after>// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gl/gl_image_ozone_native_pixmap.h"

#define FOURCC(a, b, c, d)                                    \
  ((static_cast<uint32>(a)) | (static_cast<uint32>(b) << 8) | \
   (static_cast<uint32>(c) << 16) | (static_cast<uint32>(d) << 24))

#define DRM_FORMAT_ARGB8888 FOURCC('A', 'R', '2', '4')
#define DRM_FORMAT_XRGB8888 FOURCC('X', 'R', '2', '4')

namespace gfx {
namespace {

bool ValidInternalFormat(unsigned internalformat) {
  switch (internalformat) {
    case GL_RGB:
    case GL_BGRA_EXT:
      return true;
    default:
      return false;
  }
}

bool ValidFormat(gfx::BufferFormat format) {
  switch (format) {
    case BufferFormat::BGRA_8888:
    case BufferFormat::RGBX_8888:
      return true;
    case BufferFormat::ATC:
    case BufferFormat::ATCIA:
    case BufferFormat::DXT1:
    case BufferFormat::DXT5:
    case BufferFormat::ETC1:
    case BufferFormat::R_8:
    case BufferFormat::RGBA_4444:
    case BufferFormat::RGBA_8888:
    case BufferFormat::YUV_420:
      return false;
  }

  NOTREACHED();
  return false;
}

EGLint FourCC(gfx::BufferFormat format) {
  switch (format) {
    case BufferFormat::BGRA_8888:
      return DRM_FORMAT_ARGB8888;
    case BufferFormat::RGBX_8888:
      return DRM_FORMAT_XRGB8888;
    case BufferFormat::ATC:
    case BufferFormat::ATCIA:
    case BufferFormat::DXT1:
    case BufferFormat::DXT5:
    case BufferFormat::ETC1:
    case BufferFormat::R_8:
    case BufferFormat::RGBA_4444:
    case BufferFormat::RGBA_8888:
    case BufferFormat::YUV_420:
      NOTREACHED();
      return 0;
  }

  NOTREACHED();
  return 0;
}

}  // namespace

GLImageOzoneNativePixmap::GLImageOzoneNativePixmap(const Size& size,
                                                   unsigned internalformat)
    : GLImageEGL(size), internalformat_(internalformat) {}

GLImageOzoneNativePixmap::~GLImageOzoneNativePixmap() {
}

bool GLImageOzoneNativePixmap::Initialize(ui::NativePixmap* pixmap,
                                          BufferFormat format) {
  DCHECK(!pixmap_);

  bool result = true;
  if (pixmap->GetEGLClientBuffer()) {
    EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
    result = GLImageEGL::Initialize(EGL_NATIVE_PIXMAP_KHR,
                                    pixmap->GetEGLClientBuffer(), attrs);
  } else if (pixmap->GetDmaBufFd() >= 0) {
    if (!ValidInternalFormat(internalformat_)) {
      LOG(ERROR) << "Invalid internalformat: " << internalformat_;
      return false;
    }

    if (!ValidFormat(format)) {
      LOG(ERROR) << "Invalid format: " << static_cast<int>(format);
      return false;
    }

    // Note: If eglCreateImageKHR is successful for a EGL_LINUX_DMA_BUF_EXT
    // target, the EGL will take a reference to the dma_buf.
    EGLint attrs[] = {EGL_WIDTH,
                      size_.width(),
                      EGL_HEIGHT,
                      size_.height(),
                      EGL_LINUX_DRM_FOURCC_EXT,
                      FourCC(format),
                      EGL_DMA_BUF_PLANE0_FD_EXT,
                      pixmap->GetDmaBufFd(),
                      EGL_DMA_BUF_PLANE0_OFFSET_EXT,
                      0,
                      EGL_DMA_BUF_PLANE0_PITCH_EXT,
                      pixmap->GetDmaBufPitch(),
                      EGL_NONE};
    result = GLImageEGL::Initialize(
        EGL_LINUX_DMA_BUF_EXT, static_cast<EGLClientBuffer>(nullptr), attrs);
  }

  if (result)
    pixmap_ = pixmap;
  return result;
}

unsigned GLImageOzoneNativePixmap::GetInternalFormat() {
  return internalformat_;
}

void GLImageOzoneNativePixmap::Destroy(bool have_context) {
  GLImageEGL::Destroy(have_context);
}

bool GLImageOzoneNativePixmap::ScheduleOverlayPlane(AcceleratedWidget widget,
                                                    int z_order,
                                                    OverlayTransform transform,
                                                    const Rect& bounds_rect,
                                                    const RectF& crop_rect) {
  DCHECK(pixmap_);
  return pixmap_->ScheduleOverlayPlane(widget, z_order, transform, bounds_rect,
                                       crop_rect);
}

}  // namespace gfx
<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS ooo19126 (1.7.60); FILE MERGED 2005/09/05 14:01:02 rt 1.7.60.1: #i54170# Change license header: remove SISSL<commit_after><|endoftext|>


<commit_before>// Refer to https://github.com/philsquared/Catch/blob/master/docs/own-main.md
// for providing our own main function to Catch
#define CATCH_CONFIG_RUNNER

#include <catch.hpp>

// To enable log messages:
// #define ENABLE_LOGGING

#ifdef ENABLE_LOGGING
#define LEATHERMAN_LOGGING_NAMESPACE "puppetlabs.pxp-agent.test"
#include <leatherman/logging/logging.hpp>
#endif

int main(int argc, char* const argv[]) {
#ifdef ENABLE_LOGGING
    leatherman::logging::set_level(leatherman::logging::log_level::debug);
#endif

    // configure the Catch session and start it
    Catch::Session test_session;
    test_session.applyCommandLine(argc, argv);

    // To list the reporters use:
    // test_session.configData().listReporters = true;

    // Reporters: "xml", "junit", "console", "compact"
    test_session.configData().reporterName = "console";

    // ShowDurations::Always, ::Never, ::DefaultForReporter
    test_session.configData().showDurations = Catch::ShowDurations::Always;

    return test_session.run();
}
<commit_msg>(PCP-374) Update Catch configuration<commit_after>// Refer to https://github.com/philsquared/Catch/blob/master/docs/own-main.md
// for providing our own main function to Catch
#define CATCH_CONFIG_RUNNER

#include <catch.hpp>

#include <boost/nowide/iostream.hpp>

#include <vector>

// To enable log messages:
//#define ENABLE_LOGGING

#ifdef ENABLE_LOGGING
#define LEATHERMAN_LOGGING_NAMESPACE "puppetlabs.cpp_pcp_client.test"
#include <leatherman/logging/logging.hpp>
#endif

int main(int argc, const char** argv) {
#ifdef ENABLE_LOGGING
    leatherman::logging::setup_logging(boost::nowide::cout);
    leatherman::logging::set_level(leatherman::logging::log_level::debug);
#endif

    // Create the Catch session, pass CL args, and start it
    Catch::Session test_session {};
    test_session.applyCommandLine(argc, argv);

    // NOTE(ale): to list the reporters use:
    // test_session.configData().listReporters = true;

    // Reporters: "xml", "junit", "console", and "compact" (single line)
    test_session.configData().reporterNames =
            std::vector<std::string> { "console" };

    // ShowDurations::Always, ::Never, ::DefaultForReporter
    test_session.configData().showDurations = Catch::ShowDurations::Always;

    // NOTE(ale): enforcing ConfigData::useColour == UseColour::No
    // on Windows is not necessary; the default ::Auto works fine

    return test_session.run();
}
<|endoftext|>


<commit_before>#include "pathfinder.h"

#include "stringtools.h"

#include <cassert>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <vector>

#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>

using namespace std;

static string homeDir()
{
    const char *home = getenv("HOME"); // this overrides the entry in /etc/passwd
    if (!home) {
        // from /etc/passwd (or a similar mechanism)
        // ### user's storage is static; consider using getpwuid_r though!
        struct passwd *user = getpwuid(getuid());
        if (user) {
            home = user->pw_dir;
        }
    }
    assert(home);
    return string(home);
}

static string sessionInfoFile()
{
    static const int numMachineUuidFilenames = 2;
    static const char *machineUuidFilenames[numMachineUuidFilenames] = {
        "/var/lib/dbus/machine-id",
        "/etc/machine-id"
    };

    string uuid;
    for (int i = 0; i < numMachineUuidFilenames && uuid.empty(); i++) {
        ifstream uuidFile(machineUuidFilenames[i]);
        uuidFile >> uuid;
        // TODO check that uuid consists of lowercase hex chars
    }
    if (uuid.length() != 32) {
        return string();
    }

    const char *displayChar = getenv("DISPLAY");
    if (!displayChar) {
        // TODO error message "no X11 session blah"
        return string();
    }
    string display = displayChar;
    // TODO from the original: "Note that we leave the hostname in the display most of the time"
    size_t lastColon = display.rfind(':');
    if (lastColon == string::npos) {
        return string();
    }
    display.erase(0, lastColon + 1);

    static const char *pathInHome = "/.dbus/session-bus/";
    string ret = homeDir() + pathInHome + uuid + '-' + display;
    return ret;
}

SessionBusInfo::SessionBusInfo(string str)
   : addressType(InvalidAddress)
{
    AddressType provisionalType = InvalidAddress;

    string unixAddressPrefix = "unix:";
    if (str.find(unixAddressPrefix) == 0) {
        provisionalType = LocalSocketFile;
        str.erase(0, unixAddressPrefix.length());
    }

    // TODO is there any escaping?
    const std::vector<string> parts = split(str, ',');

    if (provisionalType == LocalSocketFile) {
        string pathLiteral = "path=";
        string abstractLiteral = "abstract=";
        // TODO what about "guid=..." and "tmpdir=..."?

        for (int i = 0; i < parts.size(); i++) {
            const string &part = parts[i];
            if (part.find(pathLiteral) == 0) {
                if (addressType != InvalidAddress) {
                    goto invalid; // error - duplicate path specification
                }
                addressType = LocalSocketFile;
                path = part.substr(pathLiteral.length());
            } else if (part.find(abstractLiteral) == 0) {
                if (addressType != InvalidAddress) {
                    goto invalid;
                }
                addressType = AbstractLocalSocket;
                // by adding the \0 that signals a virtual socket address (see man 7 unix on
                // a Linux system) here already, we don't need to pass a whole SessionBusInfo
                // to the LocalSocket constructor, which makes it more flexible.
                // this might need some re-thinking.
                path = string(1, '\0') + part.substr(abstractLiteral.length());
            }
        }
    }
    return;
invalid:
    addressType = InvalidAddress;
    path.clear();
}

SessionBusInfo::SessionBusInfo()
    : addressType(InvalidAddress)
{}

//static
SessionBusInfo PathFinder::sessionBusInfo()
{
    ifstream infoFile(sessionInfoFile().c_str());

    string line;

    // try the environment variable
    const char *envAddress = getenv("DBUS_SESSION_BUS_ADDRESS");
    if (envAddress) {
        line = envAddress;
    } else {
        // try it using a byzantine system involving files...
        string busAddressPrefix = "DBUS_SESSION_BUS_ADDRESS=";
        while (getline(infoFile, line)) {
            // TODO do we need any of the other information in the file?
            if (line.find(busAddressPrefix) == 0 ) {
                line = line.substr(busAddressPrefix.length());
                break;
            }
        }
    }

    return SessionBusInfo(line);
}
<commit_msg>Add a note about yet another way to find the session bus.<commit_after>#include "pathfinder.h"

#include "stringtools.h"

#include <cassert>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <vector>

#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>

using namespace std;

static string homeDir()
{
    const char *home = getenv("HOME"); // this overrides the entry in /etc/passwd
    if (!home) {
        // from /etc/passwd (or a similar mechanism)
        // ### user's storage is static; consider using getpwuid_r though!
        struct passwd *user = getpwuid(getuid());
        if (user) {
            home = user->pw_dir;
        }
    }
    assert(home);
    return string(home);
}

static string sessionInfoFile()
{
    static const int numMachineUuidFilenames = 2;
    static const char *machineUuidFilenames[numMachineUuidFilenames] = {
        "/var/lib/dbus/machine-id",
        "/etc/machine-id"
    };

    string uuid;
    for (int i = 0; i < numMachineUuidFilenames && uuid.empty(); i++) {
        ifstream uuidFile(machineUuidFilenames[i]);
        uuidFile >> uuid;
        // TODO check that uuid consists of lowercase hex chars
    }
    if (uuid.length() != 32) {
        return string();
    }

    const char *displayChar = getenv("DISPLAY");
    if (!displayChar) {
        // TODO error message "no X11 session blah"
        return string();
    }
    string display = displayChar;
    // TODO from the original: "Note that we leave the hostname in the display most of the time"
    size_t lastColon = display.rfind(':');
    if (lastColon == string::npos) {
        return string();
    }
    display.erase(0, lastColon + 1);

    static const char *pathInHome = "/.dbus/session-bus/";
    string ret = homeDir() + pathInHome + uuid + '-' + display;
    return ret;
}

SessionBusInfo::SessionBusInfo(string str)
   : addressType(InvalidAddress)
{
    AddressType provisionalType = InvalidAddress;

    string unixAddressPrefix = "unix:";
    if (str.find(unixAddressPrefix) == 0) {
        provisionalType = LocalSocketFile;
        str.erase(0, unixAddressPrefix.length());
    }

    // TODO is there any escaping?
    const std::vector<string> parts = split(str, ',');

    if (provisionalType == LocalSocketFile) {
        string pathLiteral = "path=";
        string abstractLiteral = "abstract=";
        // TODO what about "guid=..." and "tmpdir=..."?

        for (int i = 0; i < parts.size(); i++) {
            const string &part = parts[i];
            if (part.find(pathLiteral) == 0) {
                if (addressType != InvalidAddress) {
                    goto invalid; // error - duplicate path specification
                }
                addressType = LocalSocketFile;
                path = part.substr(pathLiteral.length());
            } else if (part.find(abstractLiteral) == 0) {
                if (addressType != InvalidAddress) {
                    goto invalid;
                }
                addressType = AbstractLocalSocket;
                // by adding the \0 that signals a virtual socket address (see man 7 unix on
                // a Linux system) here already, we don't need to pass a whole SessionBusInfo
                // to the LocalSocket constructor, which makes it more flexible.
                // this might need some re-thinking.
                path = string(1, '\0') + part.substr(abstractLiteral.length());
            }
        }
    }
    return;
invalid:
    addressType = InvalidAddress;
    path.clear();
}

SessionBusInfo::SessionBusInfo()
    : addressType(InvalidAddress)
{}

//static
SessionBusInfo PathFinder::sessionBusInfo()
{
    ifstream infoFile(sessionInfoFile().c_str());

    string line;

    // TODO: on X, the spec requires a special way to find the session bus

    // try the environment variable
    const char *envAddress = getenv("DBUS_SESSION_BUS_ADDRESS");
    if (envAddress) {
        line = envAddress;
    } else {
        // try it using a byzantine system involving files...
        string busAddressPrefix = "DBUS_SESSION_BUS_ADDRESS=";
        while (getline(infoFile, line)) {
            // TODO do we need any of the other information in the file?
            if (line.find(busAddressPrefix) == 0 ) {
                line = line.substr(busAddressPrefix.length());
                break;
            }
        }
    }

    return SessionBusInfo(line);
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

// mapnik
#include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_helpers.hpp>
#include <mapnik/agg_rasterizer.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/expression_evaluator.hpp>

// agg
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
// for polygon_pattern_symbolizer
#include "agg_renderer_scanline.h"
#include "agg_span_allocator.h"
#include "agg_span_pattern_rgba.h"
#include "agg_image_accessors.h"
#include "agg_conv_clip_polygon.h"

namespace mapnik {

template <typename T>
void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,
                              mapnik::feature_ptr const& feature,
                              proj_transform const& prj_trans)
{
    typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type;
    typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
    typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
    typedef agg::wrap_mode_repeat wrap_x_type;
    typedef agg::wrap_mode_repeat wrap_y_type;
    typedef agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32_plain,
        agg::row_accessor<agg::int8u>, agg::pixel32_type> rendering_buffer;
    typedef agg::image_accessor_wrap<rendering_buffer,
        wrap_x_type,
        wrap_y_type> img_source_type;

    typedef agg::span_pattern_rgba<img_source_type> span_gen_type;

    typedef agg::renderer_scanline_aa<ren_base,
        agg::span_allocator<agg::rgba8>,
        span_gen_type> renderer_type;

    agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
    agg::pixfmt_rgba32 pixf(buf);
    ren_base renb(pixf);

    agg::scanline_u8 sl;
    ras_ptr->reset();
    set_gamma_method(sym,ras_ptr);

    std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature);
    boost::optional<mapnik::marker_ptr> marker;
    if ( !filename.empty() )
    {
        marker = marker_cache::instance()->find(filename, true);
    }
    else
    {
        std::clog << "### Warning: file not found: " << filename << "\n";
    }

    if (!marker) return;

    if (!(*marker)->is_bitmap())
    {
        std::clog << "### Warning only images (not '" << filename << "') are supported in the polygon_pattern_symbolizer\n";
        return;
    }

    boost::optional<image_ptr> pat = (*marker)->get_bitmap_data();

    if (!pat) return;

    unsigned w=(*pat)->width();
    unsigned h=(*pat)->height();
    agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)(*pat)->getBytes(),w,h,w*4);
    agg::span_allocator<agg::rgba8> sa;
    agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32_plain,
        agg::row_accessor<agg::int8u>, agg::pixel32_type> pixf_pattern(pattern_rbuf);
    img_source_type img_src(pixf_pattern);

    unsigned num_geometries = feature->num_geometries();

    pattern_alignment_e align = sym.get_alignment();
    unsigned offset_x=0;
    unsigned offset_y=0;

    if (align == LOCAL_ALIGNMENT)
    {
        double x0=0,y0=0;
        if (num_geometries>0) // FIXME: hmm...?
        {
            clipped_geometry_type clipped(feature->get_geometry(0));
            clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
            path_type path(t_,clipped,prj_trans);
            path.vertex(&x0,&y0);
        }
        offset_x = unsigned(width_-x0);
        offset_y = unsigned(height_-y0);
    }

    span_gen_type sg(img_src, offset_x, offset_y);
    renderer_type rp(renb,sa, sg);
    //metawriter_with_properties writer = sym.get_metawriter();
    for (unsigned i=0;i<num_geometries;++i)
    {
        geometry_type & geom = feature->get_geometry(i);
        if (geom.num_points() > 2)
        {
            clipped_geometry_type clipped(geom);
            clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
            path_type path(t_,clipped,prj_trans);
            ras_ptr->add_path(path);
            //if (writer.first) writer.first->add_polygon(path, *feature, t_, writer.second);
        }
    }
    agg::render_scanlines(*ras_ptr, sl, rp);
}

template void agg_renderer<image_32>::process(polygon_pattern_symbolizer const&,
                                              mapnik::feature_ptr const&,
                                              proj_transform const&);

}

<commit_msg>+ use vertex_converters<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/
//$Id$

// mapnik
#include <mapnik/agg_renderer.hpp>
#include <mapnik/agg_helpers.hpp>
#include <mapnik/agg_rasterizer.hpp>
#include <mapnik/marker.hpp>
#include <mapnik/marker_cache.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/vertex_converters.hpp>
// agg
#include "agg_basics.h"
#include "agg_rendering_buffer.h"
#include "agg_pixfmt_rgba.h"
#include "agg_rasterizer_scanline_aa.h"
#include "agg_scanline_u.h"
// for polygon_pattern_symbolizer
#include "agg_renderer_scanline.h"
#include "agg_span_allocator.h"
#include "agg_span_pattern_rgba.h"
#include "agg_image_accessors.h"
#include "agg_conv_clip_polygon.h"

namespace mapnik {

template <typename T>
void agg_renderer<T>::process(polygon_pattern_symbolizer const& sym,
                              mapnik::feature_ptr const& feature,
                              proj_transform const& prj_trans)
{
    typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type;
    typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
    typedef agg::renderer_base<agg::pixfmt_rgba32> ren_base;
    typedef agg::wrap_mode_repeat wrap_x_type;
    typedef agg::wrap_mode_repeat wrap_y_type;
    typedef agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32_plain,
        agg::row_accessor<agg::int8u>, agg::pixel32_type> rendering_buffer;
    typedef agg::image_accessor_wrap<rendering_buffer,
        wrap_x_type,
        wrap_y_type> img_source_type;

    typedef agg::span_pattern_rgba<img_source_type> span_gen_type;

    typedef agg::renderer_scanline_aa<ren_base,
        agg::span_allocator<agg::rgba8>,
        span_gen_type> renderer_type;

    agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
    agg::pixfmt_rgba32 pixf(buf);
    ren_base renb(pixf);

    agg::scanline_u8 sl;
    ras_ptr->reset();
    set_gamma_method(sym,ras_ptr);

    std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature);
    boost::optional<mapnik::marker_ptr> marker;
    if ( !filename.empty() )
    {
        marker = marker_cache::instance()->find(filename, true);
    }
    else
    {
        std::clog << "### Warning: file not found: " << filename << "\n";
    }

    if (!marker) return;

    if (!(*marker)->is_bitmap())
    {
        std::clog << "### Warning only images (not '" << filename << "') are supported in the polygon_pattern_symbolizer\n";
        return;
    }

    boost::optional<image_ptr> pat = (*marker)->get_bitmap_data();

    if (!pat) return;

    unsigned w=(*pat)->width();
    unsigned h=(*pat)->height();
    agg::row_accessor<agg::int8u> pattern_rbuf((agg::int8u*)(*pat)->getBytes(),w,h,w*4);
    agg::span_allocator<agg::rgba8> sa;
    agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32_plain,
        agg::row_accessor<agg::int8u>, agg::pixel32_type> pixf_pattern(pattern_rbuf);
    img_source_type img_src(pixf_pattern);

    unsigned num_geometries = feature->num_geometries();

    pattern_alignment_e align = sym.get_alignment();
    unsigned offset_x=0;
    unsigned offset_y=0;

    if (align == LOCAL_ALIGNMENT)
    {
        double x0=0,y0=0;
        if (num_geometries>0) // FIXME: hmm...?
        {
            clipped_geometry_type clipped(feature->get_geometry(0));
            clipped.clip_box(query_extent_.minx(),query_extent_.miny(),query_extent_.maxx(),query_extent_.maxy());
            path_type path(t_,clipped,prj_trans);
            path.vertex(&x0,&y0);
        }
        offset_x = unsigned(width_-x0);
        offset_y = unsigned(height_-y0);
    }

    span_gen_type sg(img_src, offset_x, offset_y);
    renderer_type rp(renb,sa, sg);

    //metawriter_with_properties writer = sym.get_metawriter();

    box2d<double> inflated_extent = query_extent_ * 1.1;
    typedef boost::mpl::vector<clip_poly_tag,transform_tag> conv_types;
    vertex_converter<box2d<double>,rasterizer,polygon_pattern_symbolizer, proj_transform, CoordTransform,conv_types>
        converter(inflated_extent,*ras_ptr,sym,t_,prj_trans);

    //if (sym.clip())
    converter.set<clip_poly_tag>(); //optional clip (default: true)
    converter.set<transform_tag>(); //always transform
    //if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter

    for (unsigned i=0;i<num_geometries;++i)
    {
        geometry_type & geom = feature->get_geometry(i);
        if (geom.num_points() > 2)
        {
            converter.apply(geom);
        }
    }

    agg::render_scanlines(*ras_ptr, sl, rp);
}

template void agg_renderer<image_32>::process(polygon_pattern_symbolizer const&,
                                              mapnik::feature_ptr const&,
                                              proj_transform const&);

}

<|endoftext|>


<commit_before><commit_msg>fastmodel: remove incorrect cntfrq update<commit_after><|endoftext|>


<commit_before>// Copyright 2010-2012 RethinkDB, all rights reserved.
#ifndef CLUSTERING_REACTOR_NAMESPACE_INTERFACE_HPP_
#define CLUSTERING_REACTOR_NAMESPACE_INTERFACE_HPP_

#include <math.h>

#include <algorithm>
#include <map>
#include <string>
#include <vector>
#include <set>

#include "errors.hpp"
#include <boost/ptr_container/ptr_vector.hpp>

#include "arch/timing.hpp"
#include "clustering/generic/resource.hpp"
#include "clustering/reactor/metadata.hpp"
#include "containers/clone_ptr.hpp"
#include "containers/cow_ptr.hpp"
#include "concurrency/fifo_enforcer.hpp"
#include "concurrency/pmap.hpp"
#include "concurrency/promise.hpp"
#include "concurrency/watchable.hpp"
#include "protocol_api.hpp"
#include "rdb_protocol/protocol.hpp"

template <class> class cow_ptr_t;
class master_access_t;
template <class protocol_t> class resource_access_t;
class resource_lost_exc_t;
template <class> class watchable_t;
template <class> class watchable_subscription_t;

class cluster_namespace_interface_t : public namespace_interface_t {
public:
    cluster_namespace_interface_t(
            mailbox_manager_t *mm,
            clone_ptr_t<watchable_t<std::map<peer_id_t, cow_ptr_t<reactor_business_card_t> > > > dv,
            rdb_context_t *);

    /* Returns a signal that will be pulsed when we have either successfully
    connected or tried and failed to connect to every master that was present
    at the time that the constructor was called. This is to avoid the case where
    we get errors like "lost contact with master" when really we just haven't
    finished connecting yet. */
    signal_t *get_initial_ready_signal() {
        return &start_cond;
    }

    void read(const read_t &r, read_response_t *response, order_token_t order_token, signal_t *interruptor) THROWS_ONLY(interrupted_exc_t, cannot_perform_query_exc_t);

    void read_outdated(const read_t &r, read_response_t *response, signal_t *interruptor) THROWS_ONLY(interrupted_exc_t, cannot_perform_query_exc_t);

    void write(const write_t &w, write_response_t *response, order_token_t order_token, signal_t *interruptor) THROWS_ONLY(interrupted_exc_t, cannot_perform_query_exc_t);

    std::set<region_t> get_sharding_scheme() THROWS_ONLY(cannot_perform_query_exc_t);

private:
    class relationship_t {
    public:
        bool is_local;
        region_t region;
        master_access_t *master_access;
        resource_access_t<direct_reader_business_card_t> *direct_reader_access;
        auto_drainer_t drainer;
    };

    /* The code for handling immediate reads is 99% the same as the code for
    handling writes, so it's factored out into the `dispatch_immediate_op()`
    function. */

    template <class op_type, class fifo_enforcer_token_type>
    class immediate_op_info_t {
    public:
        op_type sharded_op;
        master_access_t *master_access;
        fifo_enforcer_token_type enforcement_token;
        auto_drainer_t::lock_t keepalive;
    };

    class outdated_read_info_t {
    public:
        read_t sharded_op;
        resource_access_t<direct_reader_business_card_t> *direct_reader_access;
        auto_drainer_t::lock_t keepalive;
    };

    template <class op_type, class fifo_enforcer_token_type, class op_response_type>
    void dispatch_immediate_op(
            /* `how_to_make_token` and `how_to_run_query` have type pointer-to-member-function. */
            void (master_access_t::*how_to_make_token)(fifo_enforcer_token_type *),  // NOLINT
            void (master_access_t::*how_to_run_query)(const op_type &, op_response_type *response, order_token_t, fifo_enforcer_token_type *, signal_t *) THROWS_ONLY(interrupted_exc_t, resource_lost_exc_t, cannot_perform_query_exc_t),
            const op_type &op,
            op_response_type *response,
            order_token_t order_token,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t, cannot_perform_query_exc_t);

    // The exception specification of `how_to_run_query` is commented out in
    // order to bypass a clang bug seen on certain versions for OS X, or perhaps
    // fix a confusing violation of C++.  This function is called only by
    // dispatch_immediate_op, which still has the exception specification.
    template <class op_type, class fifo_enforcer_token_type, class op_response_type>
    void perform_immediate_op(
            void (master_access_t::*how_to_run_query)(const op_type &, op_response_type *, order_token_t, fifo_enforcer_token_type *, signal_t *) /* THROWS_ONLY(interrupted_exc_t, resource_lost_exc_t, cannot_perform_query_exc_t) */,
            boost::ptr_vector<immediate_op_info_t<op_type, fifo_enforcer_token_type> > *masters_to_contact,
            std::vector<op_response_type> *results,
            std::vector<std::string> *failures,
            order_token_t order_token,
            int i,
            signal_t *interruptor)
        THROWS_NOTHING;

    void dispatch_outdated_read(
            const read_t &op,
            read_response_t *response,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t, cannot_perform_query_exc_t);

    void perform_outdated_read(
            boost::ptr_vector<outdated_read_info_t> *direct_readers_to_contact,
            std::vector<read_response_t> *results,
            std::vector<std::string> *failures,
            int i,
            signal_t *interruptor)
        THROWS_NOTHING;

    void update_registrants(bool is_start);

    static boost::optional<boost::optional<master_business_card_t> > extract_master_business_card(const std::map<peer_id_t, cow_ptr_t<reactor_business_card_t> > &map, const peer_id_t &peer, const reactor_activity_id_t &activity_id);
    static boost::optional<boost::optional<direct_reader_business_card_t> > extract_direct_reader_business_card_from_primary(const std::map<peer_id_t, cow_ptr_t<reactor_business_card_t> > &map, const peer_id_t &peer, const reactor_activity_id_t &activity_id);

    static boost::optional<boost::optional<direct_reader_business_card_t> > extract_direct_reader_business_card_from_secondary(const std::map<peer_id_t, cow_ptr_t<reactor_business_card_t> > &map, const peer_id_t &peer, const reactor_activity_id_t &activity_id);

    void relationship_coroutine(peer_id_t peer_id, reactor_activity_id_t activity_id,
                                bool is_start, bool is_primary, const region_t &region,
                                auto_drainer_t::lock_t lock) THROWS_NOTHING;

    mailbox_manager_t *mailbox_manager;
    clone_ptr_t<watchable_t<std::map<peer_id_t, cow_ptr_t<reactor_business_card_t> > > > directory_view;
    rdb_context_t *ctx;

    rng_t distributor_rng;

    std::set<reactor_activity_id_t> handled_activity_ids;
    region_map_t<std::set<relationship_t *> > relationships;

    /* `start_cond` will be pulsed when we have either successfully connected to
    or tried and failed to connect to every peer present when the constructor
    was called. `start_count` is the number of peers we're still waiting for. */
    int start_count;
    cond_t start_cond;

    auto_drainer_t relationship_coroutine_auto_drainer;

    scoped_ptr_t<watchable_subscription_t<std::map<peer_id_t, cow_ptr_t<reactor_business_card_t> > > > watcher_subscription;

    DISABLE_COPYING(cluster_namespace_interface_t);
};

#endif /* CLUSTERING_REACTOR_NAMESPACE_INTERFACE_HPP_ */
<commit_msg>Removed weird protocol_t keyword for resource_access_t declaration.<commit_after>// Copyright 2010-2012 RethinkDB, all rights reserved.
#ifndef CLUSTERING_REACTOR_NAMESPACE_INTERFACE_HPP_
#define CLUSTERING_REACTOR_NAMESPACE_INTERFACE_HPP_

#include <math.h>

#include <algorithm>
#include <map>
#include <string>
#include <vector>
#include <set>

#include "errors.hpp"
#include <boost/ptr_container/ptr_vector.hpp>

#include "arch/timing.hpp"
#include "clustering/generic/resource.hpp"
#include "clustering/reactor/metadata.hpp"
#include "containers/clone_ptr.hpp"
#include "containers/cow_ptr.hpp"
#include "concurrency/fifo_enforcer.hpp"
#include "concurrency/pmap.hpp"
#include "concurrency/promise.hpp"
#include "concurrency/watchable.hpp"
#include "protocol_api.hpp"
#include "rdb_protocol/protocol.hpp"

template <class> class cow_ptr_t;
class master_access_t;
template <class> class resource_access_t;
class resource_lost_exc_t;
template <class> class watchable_t;
template <class> class watchable_subscription_t;

class cluster_namespace_interface_t : public namespace_interface_t {
public:
    cluster_namespace_interface_t(
            mailbox_manager_t *mm,
            clone_ptr_t<watchable_t<std::map<peer_id_t, cow_ptr_t<reactor_business_card_t> > > > dv,
            rdb_context_t *);

    /* Returns a signal that will be pulsed when we have either successfully
    connected or tried and failed to connect to every master that was present
    at the time that the constructor was called. This is to avoid the case where
    we get errors like "lost contact with master" when really we just haven't
    finished connecting yet. */
    signal_t *get_initial_ready_signal() {
        return &start_cond;
    }

    void read(const read_t &r, read_response_t *response, order_token_t order_token, signal_t *interruptor) THROWS_ONLY(interrupted_exc_t, cannot_perform_query_exc_t);

    void read_outdated(const read_t &r, read_response_t *response, signal_t *interruptor) THROWS_ONLY(interrupted_exc_t, cannot_perform_query_exc_t);

    void write(const write_t &w, write_response_t *response, order_token_t order_token, signal_t *interruptor) THROWS_ONLY(interrupted_exc_t, cannot_perform_query_exc_t);

    std::set<region_t> get_sharding_scheme() THROWS_ONLY(cannot_perform_query_exc_t);

private:
    class relationship_t {
    public:
        bool is_local;
        region_t region;
        master_access_t *master_access;
        resource_access_t<direct_reader_business_card_t> *direct_reader_access;
        auto_drainer_t drainer;
    };

    /* The code for handling immediate reads is 99% the same as the code for
    handling writes, so it's factored out into the `dispatch_immediate_op()`
    function. */

    template <class op_type, class fifo_enforcer_token_type>
    class immediate_op_info_t {
    public:
        op_type sharded_op;
        master_access_t *master_access;
        fifo_enforcer_token_type enforcement_token;
        auto_drainer_t::lock_t keepalive;
    };

    class outdated_read_info_t {
    public:
        read_t sharded_op;
        resource_access_t<direct_reader_business_card_t> *direct_reader_access;
        auto_drainer_t::lock_t keepalive;
    };

    template <class op_type, class fifo_enforcer_token_type, class op_response_type>
    void dispatch_immediate_op(
            /* `how_to_make_token` and `how_to_run_query` have type pointer-to-member-function. */
            void (master_access_t::*how_to_make_token)(fifo_enforcer_token_type *),  // NOLINT
            void (master_access_t::*how_to_run_query)(const op_type &, op_response_type *response, order_token_t, fifo_enforcer_token_type *, signal_t *) THROWS_ONLY(interrupted_exc_t, resource_lost_exc_t, cannot_perform_query_exc_t),
            const op_type &op,
            op_response_type *response,
            order_token_t order_token,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t, cannot_perform_query_exc_t);

    // The exception specification of `how_to_run_query` is commented out in
    // order to bypass a clang bug seen on certain versions for OS X, or perhaps
    // fix a confusing violation of C++.  This function is called only by
    // dispatch_immediate_op, which still has the exception specification.
    template <class op_type, class fifo_enforcer_token_type, class op_response_type>
    void perform_immediate_op(
            void (master_access_t::*how_to_run_query)(const op_type &, op_response_type *, order_token_t, fifo_enforcer_token_type *, signal_t *) /* THROWS_ONLY(interrupted_exc_t, resource_lost_exc_t, cannot_perform_query_exc_t) */,
            boost::ptr_vector<immediate_op_info_t<op_type, fifo_enforcer_token_type> > *masters_to_contact,
            std::vector<op_response_type> *results,
            std::vector<std::string> *failures,
            order_token_t order_token,
            int i,
            signal_t *interruptor)
        THROWS_NOTHING;

    void dispatch_outdated_read(
            const read_t &op,
            read_response_t *response,
            signal_t *interruptor)
        THROWS_ONLY(interrupted_exc_t, cannot_perform_query_exc_t);

    void perform_outdated_read(
            boost::ptr_vector<outdated_read_info_t> *direct_readers_to_contact,
            std::vector<read_response_t> *results,
            std::vector<std::string> *failures,
            int i,
            signal_t *interruptor)
        THROWS_NOTHING;

    void update_registrants(bool is_start);

    static boost::optional<boost::optional<master_business_card_t> > extract_master_business_card(const std::map<peer_id_t, cow_ptr_t<reactor_business_card_t> > &map, const peer_id_t &peer, const reactor_activity_id_t &activity_id);
    static boost::optional<boost::optional<direct_reader_business_card_t> > extract_direct_reader_business_card_from_primary(const std::map<peer_id_t, cow_ptr_t<reactor_business_card_t> > &map, const peer_id_t &peer, const reactor_activity_id_t &activity_id);

    static boost::optional<boost::optional<direct_reader_business_card_t> > extract_direct_reader_business_card_from_secondary(const std::map<peer_id_t, cow_ptr_t<reactor_business_card_t> > &map, const peer_id_t &peer, const reactor_activity_id_t &activity_id);

    void relationship_coroutine(peer_id_t peer_id, reactor_activity_id_t activity_id,
                                bool is_start, bool is_primary, const region_t &region,
                                auto_drainer_t::lock_t lock) THROWS_NOTHING;

    mailbox_manager_t *mailbox_manager;
    clone_ptr_t<watchable_t<std::map<peer_id_t, cow_ptr_t<reactor_business_card_t> > > > directory_view;
    rdb_context_t *ctx;

    rng_t distributor_rng;

    std::set<reactor_activity_id_t> handled_activity_ids;
    region_map_t<std::set<relationship_t *> > relationships;

    /* `start_cond` will be pulsed when we have either successfully connected to
    or tried and failed to connect to every peer present when the constructor
    was called. `start_count` is the number of peers we're still waiting for. */
    int start_count;
    cond_t start_cond;

    auto_drainer_t relationship_coroutine_auto_drainer;

    scoped_ptr_t<watchable_subscription_t<std::map<peer_id_t, cow_ptr_t<reactor_business_card_t> > > > watcher_subscription;

    DISABLE_COPYING(cluster_namespace_interface_t);
};

#endif /* CLUSTERING_REACTOR_NAMESPACE_INTERFACE_HPP_ */
<|endoftext|>


<commit_before># This was added to start testing the translator, rather than the parser.

fun f : (x : integer) -> (integer)
  if x > 0:
      x = 1
  else:
      x = 0
<commit_msg>updated test to have it type-check;<commit_after># This was added to start testing the translator, rather than the parser.

fun f : (x : integer) -> (boolean)
  if x > 0:
      x = 1
  else:
      x = 0
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/autocomplete/autocomplete_popup_view_gtk.h"

#include <gtk/gtk.h>

#include "base/basictypes.h"
#include "base/gfx/gtk_util.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/common/gfx/chrome_font.h"
#include "chrome/common/notification_service.h"

namespace {

const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce);
const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xff, 0xff, 0xff);
const GdkColor kSelectedBackgroundColor = GDK_COLOR_RGB(0xdf, 0xe6, 0xf6);

const int kBorderThickness = 1;
const int kHeightPerResult = 20;
// Additional distance below the edit control.
const int kTopMargin = 3;
// Space between edge and the text.  This includes the border, so the text
// will be kLeftRightPadding - kBorderThickness away from the border.
const int kLeftRightPadding = 3;

// TODO(deanm): We should put this on ChromeFont so it can be shared.
// Returns a new pango font, free with pango_font_description_free().
PangoFontDescription* PangoFontFromChromeFont(const ChromeFont& chrome_font) {
  ChromeFont font = chrome_font;  // Copy so we can call non-const methods.
  PangoFontDescription* pfd = pango_font_description_new();
  pango_font_description_set_family(pfd, WideToUTF8(font.FontName()).c_str());
  pango_font_description_set_size(pfd, font.FontSize() * PANGO_SCALE);

  switch (font.style()) {
    case ChromeFont::NORMAL:
      // Nothing to do, should already be PANGO_STYLE_NORMAL.
      break;
    case ChromeFont::BOLD:
      pango_font_description_set_weight(pfd, PANGO_WEIGHT_BOLD);
      break;
    case ChromeFont::ITALIC:
      pango_font_description_set_style(pfd, PANGO_STYLE_ITALIC);
      break;
    case ChromeFont::UNDERLINED:
      // TODO(deanm): How to do underlined?  Where do we use it?  Probably have
      // to paint it ourselves, see pango_font_metrics_get_underline_position.
      break;
  }

  return pfd;
}

// Return a GdkRectangle covering the whole area of |window|.
GdkRectangle GetWindowRect(GdkWindow* window) {
  gint width, height;
  gdk_drawable_get_size(GDK_DRAWABLE(window), &width, &height);
  GdkRectangle rect = {0, 0, width, height};
  return rect;
}

// Return a rectangle for the space for a result.  This excludes the border,
// but includes the padding.  This is the area that is colored for a selection.
GdkRectangle GetRectForLine(size_t line, int width) {
  GdkRectangle rect = {kBorderThickness,
                       (line * kHeightPerResult) + kBorderThickness,
                       width - (kBorderThickness * 2),
                       kHeightPerResult};
  return rect;
}

}  // namespace

AutocompletePopupViewGtk::AutocompletePopupViewGtk(
    AutocompleteEditViewGtk* edit_view,
    AutocompleteEditModel* edit_model,
    Profile* profile)
    : font_(NULL),
      model_(new AutocompletePopupModel(this, edit_model, profile)),
      edit_view_(edit_view),
      window_(gtk_window_new(GTK_WINDOW_POPUP)),
      opened_(false) {
  GTK_WIDGET_UNSET_FLAGS(window_, GTK_CAN_FOCUS);
  // Don't allow the window to be resized.  This also forces the window to
  // shrink down to the size of its child contents.
  gtk_window_set_resizable(GTK_WINDOW(window_), FALSE);
  gtk_widget_set_app_paintable(window_, TRUE);
  // Have GTK double buffer around the expose signal.
  gtk_widget_set_double_buffered(window_, TRUE);
  // Set the background color, so we don't need to paint it manually.
  gtk_widget_modify_bg(window_, GTK_STATE_NORMAL, &kBackgroundColor);

  // TODO(deanm): We might want to eventually follow what Windows does and
  // plumb a ChromeFont through.  This is because popup windows have a
  // different font size, although we could just derive that font here.
  ChromeFont default_font;
  font_ = PangoFontFromChromeFont(default_font);

  g_signal_connect(window_, "expose-event",
                   G_CALLBACK(&HandleExposeThunk), this);
}

AutocompletePopupViewGtk::~AutocompletePopupViewGtk() {
  // Explicitly destroy our model here, before we destroy our GTK widgets.
  // This is because the model destructor can call back into us, and we need
  // to make sure everything is still valid when it does.
  model_.reset();
  gtk_widget_destroy(window_);
  pango_font_description_free(font_);
}

void AutocompletePopupViewGtk::InvalidateLine(size_t line) {
  GdkRectangle rect = GetWindowRect(window_->window);
  rect = GetRectForLine(line, rect.width);
  gdk_window_invalidate_rect(window_->window, &rect, FALSE);
}

void AutocompletePopupViewGtk::UpdatePopupAppearance() {
  const AutocompleteResult& result = model_->result();
  if (result.empty()) {
    Hide();
    return;
  }

  Show(result.size());
  gtk_widget_queue_draw(window_);
}

void AutocompletePopupViewGtk::OnHoverEnabledOrDisabled(bool disabled) {
  NOTIMPLEMENTED();
}

void AutocompletePopupViewGtk::PaintUpdatesNow() {
  // Paint our queued invalidations now, synchronously.
  gdk_window_process_updates(window_->window, FALSE);
}

AutocompletePopupModel* AutocompletePopupViewGtk::GetModel() {
  return model_.get();
}

void AutocompletePopupViewGtk::Show(size_t num_results) {
  gint x, y, width;
  edit_view_->BottomLeftPosWidth(&x, &y, &width);
  gtk_window_move(GTK_WINDOW(window_), x, y + kTopMargin);
  gtk_widget_set_size_request(window_, width,
      (num_results * kHeightPerResult) + (kBorderThickness * 2));
  gtk_widget_show(window_);
  opened_ = true;
}

void AutocompletePopupViewGtk::Hide() {
  gtk_widget_hide(window_);
  opened_ = false;
}

gboolean AutocompletePopupViewGtk::HandleExpose(GtkWidget* widget,
                                                GdkEventExpose* event) {
  const AutocompleteResult& result = model_->result();

  GdkRectangle window_rect = GetWindowRect(event->window);
  // Handle when our window is super narrow.  A bunch of the calculations
  // below would go negative, and really we're not going to fit anything
  // useful in such a small window anyway.  Just don't paint anything.
  // This means we won't draw the border, but, yeah, whatever.
  if (window_rect.width < (kLeftRightPadding * 3))
    return TRUE;

  GdkDrawable* drawable = GDK_DRAWABLE(event->window);
  GdkGC* gc = gdk_gc_new(drawable);

  GdkGCValues default_gc_values;
  gdk_gc_get_values(gc, &default_gc_values);

  // kBorderColor is unallocated, so use the GdkRGB routine.
  gdk_gc_set_rgb_fg_color(gc, &kBorderColor);

  // This assert is kinda ugly, but it would be more currently unneeded work
  // to support painting a border that isn't 1 pixel thick.  There is no point
  // in writing that code now, and explode if that day ever comes.
  COMPILE_ASSERT(kBorderThickness == 1, border_1px_implied);
  // Draw the 1px border around the entire window.
  gdk_draw_rectangle(drawable, gc, FALSE,
                     0, 0,
                     window_rect.width - 1, window_rect.height - 1);

  // Draw the background for the selected result line.
  size_t selected = model_->selected_line();
  if (selected != AutocompletePopupModel::kNoMatch) {
    gdk_gc_set_rgb_fg_color(gc, &kSelectedBackgroundColor);
    GdkRectangle rect = GetRectForLine(selected, window_rect.width);
    gdk_draw_rectangle(drawable, gc, TRUE,
                       rect.x, rect.y, rect.width, rect.height);
  }

  // Restore the original GC foreground color.
  gdk_gc_set_foreground(gc, &default_gc_values.foreground);

  // TODO(deanm): Cache the layout?  How expensive is it to create?
  PangoLayout* layout = gtk_widget_create_pango_layout(window_, NULL);

  pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
  pango_layout_set_width(layout,
      (window_rect.width - (kLeftRightPadding * 2)) * PANGO_SCALE);
  pango_layout_set_height(layout, kHeightPerResult * PANGO_SCALE);
  pango_layout_set_font_description(layout, font_);

  // TODO(deanm): Intersect the line and damage rects, and only repaint and
  // layout the lines that are actually damaged.  For now paint everything.
  for (size_t i = 0; i < result.size(); ++i) {
    std::string contents_utf8 = WideToUTF8(result.match_at(i).contents);
    pango_layout_set_text(layout, contents_utf8.data(), contents_utf8.size());
    // TODO(deanm): Should probably try harder to vertically align the text.
    gdk_draw_layout(drawable, gc,
                    kLeftRightPadding, i * kHeightPerResult + 1,
                    layout);
    // TODO(deanm): Draw the "description" on the right of the contents.
  }

  g_object_unref(gc);

  return TRUE;
}
<commit_msg>Make Linux Omnibox results look more like the v2 mocks.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/autocomplete/autocomplete_popup_view_gtk.h"

#include <gtk/gtk.h>

#include "base/basictypes.h"
#include "base/gfx/gtk_util.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "chrome/browser/autocomplete/autocomplete.h"
#include "chrome/browser/autocomplete/autocomplete_edit.h"
#include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
#include "chrome/browser/autocomplete/autocomplete_popup_model.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/common/gfx/chrome_font.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/resource_bundle.h"
#include "grit/theme_resources.h"

namespace {

const GdkColor kBorderColor = GDK_COLOR_RGB(0xc7, 0xca, 0xce);
const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xff, 0xff, 0xff);
const GdkColor kSelectedBackgroundColor = GDK_COLOR_RGB(0xdf, 0xe6, 0xf6);

// TODO(deanm): This is added to extend past just the location box, and to
// be below the the star and go button.  Really this means that this should
// probably plumb all the way back to the location bar view.
const int kExtraSpace = 28;
// We have a 1 pixel border around the entire results popup.
const int kBorderThickness = 1;
// The vertical height of each result.
const int kHeightPerResult = 24;
// Additional distance below the edit control.
const int kTopMargin = 3;
// Width of the icons.
const int kIconWidth = 16;
// We want to vertically center the image in the result space.
const int kIconTopPadding = 4;
// Space between the left edge (including the border) and the text.
const int kIconLeftPadding = 6;
// Space between the image and the text.  Would be 6 to line up with the
// entry, but nudge it a bit more to match with the text in the entry.
const int kIconRightPadding = 10;
// Space between the left edge (including the border) and the text.
const int kIconAreaWidth =
    kIconLeftPadding + kIconWidth + kIconRightPadding;
// Space between the right edge (including the border) and the text.
const int kRightPadding = 3;

// TODO(deanm): We should put this on ChromeFont so it can be shared.
// Returns a new pango font, free with pango_font_description_free().
PangoFontDescription* PangoFontFromChromeFont(const ChromeFont& chrome_font) {
  ChromeFont font = chrome_font;  // Copy so we can call non-const methods.
  PangoFontDescription* pfd = pango_font_description_new();
  pango_font_description_set_family(pfd, WideToUTF8(font.FontName()).c_str());
  pango_font_description_set_size(pfd, font.FontSize() * PANGO_SCALE);

  switch (font.style()) {
    case ChromeFont::NORMAL:
      // Nothing to do, should already be PANGO_STYLE_NORMAL.
      break;
    case ChromeFont::BOLD:
      pango_font_description_set_weight(pfd, PANGO_WEIGHT_BOLD);
      break;
    case ChromeFont::ITALIC:
      pango_font_description_set_style(pfd, PANGO_STYLE_ITALIC);
      break;
    case ChromeFont::UNDERLINED:
      // TODO(deanm): How to do underlined?  Where do we use it?  Probably have
      // to paint it ourselves, see pango_font_metrics_get_underline_position.
      break;
  }

  return pfd;
}

// Return a GdkRectangle covering the whole area of |window|.
GdkRectangle GetWindowRect(GdkWindow* window) {
  gint width, height;
  gdk_drawable_get_size(GDK_DRAWABLE(window), &width, &height);
  GdkRectangle rect = {0, 0, width, height};
  return rect;
}

// Return a rectangle for the space for a result.  This excludes the border,
// but includes the padding.  This is the area that is colored for a selection.
GdkRectangle GetRectForLine(size_t line, int width) {
  GdkRectangle rect = {kBorderThickness,
                       (line * kHeightPerResult) + kBorderThickness,
                       width - (kBorderThickness * 2),
                       kHeightPerResult};
  return rect;
}

// Helper for drawing an entire pixbuf without dithering.
void DrawFullPixbuf(GdkDrawable* drawable, GdkGC* gc, GdkPixbuf* pixbuf,
                    gint dest_x, gint dest_y) {
  gdk_draw_pixbuf(drawable, gc, pixbuf,
                  0, 0,                        // Source.
                  dest_x, dest_y,              // Dest.
                  -1, -1,                      // Width/height (auto).
                  GDK_RGB_DITHER_NONE, 0, 0);  // Don't dither.
}

}  // namespace

AutocompletePopupViewGtk::AutocompletePopupViewGtk(
    AutocompleteEditViewGtk* edit_view,
    AutocompleteEditModel* edit_model,
    Profile* profile)
    : font_(NULL),
      model_(new AutocompletePopupModel(this, edit_model, profile)),
      edit_view_(edit_view),
      window_(gtk_window_new(GTK_WINDOW_POPUP)),
      opened_(false) {
  GTK_WIDGET_UNSET_FLAGS(window_, GTK_CAN_FOCUS);
  // Don't allow the window to be resized.  This also forces the window to
  // shrink down to the size of its child contents.
  gtk_window_set_resizable(GTK_WINDOW(window_), FALSE);
  gtk_widget_set_app_paintable(window_, TRUE);
  // Have GTK double buffer around the expose signal.
  gtk_widget_set_double_buffered(window_, TRUE);
  // Set the background color, so we don't need to paint it manually.
  gtk_widget_modify_bg(window_, GTK_STATE_NORMAL, &kBackgroundColor);

  // TODO(deanm): We might want to eventually follow what Windows does and
  // plumb a ChromeFont through.  This is because popup windows have a
  // different font size, although we could just derive that font here.
  ChromeFont default_font;
  font_ = PangoFontFromChromeFont(default_font);

  g_signal_connect(window_, "expose-event",
                   G_CALLBACK(&HandleExposeThunk), this);
}

AutocompletePopupViewGtk::~AutocompletePopupViewGtk() {
  // Explicitly destroy our model here, before we destroy our GTK widgets.
  // This is because the model destructor can call back into us, and we need
  // to make sure everything is still valid when it does.
  model_.reset();
  gtk_widget_destroy(window_);
  pango_font_description_free(font_);
}

void AutocompletePopupViewGtk::InvalidateLine(size_t line) {
  GdkRectangle rect = GetWindowRect(window_->window);
  rect = GetRectForLine(line, rect.width);
  gdk_window_invalidate_rect(window_->window, &rect, FALSE);
}

void AutocompletePopupViewGtk::UpdatePopupAppearance() {
  const AutocompleteResult& result = model_->result();
  if (result.empty()) {
    Hide();
    return;
  }

  Show(result.size());
  gtk_widget_queue_draw(window_);
}

void AutocompletePopupViewGtk::OnHoverEnabledOrDisabled(bool disabled) {
  NOTIMPLEMENTED();
}

void AutocompletePopupViewGtk::PaintUpdatesNow() {
  // Paint our queued invalidations now, synchronously.
  gdk_window_process_updates(window_->window, FALSE);
}

AutocompletePopupModel* AutocompletePopupViewGtk::GetModel() {
  return model_.get();
}

void AutocompletePopupViewGtk::Show(size_t num_results) {
  gint x, y, width;
  edit_view_->BottomLeftPosWidth(&x, &y, &width);
  x -= kExtraSpace;
  width += kExtraSpace * 2;

  gtk_window_move(GTK_WINDOW(window_), x, y + kTopMargin);
  gtk_widget_set_size_request(window_, width,
      (num_results * kHeightPerResult) + (kBorderThickness * 2));
  gtk_widget_show(window_);
  opened_ = true;
}

void AutocompletePopupViewGtk::Hide() {
  gtk_widget_hide(window_);
  opened_ = false;
}

gboolean AutocompletePopupViewGtk::HandleExpose(GtkWidget* widget,
                                                GdkEventExpose* event) {
  const AutocompleteResult& result = model_->result();

  // TODO(deanm): These would be better as pixmaps someday.
  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
  static GdkPixbuf* o2_globe = rb.LoadPixbuf(IDR_O2_GLOBE);
  static GdkPixbuf* o2_history = rb.LoadPixbuf(IDR_O2_HISTORY);
  static GdkPixbuf* o2_more = rb.LoadPixbuf(IDR_O2_MORE);
  static GdkPixbuf* o2_search = rb.LoadPixbuf(IDR_O2_SEARCH);
  static GdkPixbuf* o2_star = rb.LoadPixbuf(IDR_O2_STAR);

  GdkRectangle window_rect = GetWindowRect(event->window);
  // Handle when our window is super narrow.  A bunch of the calculations
  // below would go negative, and really we're not going to fit anything
  // useful in such a small window anyway.  Just don't paint anything.
  // This means we won't draw the border, but, yeah, whatever.
  // TODO(deanm): Make the code more robust and remove this check.
  if (window_rect.width < (kIconAreaWidth * 3))
    return TRUE;

  GdkDrawable* drawable = GDK_DRAWABLE(event->window);
  GdkGC* gc = gdk_gc_new(drawable);

  GdkGCValues default_gc_values;
  gdk_gc_get_values(gc, &default_gc_values);

  // kBorderColor is unallocated, so use the GdkRGB routine.
  gdk_gc_set_rgb_fg_color(gc, &kBorderColor);

  // This assert is kinda ugly, but it would be more currently unneeded work
  // to support painting a border that isn't 1 pixel thick.  There is no point
  // in writing that code now, and explode if that day ever comes.
  COMPILE_ASSERT(kBorderThickness == 1, border_1px_implied);
  // Draw the 1px border around the entire window.
  gdk_draw_rectangle(drawable, gc, FALSE,
                     0, 0,
                     window_rect.width - 1, window_rect.height - 1);

  // Draw the background for the selected result line.
  size_t selected = model_->selected_line();
  if (selected != AutocompletePopupModel::kNoMatch) {
    gdk_gc_set_rgb_fg_color(gc, &kSelectedBackgroundColor);
    GdkRectangle rect = GetRectForLine(selected, window_rect.width);
    gdk_draw_rectangle(drawable, gc, TRUE,
                       rect.x, rect.y, rect.width, rect.height);
  }

  // Restore the original GC foreground color.
  gdk_gc_set_foreground(gc, &default_gc_values.foreground);

  // TODO(deanm): Cache the layout?  How expensive is it to create?
  PangoLayout* layout = gtk_widget_create_pango_layout(window_, NULL);

  pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
  pango_layout_set_width(layout,
      (window_rect.width - (kIconAreaWidth + kRightPadding)) * PANGO_SCALE);
  pango_layout_set_height(layout, kHeightPerResult * PANGO_SCALE);
  pango_layout_set_font_description(layout, font_);

  // TODO(deanm): Intersect the line and damage rects, and only repaint and
  // layout the lines that are actually damaged.  For now paint everything.
  for (size_t i = 0; i < result.size(); ++i) {
    const AutocompleteMatch& match = result.match_at(i);
    int y = i * kHeightPerResult + kBorderThickness;

    GdkPixbuf* icon = NULL;
    if (match.starred) {
      icon = o2_star;
    } else {
      switch (match.type) {
        case AutocompleteMatch::URL_WHAT_YOU_TYPED:
        case AutocompleteMatch::NAVSUGGEST:
          icon = o2_globe;
          break;
        case AutocompleteMatch::HISTORY_URL:
        case AutocompleteMatch::HISTORY_TITLE:
        case AutocompleteMatch::HISTORY_BODY:
        case AutocompleteMatch::HISTORY_KEYWORD:
          icon = o2_history;
          break;
        case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED:
        case AutocompleteMatch::SEARCH_HISTORY:
        case AutocompleteMatch::SEARCH_SUGGEST:
        case AutocompleteMatch::SEARCH_OTHER_ENGINE:
          icon = o2_search;
          break;
        case AutocompleteMatch::OPEN_HISTORY_PAGE:
          icon = o2_more;
          break;
        default:
          NOTREACHED();
          break;
      }
    }

    // Draw the icon for this result time.
    DrawFullPixbuf(drawable, gc, icon,
                   kIconLeftPadding, y + kIconTopPadding);

    // Draw the results text vertically centered in the results space.
    std::string contents = WideToUTF8(match.contents);
    std::string description = WideToUTF8(match.description);
    // TODO(deanm): I couldn't get the weight adjustment to be granular enough
    // to match the mocks.  It was basically super bold or super thin.
    char* markup = g_markup_printf_escaped(
        "%s<b><span foreground=\"#ababab\">%s%s</span></b>",
        contents.c_str(),
        description.empty() ? "" : " - ",
        description.c_str());
    pango_layout_set_markup(layout, markup, -1);
    g_free(markup);

    int width, height;
    pango_layout_get_size(layout, &width, &height);
    height /= PANGO_SCALE;
    DCHECK_LT(height, kHeightPerResult);  // Font too tall.
    int text_y = std::max(y, y + ((kHeightPerResult - height) / 2));

    gdk_draw_layout(drawable, gc,
                    kIconAreaWidth, text_y,
                    layout);
  }

  g_object_unref(gc);

  return TRUE;
}
<|endoftext|>