<commit_before>/* This pass is meant to show how one uses the Knowledge Construction Engine
 * (KCE). It's pretty simple. Running this pass requires a lot more work and
 * I'm...heh....working on that.
 * - Joshua Scoggins (8/12/2012)
 */
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/DenseSet.h"
#include "KnowledgeConstructionEngine.h"
#include "LLVMWrapper.h"
#include "JSEdgeRemoval.h"
#include "PassDependencies.h"
extern "C" {
  #include "clips.h"
}

using namespace llvm;
char nilObject[41] = "(nil of ConstantPointerNull (Pointer 0))";
namespace {
   struct KnowledgeConstruction : public FunctionPass {
      static char ID;
      public:
      KnowledgeConstruction() : FunctionPass(ID) {
         //InitializeRuntimeAnalyzer();
      }
      virtual void getAnalysisUsage(AnalysisUsage &Info) const {
         Info.addRequired<LoopInfo>();
         Info.addRequired<RegionInfo>();
      }
      virtual bool runOnFunction(Function& fn) {
			return false;
         //do not actually wavefront schedule if we only have one block
			/*
         if(fn.size() > 1) {
            char* funcName = (char*)fn.getName().data();
            DenseMap<PointerAddress, std::string> translation;
            std::pair<PointerAddress, std::string> pair(0,"nil");
            translation.insert(pair);
            FunctionNamer namer (translation);
            Reset();
            MakeInstance(nilObject);
            ModifyFunctionContents(fn, namer);
            LoopInfo &li = getAnalysis<LoopInfo>();
            RouteLoopInfo(li, funcName, namer);
            RegionInfo &ri = getAnalysis<RegionInfo>();
            llvm::Region* top = ri.getTopLevelRegion();
            Route(top, funcName, namer);
            Run(-1L);
            return true;
         } else {
            return false;
         }
			*/
      }
   };
}
char KnowledgeConstruction::ID = 0;
INITIALIZE_PASS_BEGIN(KnowledgeConstruction, "knowledge", "Knowledge constructor", false, false)
INITIALIZE_PASS_END(KnowledgeConstruction, "knowledge", "Knowledge constructor", false, false)
//for opt
static RegisterPass<KnowledgeConstruction> X("knowledge", "Knowledge constructor", false, false);
<commit_msg>Commented out the global nilObject<commit_after>/* This pass is meant to show how one uses the Knowledge Construction Engine
 * (KCE). It's pretty simple. Running this pass requires a lot more work and
 * I'm...heh....working on that.
 * - Joshua Scoggins (8/12/2012)
 */
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/DenseSet.h"
#include "KnowledgeConstructionEngine.h"
#include "LLVMWrapper.h"
#include "JSEdgeRemoval.h"
#include "PassDependencies.h"
extern "C" {
  #include "clips.h"
}

using namespace llvm;
//char nilObject[41] = "(nil of ConstantPointerNull (Pointer 0))";
namespace {
   struct KnowledgeConstruction : public FunctionPass {
      static char ID;
      public:
      KnowledgeConstruction() : FunctionPass(ID) {
         //InitializeRuntimeAnalyzer();
      }
      virtual void getAnalysisUsage(AnalysisUsage &Info) const {
         Info.addRequired<LoopInfo>();
         Info.addRequired<RegionInfo>();
      }
      virtual bool runOnFunction(Function& fn) {
			return false;
         //do not actually wavefront schedule if we only have one block
			/*
         if(fn.size() > 1) {
            char* funcName = (char*)fn.getName().data();
            DenseMap<PointerAddress, std::string> translation;
            std::pair<PointerAddress, std::string> pair(0,"nil");
            translation.insert(pair);
            FunctionNamer namer (translation);
            Reset();
            MakeInstance(nilObject);
            ModifyFunctionContents(fn, namer);
            LoopInfo &li = getAnalysis<LoopInfo>();
            RouteLoopInfo(li, funcName, namer);
            RegionInfo &ri = getAnalysis<RegionInfo>();
            llvm::Region* top = ri.getTopLevelRegion();
            Route(top, funcName, namer);
            Run(-1L);
            return true;
         } else {
            return false;
         }
			*/
      }
   };
}
char KnowledgeConstruction::ID = 0;
INITIALIZE_PASS_BEGIN(KnowledgeConstruction, "knowledge", "Knowledge constructor", false, false)
INITIALIZE_PASS_END(KnowledgeConstruction, "knowledge", "Knowledge constructor", false, false)
//for opt
static RegisterPass<KnowledgeConstruction> X("knowledge", "Knowledge constructor", false, false);
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2009, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id: pointimage_msgto_pcd.cpp 33238 2010-03-11 00:46:58Z rusu $
 *
 */

// ROS core
#include <boost/thread/mutex.hpp>
// PCL includes
#include <pcl/common/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/range_image/range_image_planar.h>
#include <pcl/common/common_headers.h>

#include <pcl_visualization/pcl_visualizer.h>
#include "pcl_visualization/range_image_visualizer.h"

using namespace std;
using namespace pcl;
using namespace pcl_visualization;
typedef PointXYZ PointType;

float angular_resolution = 0.5f,  // Resolution of the range image
      noise_level = 0.0f,         // Distance in which the z-buffer averages instead of taking the minimum
      min_range  = 0.0f;          // Minimum range for the range image creation
int border_size = 0;              // Additional border around the range image
RangeImage::CoordinateFrame coordinate_frame = RangeImage::CAMERA_FRAME;
int source = 0;  // Default: Use PointCloud2

void
printUsage (const char* progName)
{
  cout << "\n\nUsage: "<<progName<<" [options] input:=<yourInput>\n\n"
       << "Options:\n"
       << "-------------------------------------------\n"
       << "-c <int>     source coordinate frame (default "<<coordinate_frame<<")\n"
       << "-s           source used to create the range image: "
       <<              "0 PointCloud2 (default), 1 depth image, 2 disparity image .\n"
       << "-r <float>   angular resolution in degrees (default "<<angular_resolution<<")\n"
       << "-h           this help\n"
       << "\n\n";
}

sensor_msgs::PointCloud2ConstPtr cloud_msg, old_cloud_msg;
sensor_msgs::ImageConstPtr depth_image_msg, old_depth_image_msg;
stereo_msgs::DisparityImageConstPtr disparity_image_msg, old_disparity_image_msg;
sensor_msgs::CameraInfoConstPtr camera_info_msg;
boost::mutex m;

void
disparity_image_msg_cb (const stereo_msgs::DisparityImageConstPtr& msg)
{
  m.lock ();
  disparity_image_msg = msg;
  m.unlock ();
}

void
depth_image_msg_cb (const sensor_msgs::ImageConstPtr& msg)
{
  m.lock ();
  //std::cout << "Received depth image of size "<<msg->width<<"x"<<msg->height<<".\n";
  depth_image_msg = msg;
  m.unlock ();
}

void
cloud_msg_cb (const sensor_msgs::PointCloud2ConstPtr& msg)
{
  m.lock ();
  cloud_msg = msg;
  m.unlock ();
}

void
camera_info_msg_cb (const sensor_msgs::CameraInfoConstPtr& msg)
{
  m.lock ();
  //std::cout << "Received camera info: " << "width="<<msg->width<<", height="<<msg->height<<", "
                                        //<< "center_x="<<msg->P[2]<<", center_y="<<msg->P[6]<<", "
                                       //<<"fl_x="<<msg->P[0]<<", fl_y="<<msg->P[5]<<".\n";
  camera_info_msg = msg;
  m.unlock ();
}

int
main (int argc, char** argv)
{
  // Read command line arguments.
  for (char c; (c = getopt (argc, argv, "s:hc:r:")) != -1; )
  {
    switch (c)
    {
      case 'c':
        coordinate_frame = RangeImage::CoordinateFrame (strtol (optarg, NULL, 0));
        break;
      case 'r':
      {
        angular_resolution = strtod (optarg, NULL);
        cout << PVARN(angular_resolution);
        break;
      }
      case 's':
      {
        source = strtol (optarg, NULL, 0);
        if (source < 0  ||  source > 2)
        {
          cout << "Source "<<source<<" is unknown.\n";
          exit (0);
        }
        cout << "Receiving "<<(source==0 ? "point clouds" : (source==1 ? "depth images" : "disparity images"))<<".\n";
        break;
      }
      case 'h':
      default:
        printUsage (argv[0]);
        exit (0);
    }
  }
  angular_resolution = deg2rad (angular_resolution);

  ros::init (argc, argv, "tutorial_range_image_live_viewer");
  ros::NodeHandle node_handle;
  ros::Subscriber subscriber, subscriber2;

  if (node_handle.resolveName("input")=="/input")
    std::cerr << "Did you forget input:=<your topic>?\n";

  if (source == 0)
    subscriber = node_handle.subscribe ("input", 1, cloud_msg_cb);
  else if (source == 1)
  {
    if (node_handle.resolveName("input2")=="/input2")
      std::cerr << "Did you forget input2:=<your camera_info_topic>?\n";
    subscriber = node_handle.subscribe ("input", 1, depth_image_msg_cb);
    subscriber2 = node_handle.subscribe ("input2", 1, camera_info_msg_cb);
  }
  else if (source == 2)
    subscriber  = node_handle.subscribe ("input",  1, disparity_image_msg_cb);

  PCLVisualizer viewer (argc, argv, "Live viewer - point cloud");
  RangeImageVisualizer range_image_widget("Live viewer - range image");

  RangeImagePlanar* range_image_planar;
  RangeImage* range_image;
  if (source==0)
    range_image = new RangeImage;
  else
  {
    range_image_planar = new RangeImagePlanar;
    range_image = range_image_planar;
  }

  while (node_handle.ok ())
  {
    usleep (10000);
    viewer.spinOnce (10);
    RangeImageVisualizer::spinOnce ();
    ros::spinOnce ();

    if (source==0)
    {
      // If no new message received: continue
      if (!cloud_msg || cloud_msg == old_cloud_msg)
        continue;
      old_cloud_msg = cloud_msg;

      Eigen::Affine3f sensor_pose(Eigen::Affine3f::Identity());
      PointCloud<PointWithViewpoint> far_ranges;
      RangeImage::extractFarRanges(*cloud_msg, far_ranges);
      if (pcl::getFieldIndex(*cloud_msg, "vp_x")>=0)
      {
        PointCloud<PointWithViewpoint> tmp_pc;
        fromROSMsg(*cloud_msg, tmp_pc);
        Eigen::Vector3f average_viewpoint = RangeImage::getAverageViewPoint(tmp_pc);
        sensor_pose = Eigen::Translation3f(average_viewpoint) * sensor_pose;
      }
      PointCloud<PointType> point_cloud;
      fromROSMsg(*cloud_msg, point_cloud);
      range_image->createFromPointCloud(point_cloud, angular_resolution, deg2rad(360.0f), deg2rad(180.0f),
                                        sensor_pose, coordinate_frame, noise_level, min_range, border_size);
    }
    else if (source==1)
    {
      // If no new message received: continue
      if (!depth_image_msg || depth_image_msg == old_depth_image_msg || !camera_info_msg)
        continue;
      old_depth_image_msg = depth_image_msg;
      range_image_planar->setDepthImage(reinterpret_cast<const float*> (&depth_image_msg->data[0]),
                                        depth_image_msg->width, depth_image_msg->height,
                                        camera_info_msg->P[2],  camera_info_msg->P[6],
                                        camera_info_msg->P[0],  camera_info_msg->P[5], angular_resolution);
    }
    else if (source==2)
    {
      // If no new message received: continue
      if (!disparity_image_msg || disparity_image_msg == old_disparity_image_msg)
        continue;
      old_disparity_image_msg = disparity_image_msg;
      range_image_planar->setDisparityImage(reinterpret_cast<const float*> (&disparity_image_msg->image.data[0]),
                                            disparity_image_msg->image.width, disparity_image_msg->image.height,
                                            disparity_image_msg->f, disparity_image_msg->T, angular_resolution);
    }

    range_image_widget.setRangeImage (*range_image);
    viewer.removePointCloud ("range image cloud");
    pcl_visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> color_handler_cloud(*range_image,
                                                                                200, 200, 200);
    viewer.addPointCloud (*range_image, color_handler_cloud, "range image cloud");
  }
}
<commit_msg>removed <commit_after><|endoftext|>


<commit_before>// Copyright 2014 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 "apps/ui/views/app_window_frame_view.h"

#include "apps/ui/native_app_window.h"
#include "base/strings/utf_string_conversions.h"
#include "extensions/common/draggable_region.h"
#include "grit/theme_resources.h"
#include "grit/ui_strings.h"  // Accessibility names
#include "third_party/skia/include/core/SkPaint.h"
#include "ui/base/hit_test.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/path.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/views_delegate.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

#if defined(USE_AURA)
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#endif

namespace {
// Height of the chrome-style caption, in pixels.
const int kCaptionHeight = 25;
}  // namespace

namespace apps {

const char AppWindowFrameView::kViewClassName[] =
    "browser/ui/views/extensions/AppWindowFrameView";

AppWindowFrameView::AppWindowFrameView(NativeAppWindow* window)
    : window_(window),
      frame_(NULL),
      close_button_(NULL),
      maximize_button_(NULL),
      restore_button_(NULL),
      minimize_button_(NULL),
      resize_inside_bounds_size_(0),
      resize_outside_bounds_size_(0),
      resize_area_corner_size_(0) {}

AppWindowFrameView::~AppWindowFrameView() {}

void AppWindowFrameView::Init(views::Widget* frame,
                              int resize_inside_bounds_size,
                              int resize_outside_bounds_size,
                              int resize_outside_scale_for_touch,
                              int resize_area_corner_size) {
  frame_ = frame;
  resize_inside_bounds_size_ = resize_inside_bounds_size;
  resize_outside_bounds_size_ = resize_outside_bounds_size;
  resize_area_corner_size_ = resize_area_corner_size;

  if (!window_->IsFrameless()) {
    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    close_button_ = new views::ImageButton(this);
    close_button_->SetImage(
        views::CustomButton::STATE_NORMAL,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE).ToImageSkia());
    close_button_->SetImage(
        views::CustomButton::STATE_HOVERED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE_H).ToImageSkia());
    close_button_->SetImage(
        views::CustomButton::STATE_PRESSED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE_P).ToImageSkia());
    close_button_->SetAccessibleName(
        l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE));
    AddChildView(close_button_);
    maximize_button_ = new views::ImageButton(this);
    maximize_button_->SetImage(
        views::CustomButton::STATE_NORMAL,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE).ToImageSkia());
    maximize_button_->SetImage(
        views::CustomButton::STATE_HOVERED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_H).ToImageSkia());
    maximize_button_->SetImage(
        views::CustomButton::STATE_PRESSED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_P).ToImageSkia());
    maximize_button_->SetImage(
        views::CustomButton::STATE_DISABLED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_D).ToImageSkia());
    maximize_button_->SetAccessibleName(
        l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE));
    AddChildView(maximize_button_);
    restore_button_ = new views::ImageButton(this);
    restore_button_->SetImage(
        views::CustomButton::STATE_NORMAL,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE).ToImageSkia());
    restore_button_->SetImage(
        views::CustomButton::STATE_HOVERED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE_H).ToImageSkia());
    restore_button_->SetImage(
        views::CustomButton::STATE_PRESSED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE_P).ToImageSkia());
    restore_button_->SetAccessibleName(
        l10n_util::GetStringUTF16(IDS_APP_ACCNAME_RESTORE));
    AddChildView(restore_button_);
    minimize_button_ = new views::ImageButton(this);
    minimize_button_->SetImage(
        views::CustomButton::STATE_NORMAL,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE).ToImageSkia());
    minimize_button_->SetImage(
        views::CustomButton::STATE_HOVERED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE_H).ToImageSkia());
    minimize_button_->SetImage(
        views::CustomButton::STATE_PRESSED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE_P).ToImageSkia());
    minimize_button_->SetAccessibleName(
        l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE));
    AddChildView(minimize_button_);
  }

#if defined(USE_AURA)
  aura::Window* window = frame->GetNativeWindow();
  // Ensure we get resize cursors just inside our bounds as well.
  // TODO(jeremya): do we need to update these when in fullscreen/maximized?
  window->set_hit_test_bounds_override_inner(
      gfx::Insets(resize_inside_bounds_size_,
                  resize_inside_bounds_size_,
                  resize_inside_bounds_size_,
                  resize_inside_bounds_size_));
#endif
}

// views::NonClientFrameView implementation.

gfx::Rect AppWindowFrameView::GetBoundsForClientView() const {
  if (window_->IsFrameless() || frame_->IsFullscreen())
    return bounds();
  return gfx::Rect(
      0, kCaptionHeight, width(), std::max(0, height() - kCaptionHeight));
}

gfx::Rect AppWindowFrameView::GetWindowBoundsForClientBounds(
    const gfx::Rect& client_bounds) const {
  if (window_->IsFrameless()) {
    gfx::Rect window_bounds = client_bounds;
    // Enforce minimum size (1, 1) in case that client_bounds is passed with
    // empty size. This could occur when the frameless window is being
    // initialized.
    if (window_bounds.IsEmpty()) {
      window_bounds.set_width(1);
      window_bounds.set_height(1);
    }
    return window_bounds;
  }

  int closeButtonOffsetX = (kCaptionHeight - close_button_->height()) / 2;
  int header_width = close_button_->width() + closeButtonOffsetX * 2;
  return gfx::Rect(client_bounds.x(),
                   std::max(0, client_bounds.y() - kCaptionHeight),
                   std::max(header_width, client_bounds.width()),
                   client_bounds.height() + kCaptionHeight);
}

int AppWindowFrameView::NonClientHitTest(const gfx::Point& point) {
  if (frame_->IsFullscreen())
    return HTCLIENT;

  gfx::Rect expanded_bounds = bounds();
  if (resize_outside_bounds_size_)
    expanded_bounds.Inset(gfx::Insets(-resize_outside_bounds_size_,
                                      -resize_outside_bounds_size_,
                                      -resize_outside_bounds_size_,
                                      -resize_outside_bounds_size_));
  // Points outside the (possibly expanded) bounds can be discarded.
  if (!expanded_bounds.Contains(point))
    return HTNOWHERE;

  // Check the frame first, as we allow a small area overlapping the contents
  // to be used for resize handles.
  bool can_ever_resize = frame_->widget_delegate()
                             ? frame_->widget_delegate()->CanResize()
                             : false;
  // Don't allow overlapping resize handles when the window is maximized or
  // fullscreen, as it can't be resized in those states.
  int resize_border = (frame_->IsMaximized() || frame_->IsFullscreen())
                          ? 0
                          : resize_inside_bounds_size_;
  int frame_component = GetHTComponentForFrame(point,
                                               resize_border,
                                               resize_border,
                                               resize_area_corner_size_,
                                               resize_area_corner_size_,
                                               can_ever_resize);
  if (frame_component != HTNOWHERE)
    return frame_component;

  // Check for possible draggable region in the client area for the frameless
  // window.
  if (window_->IsFrameless()) {
    SkRegion* draggable_region = window_->GetDraggableRegion();
    if (draggable_region && draggable_region->contains(point.x(), point.y()))
      return HTCAPTION;
  }

  int client_component = frame_->client_view()->NonClientHitTest(point);
  if (client_component != HTNOWHERE)
    return client_component;

  // Then see if the point is within any of the window controls.
  if (close_button_ && close_button_->visible() &&
      close_button_->GetMirroredBounds().Contains(point)) {
    return HTCLOSE;
  }
  if ((maximize_button_ && maximize_button_->visible() &&
       maximize_button_->GetMirroredBounds().Contains(point)) ||
      (restore_button_ && restore_button_->visible() &&
       restore_button_->GetMirroredBounds().Contains(point))) {
    return HTMAXBUTTON;
  }
  if (minimize_button_ && minimize_button_->visible() &&
      minimize_button_->GetMirroredBounds().Contains(point)) {
    return HTMINBUTTON;
  }

  // Caption is a safe default.
  return HTCAPTION;
}

void AppWindowFrameView::GetWindowMask(const gfx::Size& size,
                                       gfx::Path* window_mask) {
  // We got nothing to say about no window mask.
}

// views::View implementation.

gfx::Size AppWindowFrameView::GetPreferredSize() {
  gfx::Size pref = frame_->client_view()->GetPreferredSize();
  gfx::Rect bounds(0, 0, pref.width(), pref.height());
  return frame_->non_client_view()
      ->GetWindowBoundsForClientBounds(bounds)
      .size();
}

void AppWindowFrameView::Layout() {
  if (window_->IsFrameless())
    return;
  gfx::Size close_size = close_button_->GetPreferredSize();
  const int kButtonOffsetY = 0;
  const int kButtonSpacing = 1;
  const int kRightMargin = 3;

  close_button_->SetBounds(width() - kRightMargin - close_size.width(),
                           kButtonOffsetY,
                           close_size.width(),
                           close_size.height());

  bool can_ever_resize = frame_->widget_delegate()
                             ? frame_->widget_delegate()->CanResize()
                             : false;
  maximize_button_->SetEnabled(can_ever_resize);
  gfx::Size maximize_size = maximize_button_->GetPreferredSize();
  maximize_button_->SetBounds(
      close_button_->x() - kButtonSpacing - maximize_size.width(),
      kButtonOffsetY,
      maximize_size.width(),
      maximize_size.height());
  gfx::Size restore_size = restore_button_->GetPreferredSize();
  restore_button_->SetBounds(
      close_button_->x() - kButtonSpacing - restore_size.width(),
      kButtonOffsetY,
      restore_size.width(),
      restore_size.height());

  bool maximized = frame_->IsMaximized();
  maximize_button_->SetVisible(!maximized);
  restore_button_->SetVisible(maximized);
  if (maximized)
    maximize_button_->SetState(views::CustomButton::STATE_NORMAL);
  else
    restore_button_->SetState(views::CustomButton::STATE_NORMAL);

  gfx::Size minimize_size = minimize_button_->GetPreferredSize();
  minimize_button_->SetBounds(
      maximize_button_->x() - kButtonSpacing - minimize_size.width(),
      kButtonOffsetY,
      minimize_size.width(),
      minimize_size.height());
}

void AppWindowFrameView::OnPaint(gfx::Canvas* canvas) {
  if (window_->IsFrameless())
    return;

  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  if (ShouldPaintAsActive()) {
    close_button_->SetImage(
        views::CustomButton::STATE_NORMAL,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE).ToImageSkia());
  } else {
    close_button_->SetImage(
        views::CustomButton::STATE_NORMAL,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE_U).ToImageSkia());
  }

  // TODO(jeremya): different look for inactive?
  SkPaint paint;
  paint.setAntiAlias(false);
  paint.setStyle(SkPaint::kFill_Style);
  paint.setColor(SK_ColorWHITE);
  gfx::Path path;
  path.moveTo(0, 0);
  path.lineTo(width(), 0);
  path.lineTo(width(), kCaptionHeight);
  path.lineTo(0, kCaptionHeight);
  path.close();
  canvas->DrawPath(path, paint);
}

const char* AppWindowFrameView::GetClassName() const { return kViewClassName; }

gfx::Size AppWindowFrameView::GetMinimumSize() {
  gfx::Size min_size = frame_->client_view()->GetMinimumSize();
  if (window_->IsFrameless())
    return min_size;

  // Ensure we can display the top of the caption area.
  gfx::Rect client_bounds = GetBoundsForClientView();
  min_size.Enlarge(0, client_bounds.y());
  // Ensure we have enough space for the window icon and buttons.  We allow
  // the title string to collapse to zero width.
  int closeButtonOffsetX = (kCaptionHeight - close_button_->height()) / 2;
  int header_width = close_button_->width() + closeButtonOffsetX * 2;
  if (header_width > min_size.width())
    min_size.set_width(header_width);
  return min_size;
}

gfx::Size AppWindowFrameView::GetMaximumSize() {
  gfx::Size max_size = frame_->client_view()->GetMaximumSize();

  // Add to the client maximum size the height of any title bar and borders.
  gfx::Size client_size = GetBoundsForClientView().size();
  if (max_size.width())
    max_size.Enlarge(width() - client_size.width(), 0);
  if (max_size.height())
    max_size.Enlarge(0, height() - client_size.height());

  return max_size;
}

// views::ButtonListener implementation.

void AppWindowFrameView::ButtonPressed(views::Button* sender,
                                       const ui::Event& event) {
  DCHECK(!window_->IsFrameless());
  if (sender == close_button_)
    frame_->Close();
  else if (sender == maximize_button_)
    frame_->Maximize();
  else if (sender == restore_button_)
    frame_->Restore();
  else if (sender == minimize_button_)
    frame_->Minimize();
}

}  // namespace apps
<commit_msg>Fix the "Minimize" button of app windows remaining hovered after restore.<commit_after>// Copyright 2014 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 "apps/ui/views/app_window_frame_view.h"

#include "apps/ui/native_app_window.h"
#include "base/strings/utf_string_conversions.h"
#include "extensions/common/draggable_region.h"
#include "grit/theme_resources.h"
#include "grit/ui_strings.h"  // Accessibility names
#include "third_party/skia/include/core/SkPaint.h"
#include "ui/base/hit_test.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/path.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/views_delegate.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

#if defined(USE_AURA)
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#endif

namespace {
// Height of the chrome-style caption, in pixels.
const int kCaptionHeight = 25;
}  // namespace

namespace apps {

const char AppWindowFrameView::kViewClassName[] =
    "browser/ui/views/extensions/AppWindowFrameView";

AppWindowFrameView::AppWindowFrameView(NativeAppWindow* window)
    : window_(window),
      frame_(NULL),
      close_button_(NULL),
      maximize_button_(NULL),
      restore_button_(NULL),
      minimize_button_(NULL),
      resize_inside_bounds_size_(0),
      resize_outside_bounds_size_(0),
      resize_area_corner_size_(0) {}

AppWindowFrameView::~AppWindowFrameView() {}

void AppWindowFrameView::Init(views::Widget* frame,
                              int resize_inside_bounds_size,
                              int resize_outside_bounds_size,
                              int resize_outside_scale_for_touch,
                              int resize_area_corner_size) {
  frame_ = frame;
  resize_inside_bounds_size_ = resize_inside_bounds_size;
  resize_outside_bounds_size_ = resize_outside_bounds_size;
  resize_area_corner_size_ = resize_area_corner_size;

  if (!window_->IsFrameless()) {
    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    close_button_ = new views::ImageButton(this);
    close_button_->SetImage(
        views::CustomButton::STATE_NORMAL,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE).ToImageSkia());
    close_button_->SetImage(
        views::CustomButton::STATE_HOVERED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE_H).ToImageSkia());
    close_button_->SetImage(
        views::CustomButton::STATE_PRESSED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE_P).ToImageSkia());
    close_button_->SetAccessibleName(
        l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE));
    AddChildView(close_button_);
    maximize_button_ = new views::ImageButton(this);
    maximize_button_->SetImage(
        views::CustomButton::STATE_NORMAL,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE).ToImageSkia());
    maximize_button_->SetImage(
        views::CustomButton::STATE_HOVERED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_H).ToImageSkia());
    maximize_button_->SetImage(
        views::CustomButton::STATE_PRESSED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_P).ToImageSkia());
    maximize_button_->SetImage(
        views::CustomButton::STATE_DISABLED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MAXIMIZE_D).ToImageSkia());
    maximize_button_->SetAccessibleName(
        l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MAXIMIZE));
    AddChildView(maximize_button_);
    restore_button_ = new views::ImageButton(this);
    restore_button_->SetImage(
        views::CustomButton::STATE_NORMAL,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE).ToImageSkia());
    restore_button_->SetImage(
        views::CustomButton::STATE_HOVERED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE_H).ToImageSkia());
    restore_button_->SetImage(
        views::CustomButton::STATE_PRESSED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_RESTORE_P).ToImageSkia());
    restore_button_->SetAccessibleName(
        l10n_util::GetStringUTF16(IDS_APP_ACCNAME_RESTORE));
    AddChildView(restore_button_);
    minimize_button_ = new views::ImageButton(this);
    minimize_button_->SetImage(
        views::CustomButton::STATE_NORMAL,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE).ToImageSkia());
    minimize_button_->SetImage(
        views::CustomButton::STATE_HOVERED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE_H).ToImageSkia());
    minimize_button_->SetImage(
        views::CustomButton::STATE_PRESSED,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_MINIMIZE_P).ToImageSkia());
    minimize_button_->SetAccessibleName(
        l10n_util::GetStringUTF16(IDS_APP_ACCNAME_MINIMIZE));
    AddChildView(minimize_button_);
  }

#if defined(USE_AURA)
  aura::Window* window = frame->GetNativeWindow();
  // Ensure we get resize cursors just inside our bounds as well.
  // TODO(jeremya): do we need to update these when in fullscreen/maximized?
  window->set_hit_test_bounds_override_inner(
      gfx::Insets(resize_inside_bounds_size_,
                  resize_inside_bounds_size_,
                  resize_inside_bounds_size_,
                  resize_inside_bounds_size_));
#endif
}

// views::NonClientFrameView implementation.

gfx::Rect AppWindowFrameView::GetBoundsForClientView() const {
  if (window_->IsFrameless() || frame_->IsFullscreen())
    return bounds();
  return gfx::Rect(
      0, kCaptionHeight, width(), std::max(0, height() - kCaptionHeight));
}

gfx::Rect AppWindowFrameView::GetWindowBoundsForClientBounds(
    const gfx::Rect& client_bounds) const {
  if (window_->IsFrameless()) {
    gfx::Rect window_bounds = client_bounds;
    // Enforce minimum size (1, 1) in case that client_bounds is passed with
    // empty size. This could occur when the frameless window is being
    // initialized.
    if (window_bounds.IsEmpty()) {
      window_bounds.set_width(1);
      window_bounds.set_height(1);
    }
    return window_bounds;
  }

  int closeButtonOffsetX = (kCaptionHeight - close_button_->height()) / 2;
  int header_width = close_button_->width() + closeButtonOffsetX * 2;
  return gfx::Rect(client_bounds.x(),
                   std::max(0, client_bounds.y() - kCaptionHeight),
                   std::max(header_width, client_bounds.width()),
                   client_bounds.height() + kCaptionHeight);
}

int AppWindowFrameView::NonClientHitTest(const gfx::Point& point) {
  if (frame_->IsFullscreen())
    return HTCLIENT;

  gfx::Rect expanded_bounds = bounds();
  if (resize_outside_bounds_size_)
    expanded_bounds.Inset(gfx::Insets(-resize_outside_bounds_size_,
                                      -resize_outside_bounds_size_,
                                      -resize_outside_bounds_size_,
                                      -resize_outside_bounds_size_));
  // Points outside the (possibly expanded) bounds can be discarded.
  if (!expanded_bounds.Contains(point))
    return HTNOWHERE;

  // Check the frame first, as we allow a small area overlapping the contents
  // to be used for resize handles.
  bool can_ever_resize = frame_->widget_delegate()
                             ? frame_->widget_delegate()->CanResize()
                             : false;
  // Don't allow overlapping resize handles when the window is maximized or
  // fullscreen, as it can't be resized in those states.
  int resize_border = (frame_->IsMaximized() || frame_->IsFullscreen())
                          ? 0
                          : resize_inside_bounds_size_;
  int frame_component = GetHTComponentForFrame(point,
                                               resize_border,
                                               resize_border,
                                               resize_area_corner_size_,
                                               resize_area_corner_size_,
                                               can_ever_resize);
  if (frame_component != HTNOWHERE)
    return frame_component;

  // Check for possible draggable region in the client area for the frameless
  // window.
  if (window_->IsFrameless()) {
    SkRegion* draggable_region = window_->GetDraggableRegion();
    if (draggable_region && draggable_region->contains(point.x(), point.y()))
      return HTCAPTION;
  }

  int client_component = frame_->client_view()->NonClientHitTest(point);
  if (client_component != HTNOWHERE)
    return client_component;

  // Then see if the point is within any of the window controls.
  if (close_button_ && close_button_->visible() &&
      close_button_->GetMirroredBounds().Contains(point)) {
    return HTCLOSE;
  }
  if ((maximize_button_ && maximize_button_->visible() &&
       maximize_button_->GetMirroredBounds().Contains(point)) ||
      (restore_button_ && restore_button_->visible() &&
       restore_button_->GetMirroredBounds().Contains(point))) {
    return HTMAXBUTTON;
  }
  if (minimize_button_ && minimize_button_->visible() &&
      minimize_button_->GetMirroredBounds().Contains(point)) {
    return HTMINBUTTON;
  }

  // Caption is a safe default.
  return HTCAPTION;
}

void AppWindowFrameView::GetWindowMask(const gfx::Size& size,
                                       gfx::Path* window_mask) {
  // We got nothing to say about no window mask.
}

// views::View implementation.

gfx::Size AppWindowFrameView::GetPreferredSize() {
  gfx::Size pref = frame_->client_view()->GetPreferredSize();
  gfx::Rect bounds(0, 0, pref.width(), pref.height());
  return frame_->non_client_view()
      ->GetWindowBoundsForClientBounds(bounds)
      .size();
}

void AppWindowFrameView::Layout() {
  if (window_->IsFrameless())
    return;
  gfx::Size close_size = close_button_->GetPreferredSize();
  const int kButtonOffsetY = 0;
  const int kButtonSpacing = 1;
  const int kRightMargin = 3;

  close_button_->SetBounds(width() - kRightMargin - close_size.width(),
                           kButtonOffsetY,
                           close_size.width(),
                           close_size.height());

  bool can_ever_resize = frame_->widget_delegate()
                             ? frame_->widget_delegate()->CanResize()
                             : false;
  maximize_button_->SetEnabled(can_ever_resize);
  gfx::Size maximize_size = maximize_button_->GetPreferredSize();
  maximize_button_->SetBounds(
      close_button_->x() - kButtonSpacing - maximize_size.width(),
      kButtonOffsetY,
      maximize_size.width(),
      maximize_size.height());
  gfx::Size restore_size = restore_button_->GetPreferredSize();
  restore_button_->SetBounds(
      close_button_->x() - kButtonSpacing - restore_size.width(),
      kButtonOffsetY,
      restore_size.width(),
      restore_size.height());

  bool maximized = frame_->IsMaximized();
  maximize_button_->SetVisible(!maximized);
  restore_button_->SetVisible(maximized);
  if (maximized)
    maximize_button_->SetState(views::CustomButton::STATE_NORMAL);
  else
    restore_button_->SetState(views::CustomButton::STATE_NORMAL);

  gfx::Size minimize_size = minimize_button_->GetPreferredSize();
  minimize_button_->SetState(views::CustomButton::STATE_NORMAL);
  minimize_button_->SetBounds(
      maximize_button_->x() - kButtonSpacing - minimize_size.width(),
      kButtonOffsetY,
      minimize_size.width(),
      minimize_size.height());
}

void AppWindowFrameView::OnPaint(gfx::Canvas* canvas) {
  if (window_->IsFrameless())
    return;

  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  if (ShouldPaintAsActive()) {
    close_button_->SetImage(
        views::CustomButton::STATE_NORMAL,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE).ToImageSkia());
  } else {
    close_button_->SetImage(
        views::CustomButton::STATE_NORMAL,
        rb.GetNativeImageNamed(IDR_APP_WINDOW_CLOSE_U).ToImageSkia());
  }

  // TODO(jeremya): different look for inactive?
  SkPaint paint;
  paint.setAntiAlias(false);
  paint.setStyle(SkPaint::kFill_Style);
  paint.setColor(SK_ColorWHITE);
  gfx::Path path;
  path.moveTo(0, 0);
  path.lineTo(width(), 0);
  path.lineTo(width(), kCaptionHeight);
  path.lineTo(0, kCaptionHeight);
  path.close();
  canvas->DrawPath(path, paint);
}

const char* AppWindowFrameView::GetClassName() const { return kViewClassName; }

gfx::Size AppWindowFrameView::GetMinimumSize() {
  gfx::Size min_size = frame_->client_view()->GetMinimumSize();
  if (window_->IsFrameless())
    return min_size;

  // Ensure we can display the top of the caption area.
  gfx::Rect client_bounds = GetBoundsForClientView();
  min_size.Enlarge(0, client_bounds.y());
  // Ensure we have enough space for the window icon and buttons.  We allow
  // the title string to collapse to zero width.
  int closeButtonOffsetX = (kCaptionHeight - close_button_->height()) / 2;
  int header_width = close_button_->width() + closeButtonOffsetX * 2;
  if (header_width > min_size.width())
    min_size.set_width(header_width);
  return min_size;
}

gfx::Size AppWindowFrameView::GetMaximumSize() {
  gfx::Size max_size = frame_->client_view()->GetMaximumSize();

  // Add to the client maximum size the height of any title bar and borders.
  gfx::Size client_size = GetBoundsForClientView().size();
  if (max_size.width())
    max_size.Enlarge(width() - client_size.width(), 0);
  if (max_size.height())
    max_size.Enlarge(0, height() - client_size.height());

  return max_size;
}

// views::ButtonListener implementation.

void AppWindowFrameView::ButtonPressed(views::Button* sender,
                                       const ui::Event& event) {
  DCHECK(!window_->IsFrameless());
  if (sender == close_button_)
    frame_->Close();
  else if (sender == maximize_button_)
    frame_->Maximize();
  else if (sender == restore_button_)
    frame_->Restore();
  else if (sender == minimize_button_)
    frame_->Minimize();
}

}  // namespace apps
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>

int main(){
    // open a file in read mode.
    ifstream infile;

}
<commit_msg>adding pass runner skeleton<commit_after>#include <iostream>
#include <fstream>
#include <vector>
#include <string>

using namespace std;

// vector with permutations of passorder
vector<string> passOrder;

void runOptimizationPasses(){

    for( int i = 0; i < passOrder.size() ; ++i ) {
        system(NULL);
    }
}

// print operator for vector<string>
void operator<<(ostream& os, vector<string> V){
    for( vector<string>::iterator it = V.begin(); it != V.end() ; ++it ) {
        os << *it << endl;
    }
}

int main(){
    // open a file in read mode.
    ifstream infile;
    infile.open("events.1");

    string opt_order;
    while(getline(infile,opt_order)) {
        passOrder.push_back(opt_order);
    }

    // this will potentially print the contents of events.1 file
#ifdef VERBOSE
    cout << passOrder;
#endif

    runOptimizationPasses();

}
<|endoftext|>


<commit_before>#pragma once

#include "common/SignalVector.hpp"

#include <QAbstractTableModel>
#include <QMimeData>
#include <QStandardItem>
#include <boost/optional.hpp>

#include <pajlada/signals/signalholder.hpp>

namespace chatterino {

template <typename TVectorItem>
class SignalVectorModel : public QAbstractTableModel,
                          pajlada::Signals::SignalHolder
{
public:
    SignalVectorModel(int columnCount, QObject *parent = nullptr)
        : QAbstractTableModel(parent)
        , columnCount_(columnCount)
    {
        for (int i = 0; i < columnCount; i++)
        {
            this->headerData_.emplace_back();
        }
    }

    void initialize(SignalVector<TVectorItem> *vec)
    {
        this->vector_ = vec;

        auto insert = [this](const SignalVectorItemEvent<TVectorItem> &args) {
            if (args.caller == this)
            {
                return;
            }
            // get row index
            int index = this->getModelIndexFromVectorIndex(args.index);
            assert(index >= 0 && index <= this->rows_.size());

            // get row items
            std::vector<QStandardItem *> row = this->createRow();
            this->getRowFromItem(args.item, row);

            // insert row
            index = this->beforeInsert(args.item, row, index);

            this->beginInsertRows(QModelIndex(), index, index);
            this->rows_.insert(this->rows_.begin() + index,
                               Row(row, args.item));
            this->endInsertRows();
        };

        int i = 0;
        for (const TVectorItem &item : vec->raw())
        {
            SignalVectorItemEvent<TVectorItem> args{item, i++, 0};

            insert(args);
        }

        this->managedConnect(vec->itemInserted, insert);

        this->managedConnect(vec->itemRemoved, [this](auto args) {
            if (args.caller == this)
            {
                return;
            }

            int row = this->getModelIndexFromVectorIndex(args.index);
            assert(row >= 0 && row <= this->rows_.size());

            // remove row
            std::vector<QStandardItem *> items = this->rows_[row].items;

            this->beginRemoveRows(QModelIndex(), row, row);
            this->rows_.erase(this->rows_.begin() + row);
            this->endRemoveRows();

            this->afterRemoved(args.item, items, row);

            for (QStandardItem *item : items)
            {
                delete item;
            }
        });

        this->afterInit();
    }

    SignalVectorModel<TVectorItem> *initialized(SignalVector<TVectorItem> *vec)
    {
        this->initialize(vec);
        return this;
    }

    virtual ~SignalVectorModel()
    {
        for (Row &row : this->rows_)
        {
            for (QStandardItem *item : row.items)
            {
                delete item;
            }
        }
    }

    int rowCount(const QModelIndex &parent) const override
    {
        (void)parent;

        return this->rows_.size();
    }

    int columnCount(const QModelIndex &parent) const override
    {
        (void)parent;

        return this->columnCount_;
    }

    QVariant data(const QModelIndex &index, int role) const override
    {
        int row = index.row(), column = index.column();
        if (row < 0 || column < 0 || row >= this->rows_.size() ||
            column >= this->columnCount_)
        {
            return QVariant();
        }

        return rows_[row].items[column]->data(role);
    }

    bool setData(const QModelIndex &index, const QVariant &value,
                 int role) override
    {
        int row = index.row(), column = index.column();
        if (row < 0 || column < 0 || row >= this->rows_.size() ||
            column >= this->columnCount_)
        {
            return false;
        }

        Row &rowItem = this->rows_[row];

        assert(this->columnCount_ == rowItem.items.size());

        auto &cell = rowItem.items[column];

        cell->setData(value, role);

        if (rowItem.isCustomRow)
        {
            this->customRowSetData(rowItem.items, column, value, role, row);
        }
        else
        {
            int vecRow = this->getVectorIndexFromModelIndex(row);
            this->vector_->removeAt(vecRow, this);

            assert(this->rows_[row].original);
            TVectorItem item = this->getItemFromRow(
                this->rows_[row].items, this->rows_[row].original.get());
            this->vector_->insert(item, vecRow, this);
        }

        return true;
    }

    QVariant headerData(int section, Qt::Orientation orientation,
                        int role) const override
    {
        if (orientation != Qt::Horizontal)
        {
            return QVariant();
        }

        auto it = this->headerData_[section].find(role);
        if (it == this->headerData_[section].end())
        {
            return QVariant();
        }
        else
        {
            return it.value();
        }
    }

    bool setHeaderData(int section, Qt::Orientation orientation,
                       const QVariant &value,
                       int role = Qt::DisplayRole) override
    {
        if (orientation != Qt::Horizontal)
        {
            return false;
        }

        this->headerData_[section][role] = value;

        emit this->headerDataChanged(Qt::Horizontal, section, section);
        return true;
    }

    Qt::ItemFlags flags(const QModelIndex &index) const override
    {
        int row = index.row(), column = index.column();

        if (row < 0 || column < 0 || row >= this->rows_.size() ||
            column >= this->columnCount_)
        {
            return Qt::NoItemFlags;
        }

        assert(row >= 0 && row < this->rows_.size() && column >= 0 &&
               column < this->columnCount_);

        const auto &rowItem = this->rows_[row];

        assert(this->columnCount_ == rowItem.items.size());

        return rowItem.items[column]->flags();
    }

    QStandardItem *getItem(int row, int column)
    {
        assert(row >= 0 && row < this->rows_.size() && column >= 0 &&
               column < this->columnCount_);

        const auto &rowItem = this->rows_[row];

        assert(this->columnCount_ == rowItem.items.size());

        return rowItem.items[column];
    }

    void deleteRow(int row)
    {
        int signalVectorRow = this->getVectorIndexFromModelIndex(row);
        this->vector_->removeAt(signalVectorRow);
    }

    bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count,
                  const QModelIndex &destinationParent,
                  int destinationChild) override
    {
        if (count != 1)
        {
            return false;
        }

        assert(sourceRow >= 0 && sourceRow < this->rows_.size());

        int signalVectorRow = this->getVectorIndexFromModelIndex(sourceRow);
        this->beginMoveRows(sourceParent, sourceRow, sourceRow,
                            destinationParent, destinationChild);

        TVectorItem item =
            this->getItemFromRow(this->rows_[sourceRow].items,
                                 this->rows_[sourceRow].original.get());
        this->vector_->removeAt(signalVectorRow);
        this->vector_->insert(
            item, this->getVectorIndexFromModelIndex(destinationChild));

        this->endMoveRows();

        return true;
    }

    bool removeRows(int row, int count, const QModelIndex &parent) override
    {
        (void)parent;

        if (count != 1)
        {
            return false;
        }

        assert(row >= 0 && row < this->rows_.size());

        int signalVectorRow = this->getVectorIndexFromModelIndex(row);
        this->vector_->removeAt(signalVectorRow);

        return true;
    }

    QStringList mimeTypes() const override
    {
        return {"chatterino_row_id"};
    }

    QMimeData *mimeData(const QModelIndexList &list) const override
    {
        if (list.length() == 1)
        {
            return nullptr;
        }

        // Check if all indices are in the same row -> single row selected
        for (auto &&x : list)
        {
            if (x.row() != list.first().row())
                return nullptr;
        }

        auto data = new QMimeData;
        data->setData("chatterino_row_id", QByteArray::number(list[0].row()));
        return data;
    }

    bool dropMimeData(const QMimeData *data, Qt::DropAction action, int /*row*/,
                      int /*column*/, const QModelIndex &parent) override
    {
        if (data->hasFormat("chatterino_row_id") &&
            action & (Qt::DropAction::MoveAction | Qt::DropAction::CopyAction))
        {
            int from = data->data("chatterino_row_id").toInt();
            int to = parent.row();

            int vectorFrom = this->getVectorIndexFromModelIndex(from);
            int vectorTo = this->getVectorIndexFromModelIndex(to);

            if (vectorFrom < 0 || vectorFrom > this->vector_->raw().size() ||
                vectorTo < 0 || vectorTo > this->vector_->raw().size())
            {
                return false;
            }

            if (from != to)
            {
                this->moveRow(this->index(from, to), from, parent, to);
            }

            // We return false since we remove items ourselves.
            return false;
        }

        return false;
    }

    Qt::DropActions supportedDropActions() const override
    {
        return this->vector_->isSorted()
                   ? Qt::DropActions()
                   : Qt::DropAction::CopyAction | Qt::DropAction::MoveAction;
    }

protected:
    virtual void afterInit()
    {
    }

    // turn a vector item into a model row
    virtual TVectorItem getItemFromRow(std::vector<QStandardItem *> &row,
                                       const TVectorItem &original) = 0;

    // turns a row in the model into a vector item
    virtual void getRowFromItem(const TVectorItem &item,
                                std::vector<QStandardItem *> &row) = 0;

    virtual int beforeInsert(const TVectorItem &item,
                             std::vector<QStandardItem *> &row,
                             int proposedIndex)
    {
        (void)item, (void)row;

        return proposedIndex;
    }

    virtual void afterRemoved(const TVectorItem &item,
                              std::vector<QStandardItem *> &row, int index)
    {
        (void)item, (void)row, (void)index;
    }

    virtual void customRowSetData(const std::vector<QStandardItem *> &row,
                                  int column, const QVariant &value, int role,
                                  int rowIndex)
    {
        (void)row, (void)column, (void)value, (void)role, (void)rowIndex;
    }

    void insertCustomRow(std::vector<QStandardItem *> row, int index)
    {
        assert(index >= 0 && index <= this->rows_.size());

        this->beginInsertRows(QModelIndex(), index, index);
        this->rows_.insert(this->rows_.begin() + index,
                           Row(std::move(row), true));
        this->endInsertRows();
    }

    void removeCustomRow(int index)
    {
        assert(index >= 0 && index <= this->rows_.size());
        assert(this->rows_[index].isCustomRow);

        this->beginRemoveRows(QModelIndex(), index, index);
        this->rows_.erase(this->rows_.begin() + index);
        this->endRemoveRows();
    }

    std::vector<QStandardItem *> createRow()
    {
        std::vector<QStandardItem *> row;
        for (int i = 0; i < this->columnCount_; i++)
        {
            row.push_back(new QStandardItem());
        }
        return row;
    }

    struct Row {
        std::vector<QStandardItem *> items;
        boost::optional<TVectorItem> original;
        bool isCustomRow;

        Row(std::vector<QStandardItem *> _items, bool _isCustomRow = false)
            : items(std::move(_items))
            , isCustomRow(_isCustomRow)
        {
        }

        Row(std::vector<QStandardItem *> _items, const TVectorItem &_original,
            bool _isCustomRow = false)
            : items(std::move(_items))
            , original(_original)
            , isCustomRow(_isCustomRow)
        {
        }
    };

private:
    std::vector<QMap<int, QVariant>> headerData_;
    SignalVector<TVectorItem> *vector_;
    std::vector<Row> rows_;

    const int columnCount_;

    // returns the related index of the SignalVector
    int getVectorIndexFromModelIndex(int index)
    {
        int i = 0;

        for (auto &row : this->rows_)
        {
            if (row.isCustomRow)
            {
                index--;
                continue;
            }

            if (i == index)
            {
                return i;
            }
            i++;
        }

        return i;
    }

    // returns the related index of the model
    int getModelIndexFromVectorIndex(int index)
    {
        int i = 0;

        for (auto &row : this->rows_)
        {
            if (row.isCustomRow)
            {
                index++;
            }

            if (i == index)
            {
                return i;
            }
            i++;
        }

        return i;
    }
};

}  // namespace chatterino
<commit_msg>Refactor parts of SignalVectorModel (#3342)<commit_after>#pragma once

#include "common/SignalVector.hpp"

#include <QAbstractTableModel>
#include <QMimeData>
#include <QStandardItem>
#include <boost/optional.hpp>

#include <pajlada/signals/signalholder.hpp>

namespace chatterino {

template <typename TVectorItem>
class SignalVectorModel : public QAbstractTableModel,
                          pajlada::Signals::SignalHolder
{
public:
    SignalVectorModel(int columnCount, QObject *parent = nullptr)
        : QAbstractTableModel(parent)
        , columnCount_(columnCount)
    {
        for (int i = 0; i < columnCount; i++)
        {
            this->headerData_.emplace_back();
        }
    }

    void initialize(SignalVector<TVectorItem> *vec)
    {
        this->vector_ = vec;

        auto insert = [this](const SignalVectorItemEvent<TVectorItem> &args) {
            if (args.caller == this)
            {
                return;
            }
            // get row index
            int index = this->getModelIndexFromVectorIndex(args.index);
            assert(index >= 0 && index <= this->rows_.size());

            // get row items
            std::vector<QStandardItem *> row = this->createRow();
            this->getRowFromItem(args.item, row);

            // insert row
            index = this->beforeInsert(args.item, row, index);

            this->beginInsertRows(QModelIndex(), index, index);
            this->rows_.insert(this->rows_.begin() + index,
                               Row(row, args.item));
            this->endInsertRows();
        };

        int i = 0;
        for (const TVectorItem &item : vec->raw())
        {
            SignalVectorItemEvent<TVectorItem> args{item, i++, 0};

            insert(args);
        }

        this->managedConnect(vec->itemInserted, insert);

        this->managedConnect(vec->itemRemoved, [this](auto args) {
            if (args.caller == this)
            {
                return;
            }

            int row = this->getModelIndexFromVectorIndex(args.index);
            assert(row >= 0 && row <= this->rows_.size());

            // remove row
            std::vector<QStandardItem *> items = this->rows_[row].items;

            this->beginRemoveRows(QModelIndex(), row, row);
            this->rows_.erase(this->rows_.begin() + row);
            this->endRemoveRows();

            this->afterRemoved(args.item, items, row);

            for (QStandardItem *item : items)
            {
                delete item;
            }
        });

        this->afterInit();
    }

    SignalVectorModel<TVectorItem> *initialized(SignalVector<TVectorItem> *vec)
    {
        this->initialize(vec);
        return this;
    }

    virtual ~SignalVectorModel()
    {
        for (Row &row : this->rows_)
        {
            for (QStandardItem *item : row.items)
            {
                delete item;
            }
        }
    }

    int rowCount(const QModelIndex &parent) const override
    {
        (void)parent;

        return this->rows_.size();
    }

    int columnCount(const QModelIndex &parent) const override
    {
        (void)parent;

        return this->columnCount_;
    }

    QVariant data(const QModelIndex &index, int role) const override
    {
        int row = index.row(), column = index.column();
        if (row < 0 || column < 0 || row >= this->rows_.size() ||
            column >= this->columnCount_)
        {
            return QVariant();
        }

        return rows_[row].items[column]->data(role);
    }

    bool setData(const QModelIndex &index, const QVariant &value,
                 int role) override
    {
        int row = index.row(), column = index.column();
        if (row < 0 || column < 0 || row >= this->rows_.size() ||
            column >= this->columnCount_)
        {
            return false;
        }

        Row &rowItem = this->rows_[row];

        assert(this->columnCount_ == rowItem.items.size());

        auto &cell = rowItem.items[column];

        cell->setData(value, role);

        if (rowItem.isCustomRow)
        {
            this->customRowSetData(rowItem.items, column, value, role, row);
        }
        else
        {
            int vecRow = this->getVectorIndexFromModelIndex(row);
            this->vector_->removeAt(vecRow, this);

            assert(this->rows_[row].original);
            TVectorItem item = this->getItemFromRow(
                this->rows_[row].items, this->rows_[row].original.get());
            this->vector_->insert(item, vecRow, this);
        }

        return true;
    }

    QVariant headerData(int section, Qt::Orientation orientation,
                        int role) const override
    {
        if (orientation != Qt::Horizontal)
        {
            return QVariant();
        }

        auto it = this->headerData_[section].find(role);
        if (it == this->headerData_[section].end())
        {
            return QVariant();
        }
        else
        {
            return it.value();
        }
    }

    bool setHeaderData(int section, Qt::Orientation orientation,
                       const QVariant &value,
                       int role = Qt::DisplayRole) override
    {
        if (orientation != Qt::Horizontal)
        {
            return false;
        }

        this->headerData_[section][role] = value;

        emit this->headerDataChanged(Qt::Horizontal, section, section);
        return true;
    }

    Qt::ItemFlags flags(const QModelIndex &index) const override
    {
        int row = index.row(), column = index.column();

        if (row < 0 || column < 0 || row >= this->rows_.size() ||
            column >= this->columnCount_)
        {
            return Qt::NoItemFlags;
        }

        assert(row >= 0 && row < this->rows_.size() && column >= 0 &&
               column < this->columnCount_);

        const auto &rowItem = this->rows_[row];

        assert(this->columnCount_ == rowItem.items.size());

        return rowItem.items[column]->flags();
    }

    QStandardItem *getItem(int row, int column)
    {
        assert(row >= 0 && row < this->rows_.size() && column >= 0 &&
               column < this->columnCount_);

        const auto &rowItem = this->rows_[row];

        assert(this->columnCount_ == rowItem.items.size());

        return rowItem.items[column];
    }

    void deleteRow(int row)
    {
        int signalVectorRow = this->getVectorIndexFromModelIndex(row);
        this->vector_->removeAt(signalVectorRow);
    }

    bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count,
                  const QModelIndex &destinationParent,
                  int destinationChild) override
    {
        if (count != 1)
        {
            return false;
        }

        assert(sourceRow >= 0 && sourceRow < this->rows_.size());

        int signalVectorRow = this->getVectorIndexFromModelIndex(sourceRow);
        this->beginMoveRows(sourceParent, sourceRow, sourceRow,
                            destinationParent, destinationChild);

        TVectorItem item =
            this->getItemFromRow(this->rows_[sourceRow].items,
                                 this->rows_[sourceRow].original.get());
        this->vector_->removeAt(signalVectorRow);
        this->vector_->insert(
            item, this->getVectorIndexFromModelIndex(destinationChild));

        this->endMoveRows();

        return true;
    }

    bool removeRows(int row, int count, const QModelIndex &parent) override
    {
        (void)parent;

        if (count != 1)
        {
            return false;
        }

        assert(row >= 0 && row < this->rows_.size());

        int signalVectorRow = this->getVectorIndexFromModelIndex(row);
        this->vector_->removeAt(signalVectorRow);

        return true;
    }

    QStringList mimeTypes() const override
    {
        return {"chatterino_row_id"};
    }

    QMimeData *mimeData(const QModelIndexList &list) const override
    {
        if (list.length() == 1)
        {
            return nullptr;
        }

        // Check if all indices are in the same row -> single row selected
        for (auto &&x : list)
        {
            if (x.row() != list.first().row())
                return nullptr;
        }

        auto data = new QMimeData;
        data->setData("chatterino_row_id", QByteArray::number(list[0].row()));
        return data;
    }

    bool dropMimeData(const QMimeData *data, Qt::DropAction action, int /*row*/,
                      int /*column*/, const QModelIndex &parent) override
    {
        if (data->hasFormat("chatterino_row_id") &&
            action & (Qt::DropAction::MoveAction | Qt::DropAction::CopyAction))
        {
            int from = data->data("chatterino_row_id").toInt();
            int to = parent.row();

            int vectorFrom = this->getVectorIndexFromModelIndex(from);
            int vectorTo = this->getVectorIndexFromModelIndex(to);

            if (vectorFrom < 0 || vectorFrom > this->vector_->raw().size() ||
                vectorTo < 0 || vectorTo > this->vector_->raw().size())
            {
                return false;
            }

            if (from != to)
            {
                this->moveRow(this->index(from, to), from, parent, to);
            }

            // We return false since we remove items ourselves.
            return false;
        }

        return false;
    }

    Qt::DropActions supportedDropActions() const override
    {
        return this->vector_->isSorted()
                   ? Qt::DropActions()
                   : Qt::DropAction::CopyAction | Qt::DropAction::MoveAction;
    }

protected:
    virtual void afterInit()
    {
    }

    // turn a vector item into a model row
    virtual TVectorItem getItemFromRow(std::vector<QStandardItem *> &row,
                                       const TVectorItem &original) = 0;

    // turns a row in the model into a vector item
    virtual void getRowFromItem(const TVectorItem &item,
                                std::vector<QStandardItem *> &row) = 0;

    virtual int beforeInsert(const TVectorItem &item,
                             std::vector<QStandardItem *> &row,
                             int proposedIndex)
    {
        (void)item, (void)row;

        return proposedIndex;
    }

    virtual void afterRemoved(const TVectorItem &item,
                              std::vector<QStandardItem *> &row, int index)
    {
        (void)item, (void)row, (void)index;
    }

    virtual void customRowSetData(const std::vector<QStandardItem *> &row,
                                  int column, const QVariant &value, int role,
                                  int rowIndex)
    {
        (void)row, (void)column, (void)value, (void)role, (void)rowIndex;
    }

    void insertCustomRow(std::vector<QStandardItem *> row, int index)
    {
        assert(index >= 0 && index <= this->rows_.size());

        this->beginInsertRows(QModelIndex(), index, index);
        this->rows_.insert(this->rows_.begin() + index,
                           Row(std::move(row), true));
        this->endInsertRows();
    }

    void removeCustomRow(int index)
    {
        assert(index >= 0 && index <= this->rows_.size());
        assert(this->rows_[index].isCustomRow);

        this->beginRemoveRows(QModelIndex(), index, index);
        this->rows_.erase(this->rows_.begin() + index);
        this->endRemoveRows();
    }

    std::vector<QStandardItem *> createRow()
    {
        std::vector<QStandardItem *> row;
        for (int i = 0; i < this->columnCount_; i++)
        {
            row.push_back(new QStandardItem());
        }
        return row;
    }

    struct Row {
        std::vector<QStandardItem *> items;
        boost::optional<TVectorItem> original;
        bool isCustomRow;

        Row(std::vector<QStandardItem *> _items, bool _isCustomRow = false)
            : items(std::move(_items))
            , isCustomRow(_isCustomRow)
        {
        }

        Row(std::vector<QStandardItem *> _items, const TVectorItem &_original,
            bool _isCustomRow = false)
            : items(std::move(_items))
            , original(_original)
            , isCustomRow(_isCustomRow)
        {
        }
    };

    const std::vector<Row> &rows() const
    {
        return this->rows_;
    }

private:
    std::vector<QMap<int, QVariant>> headerData_;
    SignalVector<TVectorItem> *vector_;
    std::vector<Row> rows_;

    const int columnCount_;

    // returns the related index of the SignalVector
    int getVectorIndexFromModelIndex(int index)
    {
        int i = 0;

        for (auto &row : this->rows_)
        {
            if (row.isCustomRow)
            {
                index--;
                continue;
            }

            if (i == index)
            {
                return i;
            }
            i++;
        }

        return i;
    }

public:
    // returns the related index of the model
    int getModelIndexFromVectorIndex(int vectorIndex) const
    {
        int modelIndex = 0;

        for (auto &row : this->rows())
        {
            if (row.isCustomRow)
            {
                vectorIndex++;
            }

            if (modelIndex == vectorIndex)
            {
                return modelIndex;
            }

            modelIndex++;
        }

        return modelIndex;
    }
};

}  // namespace chatterino
<|endoftext|>


<commit_before>#include "packagerplugin.h"

#include <QFileInfo>

PackagerPlugin::PackagerPlugin(QObject *parent) :
    PackagerInterface(parent)
{
}

Q_EXPORT_PLUGIN2(PackagerPlugin, PackagerPlugin)

PackagerPlugin::~PackagerPlugin()
{
}

QString PackagerPlugin::name() const
{
    return "PackagerPlugin";
}

QString PackagerPlugin::version() const
{
    return "1.0";
}

void PackagerPlugin::setDefaultParameters()
{

}

bool PackagerPlugin::pack(const QString &path, const QString &name)
{
    QFile *file = new QFile(name);
    if (!file->open(QIODevice::WriteOnly)) {
        return false;
    }

    int size = 1048576;
    for (int i = 0; i < 20; i++) {
        char *data = new char[size];
        memset(data,'-',size);
        file->seek(i*size);
        file->writeData(reinterpret_cast<const char*>(data), size);
        delete[] data;
    }

    file->close();

    return true;
}

bool PackagerPlugin::unpack(const QString &name, const QString &path)
{
    int size = 1048576;
    for (int i = 0; i < 5; i++) {
        QString filename = path + "/" + "output_" + QString::number(i);
        QFile *file = new QFile(filename);
        if (file->open(QIODevice::WriteOnly)) {
            char *data = new char[size];
            memset(data,'-',size);
            file->writeData(reinterpret_cast<const char*>(data), size);
            delete[] data;
        }
        file->close();
    }

    return true;
}
<commit_msg>fix file write error<commit_after>#include "packagerplugin.h"

#include <QFileInfo>

PackagerPlugin::PackagerPlugin(QObject *parent) :
    PackagerInterface(parent)
{
}

Q_EXPORT_PLUGIN2(PackagerPlugin, PackagerPlugin)

PackagerPlugin::~PackagerPlugin()
{
}

QString PackagerPlugin::name() const
{
    return "PackagerPlugin";
}

QString PackagerPlugin::version() const
{
    return "1.0";
}

void PackagerPlugin::setDefaultParameters()
{

}

bool PackagerPlugin::pack(const QString &path, const QString &name)
{
    QFile *file = new QFile(name);
    if (!file->open(QIODevice::WriteOnly)) {
        return false;
    }

    int size = 1048576;
    for (int i = 0; i < 20; i++) {
        char *data = new char[size];
        memset(data,'-',size);
        file->seek(i*size);
        file->write(reinterpret_cast<const char*>(data), size);
        delete[] data;
    }

    file->close();

    return true;
}

bool PackagerPlugin::unpack(const QString &name, const QString &path)
{
    int size = 1048576;
    for (int i = 0; i < 5; i++) {
        QString filename = path + "/" + "output_" + QString::number(i);
        QFile *file = new QFile(filename);
        if (file->open(QIODevice::WriteOnly)) {
            char *data = new char[size];
            memset(data,'-',size);
            file->write(reinterpret_cast<const char*>(data), size);
            delete[] data;
        }
        file->close();
    }

    return true;
}
<|endoftext|>


<commit_before>//  Natron
//
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
*Created by Alexandre GAUTHIER-FOICHAT on 6/1/2012.
*contact: immarespond at gmail dot com
*
*/

#include "Image.h"

#include "Engine/Lut.h"

RectI Natron::Bitmap::minimalNonMarkedBbox(const RectI& roi) const
{
    /*if we rendered everything we just append
     a NULL box to indicate we rendered it all.*/
//    if(!memchr(_map.get(),0,_rod.area())){
//        ret.push_back(RectI());
//        return ret;
//    }

    RectI bbox = roi;
    //find bottom
    for (int i = bbox.bottom(); i < bbox.top();++i) {
        char* buf = &_map[(i-_rod.bottom())*_rod.width()];
        if(!memchr(buf, 0, _rod.width())){
            bbox.set_bottom(bbox.bottom()+1);
        } else {
            break;
        }
    }

    //find top (will do zero iteration if the bbox is already empty)
    for (int i = bbox.top()-1; i >= bbox.bottom();--i) {
        char* buf = &_map[(i-_rod.bottom())*_rod.width()];
        if (!memchr(buf, 0, _rod.width())) {
            bbox.set_top(bbox.top()-1);
        } else {
            break;
        }
    }

    // avoid making bbox.width() iterations for nothing
    if (bbox.isNull()) {
        return bbox;
    }

    //find left
    for (int j = bbox.left(); j < bbox.right(); ++j) {
        bool shouldStop = false;
        for (int i = bbox.bottom(); i < bbox.top(); ++i) {
            if (!_map[(i-_rod.bottom())*_rod.width() + (j-_rod.left())]) {
                shouldStop = true;
                break;
            }
        }
        if (!shouldStop) {
            bbox.set_left(bbox.left()+1);
        } else {
            break;
        }
    }

    //find right
    for (int j = bbox.right()-1; j >= bbox.left(); --j) {
        bool shouldStop = false;
        for (int i = bbox.bottom(); i < bbox.top(); ++i) {
            if (!_map[(i-_rod.bottom())*_rod.width() + (j-_rod.left())]) {
                shouldStop = true;
                break;
            }
        }
        if (!shouldStop) {
            bbox.set_right(bbox.right()-1);
        } else {
            break;
        }
    }
    return bbox;
}

std::list<RectI> Natron::Bitmap::minimalNonMarkedRects(const RectI& roi) const
{
    std::list<RectI> ret;

    RectI bboxM = minimalNonMarkedBbox(roi);
//#define NATRON_BITMAP_DISABLE_OPTIMIZATION
#ifdef NATRON_BITMAP_DISABLE_OPTIMIZATION
    if (!bboxM.isNull()) { // empty boxes should not be pushed
        ret.push_back(bboxM);
    }
#else
    if (bboxM.isNull()) {
        return ret; // return an empty rectangle list
    }

    // optimization by Fred, Jan 31, 2014
    //
    // Now that we have the smallest enclosing bounding box,
    // let's try to find rectangles for the bottom, the top,
    // the left and the right part.
    // This happens quite often, for example when zooming out
    // (in this case the area to compute is formed of A, B, C and D,
    // and X is already rendered), or when panning (in this case the area
    // is just two rectangles, e.g. A and C, and the rectangles B, D and
    // X are already rendered).
    // The rectangles A, B, C and D from the following drawing are just
    // zeroes, and X contains zeroes and ones.
    //
    // BBBBBBBBBBBBBB
    // BBBBBBBBBBBBBB
    // CXXXXXXXXXXDDD
    // CXXXXXXXXXXDDD
    // CXXXXXXXXXXDDD
    // CXXXXXXXXXXDDD
    // AAAAAAAAAAAAAA

    // First, find if there's an "A" rectangle, and push it to the result
    //find bottom
    RectI bboxX = bboxM;
    RectI bboxA = bboxX;
    bboxA.set_top(bboxX.bottom());
    for (int i = bboxX.bottom(); i < bboxX.top();++i) {
        char* buf = &_map[(i-_rod.bottom())*_rod.width()];
        if (!memchr(buf, 1, _rod.width())) {
            bboxX.set_bottom(bboxX.bottom()+1);
            bboxA.set_top(bboxX.bottom());
        } else {
            break;
        }
    }
    if (!bboxA.isNull()) { // empty boxes should not be pushed
        ret.push_back(bboxA);
    }

    // Now, find the "B" rectangle
    //find top
    RectI bboxB = bboxX;
    bboxB.set_bottom(bboxX.top());
    for (int i = bboxX.top()-1; i >= bboxX.bottom();--i) {
        char* buf = &_map[(i-_rod.bottom())*_rod.width()];
        if (!memchr(buf, 1, _rod.width())) {
            bboxX.set_top(bboxX.top()-1);
            bboxB.set_bottom(bboxX.top());
        } else {
            break;
        }
    }
    if (!bboxB.isNull()) { // empty boxes should not be pushed
        ret.push_back(bboxB);
    }

    //find left
    RectI bboxC = bboxX;
    bboxC.set_right(bboxX.left());
    for (int j = bboxX.left(); j < bboxX.right(); ++j) {
        bool shouldStop = false;
        for (int i = bboxX.bottom(); i < bboxX.top(); ++i) {
            if (_map[(i-_rod.bottom())*_rod.width()+(j-_rod.left())]) {
                shouldStop = true;
                break;
            }
        }
        if (!shouldStop) {
            bboxX.set_left(bboxX.left()+1);
            bboxC.set_right(bboxX.left());
        } else {
            break;
        }
    }
    if (!bboxC.isNull()) { // empty boxes should not be pushed
        ret.push_back(bboxC);
    }

    //find right
    RectI bboxD = bboxX;
    bboxD.set_left(bboxX.right());
    for (int j = bboxX.right()-1; j >= bboxX.left(); --j) {
        bool shouldStop = false;
        for (int i = bboxX.bottom(); i < bboxX.top(); ++i) {
            if (_map[(i-_rod.bottom())*_rod.width()+(j-_rod.left())]) {
                shouldStop = true;
                break;
            }
        }
        if (!shouldStop) {
            bboxX.set_right(bboxX.right()-1);
            bboxD.set_left(bboxX.right());
        } else {
            break;
        }
    }

    assert(bboxA.bottom() == bboxM.bottom());
    assert(bboxA.left() == bboxM.left());
    assert(bboxA.right() == bboxM.right());
    assert(bboxA.top() == bboxX.bottom());

    assert(bboxB.top() == bboxM.top());
    assert(bboxB.left() == bboxM.left());
    assert(bboxB.right() == bboxM.right());
    assert(bboxB.bottom() == bboxX.top());

    assert(bboxC.top() == bboxX.top());
    assert(bboxC.left() == bboxM.left());
    assert(bboxC.right() == bboxX.left());
    assert(bboxC.bottom() == bboxX.bottom());

    assert(bboxD.top() == bboxX.top());
    assert(bboxD.left() == bboxX.right());
    assert(bboxD.right() == bboxM.right());
    assert(bboxD.bottom() == bboxX.bottom());

    // get the bounding box of what's left (the X rectangle in the drawing above)
    bboxX = minimalNonMarkedBbox(bboxX);
    if (!bboxX.isNull()) { // empty boxes should not be pushed
        ret.push_back(bboxX);
    }

#endif // NATRON_BITMAP_DISABLE_OPTIMIZATION
    qDebug() << "render " << ret.size() << " rectangles";
    for (std::list<RectI>::const_iterator it = ret.begin(); it != ret.end(); ++it) {
        qDebug() << "rect: " << it->x1 << ',' << it->x2 << ',' << it->y1 << ',' << it->y2;
    }
    return ret;
}

void Natron::Bitmap::markForRendered(const RectI& roi){
    for (int i = roi.bottom(); i < roi.top();++i) {
        char* buf = &_map[(i-_rod.bottom())*_rod.width() + (roi.left() - _rod.left())];
        memset(buf, 1, roi.width());
    }
}

void Natron::Image::copy(const Natron::Image& other){

    RectI intersection;
    this->_params._rod.intersect(other._params._rod, &intersection);

    if (intersection.isNull()) {
        return;
    }

    const float* src = other.pixelAt(0, 0);
    float* dst = pixelAt(0, 0);
    memcpy(dst, src, intersection.area());
}

namespace Natron{
    void debugImage(Natron::Image* img,const QString& filename){
        const RectI& rod = img->getRoD();
        QImage output(rod.width(),rod.height(),QImage::Format_ARGB32);
        const Natron::Color::Lut* lut = Natron::Color::LutManager::sRGBLut();
        lut->to_byte_packed(output.bits(), img->pixelAt(0, 0), rod, rod, rod,
                            Natron::Color::PACKING_RGBA,Natron::Color::PACKING_BGRA, true,false);
        U64 hashKey = img->getHashKey();
        QString hashKeyStr = QString::number(hashKey);
        QString realFileName = filename.isEmpty() ? QString(hashKeyStr+".png") : filename;
        output.save(realFileName);
    }

}

<commit_msg>Image: fix the last bug (!) in the optimized Bitmap::minimalNonMarkedRects()<commit_after>//  Natron
//
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
*Created by Alexandre GAUTHIER-FOICHAT on 6/1/2012.
*contact: immarespond at gmail dot com
*
*/

#include "Image.h"

#include "Engine/Lut.h"

RectI Natron::Bitmap::minimalNonMarkedBbox(const RectI& roi) const
{
    /*if we rendered everything we just append
     a NULL box to indicate we rendered it all.*/
//    if(!memchr(_map.get(),0,_rod.area())){
//        ret.push_back(RectI());
//        return ret;
//    }

    RectI bbox = roi;
    //find bottom
    for (int i = bbox.bottom(); i < bbox.top();++i) {
        char* buf = &_map[(i-_rod.bottom())*_rod.width()];
        if(!memchr(buf, 0, _rod.width())){
            bbox.set_bottom(bbox.bottom()+1);
        } else {
            break;
        }
    }

    //find top (will do zero iteration if the bbox is already empty)
    for (int i = bbox.top()-1; i >= bbox.bottom();--i) {
        char* buf = &_map[(i-_rod.bottom())*_rod.width()];
        if (!memchr(buf, 0, _rod.width())) {
            bbox.set_top(bbox.top()-1);
        } else {
            break;
        }
    }

    // avoid making bbox.width() iterations for nothing
    if (bbox.isNull()) {
        return bbox;
    }

    //find left
    for (int j = bbox.left(); j < bbox.right(); ++j) {
        bool shouldStop = false;
        for (int i = bbox.bottom(); i < bbox.top(); ++i) {
            if (!_map[(i-_rod.bottom())*_rod.width() + (j-_rod.left())]) {
                shouldStop = true;
                break;
            }
        }
        if (!shouldStop) {
            bbox.set_left(bbox.left()+1);
        } else {
            break;
        }
    }

    //find right
    for (int j = bbox.right()-1; j >= bbox.left(); --j) {
        bool shouldStop = false;
        for (int i = bbox.bottom(); i < bbox.top(); ++i) {
            if (!_map[(i-_rod.bottom())*_rod.width() + (j-_rod.left())]) {
                shouldStop = true;
                break;
            }
        }
        if (!shouldStop) {
            bbox.set_right(bbox.right()-1);
        } else {
            break;
        }
    }
    return bbox;
}

std::list<RectI> Natron::Bitmap::minimalNonMarkedRects(const RectI& roi) const
{
    std::list<RectI> ret;

    RectI bboxM = minimalNonMarkedBbox(roi);
//#define NATRON_BITMAP_DISABLE_OPTIMIZATION
#ifdef NATRON_BITMAP_DISABLE_OPTIMIZATION
    if (!bboxM.isNull()) { // empty boxes should not be pushed
        ret.push_back(bboxM);
    }
#else
    if (bboxM.isNull()) {
        return ret; // return an empty rectangle list
    }

    // optimization by Fred, Jan 31, 2014
    //
    // Now that we have the smallest enclosing bounding box,
    // let's try to find rectangles for the bottom, the top,
    // the left and the right part.
    // This happens quite often, for example when zooming out
    // (in this case the area to compute is formed of A, B, C and D,
    // and X is already rendered), or when panning (in this case the area
    // is just two rectangles, e.g. A and C, and the rectangles B, D and
    // X are already rendered).
    // The rectangles A, B, C and D from the following drawing are just
    // zeroes, and X contains zeroes and ones.
    //
    // BBBBBBBBBBBBBB
    // BBBBBBBBBBBBBB
    // CXXXXXXXXXXDDD
    // CXXXXXXXXXXDDD
    // CXXXXXXXXXXDDD
    // CXXXXXXXXXXDDD
    // AAAAAAAAAAAAAA

    // First, find if there's an "A" rectangle, and push it to the result
    //find bottom
    RectI bboxX = bboxM;
    RectI bboxA = bboxX;
    bboxA.set_top(bboxX.bottom());
    for (int i = bboxX.bottom(); i < bboxX.top();++i) {
        char* buf = &_map[(i-_rod.bottom())*_rod.width()];
        if (!memchr(buf, 1, _rod.width())) {
            bboxX.set_bottom(bboxX.bottom()+1);
            bboxA.set_top(bboxX.bottom());
        } else {
            break;
        }
    }
    if (!bboxA.isNull()) { // empty boxes should not be pushed
        ret.push_back(bboxA);
    }

    // Now, find the "B" rectangle
    //find top
    RectI bboxB = bboxX;
    bboxB.set_bottom(bboxX.top());
    for (int i = bboxX.top()-1; i >= bboxX.bottom();--i) {
        char* buf = &_map[(i-_rod.bottom())*_rod.width()];
        if (!memchr(buf, 1, _rod.width())) {
            bboxX.set_top(bboxX.top()-1);
            bboxB.set_bottom(bboxX.top());
        } else {
            break;
        }
    }
    if (!bboxB.isNull()) { // empty boxes should not be pushed
        ret.push_back(bboxB);
    }

    //find left
    RectI bboxC = bboxX;
    bboxC.set_right(bboxX.left());
    for (int j = bboxX.left(); j < bboxX.right(); ++j) {
        bool shouldStop = false;
        for (int i = bboxX.bottom(); i < bboxX.top(); ++i) {
            if (_map[(i-_rod.bottom())*_rod.width()+(j-_rod.left())]) {
                shouldStop = true;
                break;
            }
        }
        if (!shouldStop) {
            bboxX.set_left(bboxX.left()+1);
            bboxC.set_right(bboxX.left());
        } else {
            break;
        }
    }
    if (!bboxC.isNull()) { // empty boxes should not be pushed
        ret.push_back(bboxC);
    }

    //find right
    RectI bboxD = bboxX;
    bboxD.set_left(bboxX.right());
    for (int j = bboxX.right()-1; j >= bboxX.left(); --j) {
        bool shouldStop = false;
        for (int i = bboxX.bottom(); i < bboxX.top(); ++i) {
            if (_map[(i-_rod.bottom())*_rod.width()+(j-_rod.left())]) {
                shouldStop = true;
                break;
            }
        }
        if (!shouldStop) {
            bboxX.set_right(bboxX.right()-1);
            bboxD.set_left(bboxX.right());
        } else {
            break;
        }
    }
    if (!bboxD.isNull()) { // empty boxes should not be pushed
        ret.push_back(bboxD);
    }

    assert(bboxA.bottom() == bboxM.bottom());
    assert(bboxA.left() == bboxM.left());
    assert(bboxA.right() == bboxM.right());
    assert(bboxA.top() == bboxX.bottom());

    assert(bboxB.top() == bboxM.top());
    assert(bboxB.left() == bboxM.left());
    assert(bboxB.right() == bboxM.right());
    assert(bboxB.bottom() == bboxX.top());

    assert(bboxC.top() == bboxX.top());
    assert(bboxC.left() == bboxM.left());
    assert(bboxC.right() == bboxX.left());
    assert(bboxC.bottom() == bboxX.bottom());

    assert(bboxD.top() == bboxX.top());
    assert(bboxD.left() == bboxX.right());
    assert(bboxD.right() == bboxM.right());
    assert(bboxD.bottom() == bboxX.bottom());

    // get the bounding box of what's left (the X rectangle in the drawing above)
    bboxX = minimalNonMarkedBbox(bboxX);
    if (!bboxX.isNull()) { // empty boxes should not be pushed
        ret.push_back(bboxX);
    }

#endif // NATRON_BITMAP_DISABLE_OPTIMIZATION
    qDebug() << "render " << ret.size() << " rectangles";
    for (std::list<RectI>::const_iterator it = ret.begin(); it != ret.end(); ++it) {
        qDebug() << "rect: " << it->x1 << ',' << it->x2 << ',' << it->y1 << ',' << it->y2;
    }
    return ret;
}

void Natron::Bitmap::markForRendered(const RectI& roi){
    for (int i = roi.bottom(); i < roi.top();++i) {
        char* buf = &_map[(i-_rod.bottom())*_rod.width() + (roi.left() - _rod.left())];
        memset(buf, 1, roi.width());
    }
}

void Natron::Image::copy(const Natron::Image& other){

    RectI intersection;
    this->_params._rod.intersect(other._params._rod, &intersection);

    if (intersection.isNull()) {
        return;
    }

    const float* src = other.pixelAt(0, 0);
    float* dst = pixelAt(0, 0);
    memcpy(dst, src, intersection.area());
}

namespace Natron{
    void debugImage(Natron::Image* img,const QString& filename){
        const RectI& rod = img->getRoD();
        QImage output(rod.width(),rod.height(),QImage::Format_ARGB32);
        const Natron::Color::Lut* lut = Natron::Color::LutManager::sRGBLut();
        lut->to_byte_packed(output.bits(), img->pixelAt(0, 0), rod, rod, rod,
                            Natron::Color::PACKING_RGBA,Natron::Color::PACKING_BGRA, true,false);
        U64 hashKey = img->getHashKey();
        QString hashKeyStr = QString::number(hashKey);
        QString realFileName = filename.isEmpty() ? QString(hashKeyStr+".png") : filename;
        output.save(realFileName);
    }

}

<|endoftext|>