<commit_before>// Copyright (c) 2011 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 "remoting/host/disconnect_window.h"

#include "base/compiler_specific.h"
#include "base/logging.h"

namespace {
class DisconnectWindowLinux : public remoting::DisconnectWindow {
 public:
  DisconnectWindowLinux() {}
  virtual void Show(remoting::ChromotingHost* host,
                    const std::string& username) OVERRIDE;
  virtual void Hide() OVERRIDE;

 private:
  DISALLOW_COPY_AND_ASSIGN(DisconnectWindowLinux);
};
}  // namespace

void DisconnectWindowLinux::Show(remoting::ChromotingHost* host,
                                 const std::string& username) {
  NOTIMPLEMENTED();
}

void DisconnectWindowLinux::Hide() {
  NOTIMPLEMENTED();
}

remoting::DisconnectWindow* remoting::DisconnectWindow::Create() {
  return new DisconnectWindowLinux;
}
<commit_msg>Initial implementation of DisconnectWindow on Linux.<commit_after>// Copyright (c) 2011 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 "remoting/host/disconnect_window.h"

#include <gtk/gtk.h>

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "remoting/host/chromoting_host.h"
#include "ui/base/gtk/gtk_signal.h"

namespace {

const char kDisconnectWindowTitle[] = "Remoting";
const char kDisconnectWindowShareText[] = "Sharing with: ";
const char kDisconnectWindowButtonText[] = "Disconnect";

class DisconnectWindowLinux : public remoting::DisconnectWindow {
 public:
  DisconnectWindowLinux();

  virtual void Show(remoting::ChromotingHost* host,
                    const std::string& username) OVERRIDE;
  virtual void Hide() OVERRIDE;

 private:
  CHROMEGTK_CALLBACK_1(DisconnectWindowLinux, gboolean, OnWindowDelete,
                       GdkEvent*);
  CHROMEG_CALLBACK_0(DisconnectWindowLinux, void, OnDisconnectClicked,
                     GtkButton*);

  void CreateWindow();

  remoting::ChromotingHost* host_;
  GtkWidget* disconnect_window_;
  GtkWidget* user_label_;

  DISALLOW_COPY_AND_ASSIGN(DisconnectWindowLinux);
};
}  // namespace

DisconnectWindowLinux::DisconnectWindowLinux()
    : host_(NULL),
      disconnect_window_(NULL) {
}

void DisconnectWindowLinux::CreateWindow() {
  if (disconnect_window_) return;

  disconnect_window_ = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  GtkWindow* window = GTK_WINDOW(disconnect_window_);
  gtk_window_set_title(window, kDisconnectWindowTitle);
  gtk_window_set_resizable(window, FALSE);
  // Try to keep the window always visible.
  gtk_window_stick(window);
  gtk_window_set_keep_above(window, TRUE);

  g_signal_connect(disconnect_window_, "delete-event",
                   G_CALLBACK(OnWindowDeleteThunk), this);

  GtkWidget* main_area = gtk_vbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(disconnect_window_), main_area);

  GtkWidget* username_row = gtk_hbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(main_area), username_row);

  GtkWidget* share_label = gtk_label_new(kDisconnectWindowShareText);
  gtk_container_add(GTK_CONTAINER(username_row), share_label);

  user_label_ = gtk_label_new(NULL);
  gtk_container_add(GTK_CONTAINER(username_row), user_label_);

  GtkWidget* disconnect_box = gtk_hbox_new(FALSE, 0);
  gtk_container_add(GTK_CONTAINER(main_area), disconnect_box);

  GtkWidget* disconnect_button = gtk_button_new_with_label(
      kDisconnectWindowButtonText);
  gtk_box_pack_start(GTK_BOX(disconnect_box), disconnect_button,
                     TRUE, FALSE, 0);

  g_signal_connect(disconnect_button, "clicked",
                   G_CALLBACK(OnDisconnectClickedThunk), this);

  gtk_widget_show_all(main_area);
}

void DisconnectWindowLinux::Show(remoting::ChromotingHost* host,
                                 const std::string& username) {
  host_ = host;
  CreateWindow();
  gtk_label_set_text(GTK_LABEL(user_label_), username.c_str());
  gtk_window_present(GTK_WINDOW(disconnect_window_));
}

void DisconnectWindowLinux::Hide() {
  DCHECK(disconnect_window_);

  gtk_widget_hide(disconnect_window_);
}

gboolean DisconnectWindowLinux::OnWindowDelete(GtkWidget* widget,
                                               GdkEvent* event) {
  // Don't allow the window to be closed.
  return TRUE;
}

void DisconnectWindowLinux::OnDisconnectClicked(GtkButton* sender) {
  DCHECK(host_);
  host_->Shutdown();
}

remoting::DisconnectWindow* remoting::DisconnectWindow::Create() {
  return new DisconnectWindowLinux;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkMultiGroupDataSet.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkMultiGroupDataSet.h"

#include "vtkDataSet.h"
#include "vtkMultiGroupDataInformation.h"
#include "vtkMultiGroupDataIterator.h"
#include "vtkMultiGroupDataSetInternal.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkInformationIntegerKey.h"

#include "vtkObjectFactory.h"

vtkCxxRevisionMacro(vtkMultiGroupDataSet, "1.7");
vtkStandardNewMacro(vtkMultiGroupDataSet);

vtkInformationKeyMacro(vtkMultiGroupDataSet,GROUP,Integer);

//----------------------------------------------------------------------------
vtkMultiGroupDataSet::vtkMultiGroupDataSet()
{
  this->Internal = new vtkMultiGroupDataSetInternal;
  this->MultiGroupDataInformation = vtkMultiGroupDataInformation::New();
}

//----------------------------------------------------------------------------
vtkMultiGroupDataSet::~vtkMultiGroupDataSet()
{
  this->InitializeDataSets();
  delete this->Internal;

  // Cannot be released with SetMultiGroupDataInformation(0) because
  // that method always allocates a new one.
  if (this->MultiGroupDataInformation)
    {
    this->MultiGroupDataInformation->Delete();
    this->MultiGroupDataInformation = 0;
    }
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::SetMultiGroupDataInformation(
  vtkMultiGroupDataInformation* info)
{
  if (info == this->MultiGroupDataInformation)
    {
    return;
    }
  if (this->MultiGroupDataInformation)
    {
    this->MultiGroupDataInformation->Delete();
    this->MultiGroupDataInformation = 0;
    }
  if (info)
    {
    this->MultiGroupDataInformation = info;
    info->Register(this);
    }
  else
    {
    this->MultiGroupDataInformation = vtkMultiGroupDataInformation::New();
    }
  this->Modified();
}

//----------------------------------------------------------------------------
vtkCompositeDataIterator* vtkMultiGroupDataSet::NewIterator()
{
  vtkMultiGroupDataIterator* iter = vtkMultiGroupDataIterator::New();
  iter->SetDataSet(this);
  return iter;
}

//----------------------------------------------------------------------------
vtkMGDSNode* vtkMultiGroupDataSet::NewNode()
{
  return new vtkMGDSNode;
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::InitializeDataSets()
{
  this->Internal->DataSets.clear();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::Initialize()
{
  this->Superclass::Initialize();
  this->InitializeDataSets();
  if (this->MultiGroupDataInformation)
    {
    this->MultiGroupDataInformation->Delete();
    this->MultiGroupDataInformation = 0;
    }
  this->MultiGroupDataInformation = vtkMultiGroupDataInformation::New();
}

//----------------------------------------------------------------------------
unsigned int vtkMultiGroupDataSet::GetNumberOfGroups()
{
  return this->Internal->DataSets.size();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::SetNumberOfGroups(unsigned int numGroups)
{
  if (!this->MultiGroupDataInformation)
    {
    this->MultiGroupDataInformation = vtkMultiGroupDataInformation::New();
    }
  this->MultiGroupDataInformation->SetNumberOfGroups(numGroups);
  if (numGroups == this->GetNumberOfGroups())
    {
    return;
    }
  this->Internal->DataSets.resize(numGroups);
  this->Modified();
}

//----------------------------------------------------------------------------
unsigned int vtkMultiGroupDataSet::GetNumberOfDataSets(unsigned int group)
{
  if (this->Internal->DataSets.size() <= group)
    {
    return 0;
    }

  vtkMultiGroupDataSetInternal::GroupDataSetsType& ldataSets =
    this->Internal->DataSets[group];

  return ldataSets.size();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::SetNumberOfDataSets(unsigned int group,
                                                 unsigned int numDataSets)
{
  if (!this->MultiGroupDataInformation)
    {
    this->MultiGroupDataInformation = vtkMultiGroupDataInformation::New();
    }
  this->MultiGroupDataInformation->SetNumberOfDataSets(group, numDataSets);
  if (numDataSets == this->GetNumberOfDataSets(group))
    {
    return;
    }
  // Make sure that there is a vector allocated for this group
  if (this->Internal->DataSets.size() <= group)
    {
    this->SetNumberOfGroups(group+1);
    }

  vtkMultiGroupDataSetInternal::GroupDataSetsType& ldataSets =
    this->Internal->DataSets[group];

  // We need to delete all extra nodes since we manage memory for them.
  unsigned int curNumDataSets = ldataSets.size();
  ldataSets.resize(numDataSets);

  // Assign NULL to all new pointers. We use this later to figure out
  // whether a node allocated for a particular entry.
  if (curNumDataSets < numDataSets)
    {
    for (unsigned int i=curNumDataSets; i<numDataSets; i++)
      {
      ldataSets[i] = 0;
      }
    }
  this->Modified();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::InitializeNode(unsigned int group,
                                            unsigned int id)
{

  // Make sure that there is a vector allocated for this group
  if (this->Internal->DataSets.size() <= group)
    {
    this->SetNumberOfGroups(group+1);
    }

  vtkMultiGroupDataSetInternal::GroupDataSetsType& ldataSets =
    this->Internal->DataSets[group];

  // Make sure that the size of the vector for this group is big enough.
  if (ldataSets.size() <= id)
    {
    this->SetNumberOfDataSets(group, id+1);
    }

  ldataSets[id] = 0;

  this->Modified();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::SetDataSet(unsigned int group,
                                        unsigned int id,
                                        vtkDataObject* ds)
{
  // Make sure that there is a vector allocated for this group
  if (this->Internal->DataSets.size() <= group)
    {
    this->SetNumberOfGroups(group+1);
    }

  vtkMultiGroupDataSetInternal::GroupDataSetsType& ldataSets =
    this->Internal->DataSets[group];

  // Make sure that the size of the vector for this group is big enough.
  if (ldataSets.size() <= id)
    {
    this->SetNumberOfDataSets(group, id+1);
    }

  ldataSets[id] = ds;
  this->Modified();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::AddDataSet(vtkInformation* index, vtkDataObject* dobj)
{
  if (index->Has(INDEX()) && index->Has(GROUP()))
    {
    this->SetDataSet(index->Get(GROUP()), index->Get(INDEX()), dobj);
    }
}

//----------------------------------------------------------------------------
vtkDataObject* vtkMultiGroupDataSet::GetDataSet(unsigned int group,
                                                  unsigned int id)
{
  if (this->Internal->DataSets.size() <= group)
    {
    return 0;
    }

  vtkMultiGroupDataSetInternal::GroupDataSetsType& ldataSets =
    this->Internal->DataSets[group];
  if (ldataSets.size() <= id)
    {
    return 0;
    }

  if (!ldataSets[id])
    {
    return 0;
    }

  return ldataSets[id];
}

//----------------------------------------------------------------------------
vtkDataObject* vtkMultiGroupDataSet::GetDataSet(vtkInformation* index)
{
  if (index->Has(INDEX()) && index->Has(GROUP()))
    {
    return this->GetDataSet(index->Get(GROUP()), index->Get(INDEX()));
    }
  return 0;
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::ShallowCopy(vtkDataObject *src)
{
  if (src == this)
    {
    return;
    }
  this->InitializeDataSets();
  this->Superclass::ShallowCopy(src);

  vtkMultiGroupDataSet* from = vtkMultiGroupDataSet::SafeDownCast(src);
  if (from)
    {
    this->SetMultiGroupDataInformation(from->MultiGroupDataInformation);
    unsigned int numGroups = from->GetNumberOfGroups();
    this->SetNumberOfGroups(numGroups);
    for (unsigned int i=0; i<numGroups; i++)
      {
      unsigned int numDataSets = from->GetNumberOfDataSets(i);
      this->SetNumberOfDataSets(i, numDataSets);
      for (unsigned int j=0; j<numDataSets; j++)
        {
        this->SetDataSet(i, j, from->GetDataSet(i,j));
        }
      }
    }

  this->Modified();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::DeepCopy(vtkDataObject *src)
{
  if (src == this)
    {
    return;
    }
  this->InitializeDataSets();
  this->Superclass::ShallowCopy(src);
  if (this->MultiGroupDataInformation)
    {
    this->MultiGroupDataInformation->Delete();
    this->MultiGroupDataInformation = 0;
    }
  this->MultiGroupDataInformation = vtkMultiGroupDataInformation::New();

  vtkMultiGroupDataSet* from = vtkMultiGroupDataSet::SafeDownCast(src);
  if (from)
    {
    this->MultiGroupDataInformation->DeepCopy(
      from->MultiGroupDataInformation);
    unsigned int numGroups = from->GetNumberOfGroups();
    this->SetNumberOfGroups(numGroups);
    for (unsigned int i=0; i<numGroups; i++)
      {
      unsigned int numDataSets = from->GetNumberOfDataSets(i);
      this->SetNumberOfDataSets(i, numDataSets);
      for (unsigned int j=0; j<numDataSets; j++)
        {
        vtkDataObject* ds = from->GetDataSet(i,j);
        if (ds)
          {
          vtkDataObject* copy = ds->NewInstance();
          copy->DeepCopy(ds);
          this->SetDataSet(i, j, copy);
          }
        }
      }
    }

  this->Modified();
}

//----------------------------------------------------------------------------
vtkIdType vtkMultiGroupDataSet::GetNumberOfPoints()
{
  vtkIdType numPts = 0;

  vtkCompositeDataIterator* iterator = this->NewIterator();
  iterator->InitTraversal();
  while (!iterator->IsDoneWithTraversal())
    {
    vtkDataObject* dObj = iterator->GetCurrentDataObject();
    if (dObj)
      {
      vtkDataSet* ds = vtkDataSet::SafeDownCast(dObj);
      if (ds)
        {
        numPts += ds->GetNumberOfPoints();
        }
      else
        {
        vtkMultiGroupDataSet* hds =
          vtkMultiGroupDataSet::SafeDownCast(dObj);
        if (hds)
          {
          numPts += hds->GetNumberOfPoints();
          }
        }
      }
    iterator->GoToNextItem();
    }
  iterator->Delete();

  return numPts;
}

//----------------------------------------------------------------------------
vtkMultiGroupDataSet* vtkMultiGroupDataSet::GetData(vtkInformation* info)
{
  return
    info? vtkMultiGroupDataSet::SafeDownCast(info->Get(DATA_OBJECT())) : 0;
}

//----------------------------------------------------------------------------
vtkMultiGroupDataSet* vtkMultiGroupDataSet::GetData(vtkInformationVector* v,
                                                    int i)
{
  return vtkMultiGroupDataSet::GetData(v->GetInformationObject(i));
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "MultiGroupDataInformation: ";
  if (this->MultiGroupDataInformation)
    {
    os << endl;
    this->MultiGroupDataInformation->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)" << endl;
    }
}

<commit_msg>BUG: Attempting once again to fix the memory leak. It is a stubborn one.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkMultiGroupDataSet.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkMultiGroupDataSet.h"

#include "vtkDataSet.h"
#include "vtkMultiGroupDataInformation.h"
#include "vtkMultiGroupDataIterator.h"
#include "vtkMultiGroupDataSetInternal.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkInformationIntegerKey.h"

#include "vtkObjectFactory.h"

vtkCxxRevisionMacro(vtkMultiGroupDataSet, "1.8");
vtkStandardNewMacro(vtkMultiGroupDataSet);

vtkInformationKeyMacro(vtkMultiGroupDataSet,GROUP,Integer);

//----------------------------------------------------------------------------
vtkMultiGroupDataSet::vtkMultiGroupDataSet()
{
  this->Internal = new vtkMultiGroupDataSetInternal;
  this->MultiGroupDataInformation = vtkMultiGroupDataInformation::New();
}

//----------------------------------------------------------------------------
vtkMultiGroupDataSet::~vtkMultiGroupDataSet()
{
  this->InitializeDataSets();
  delete this->Internal;

  // Cannot be released with SetMultiGroupDataInformation(0) because
  // that method always allocates a new one.
  if (this->MultiGroupDataInformation)
    {
    this->MultiGroupDataInformation->Delete();
    this->MultiGroupDataInformation = 0;
    }
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::SetMultiGroupDataInformation(
  vtkMultiGroupDataInformation* info)
{
  if (info == this->MultiGroupDataInformation)
    {
    return;
    }
  if (this->MultiGroupDataInformation)
    {
    this->MultiGroupDataInformation->Delete();
    this->MultiGroupDataInformation = 0;
    }
  if (info)
    {
    this->MultiGroupDataInformation = info;
    info->Register(this);
    }
  else
    {
    this->MultiGroupDataInformation = vtkMultiGroupDataInformation::New();
    }
  this->Modified();
}

//----------------------------------------------------------------------------
vtkCompositeDataIterator* vtkMultiGroupDataSet::NewIterator()
{
  vtkMultiGroupDataIterator* iter = vtkMultiGroupDataIterator::New();
  iter->SetDataSet(this);
  return iter;
}

//----------------------------------------------------------------------------
vtkMGDSNode* vtkMultiGroupDataSet::NewNode()
{
  return new vtkMGDSNode;
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::InitializeDataSets()
{
  this->Internal->DataSets.clear();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::Initialize()
{
  this->Superclass::Initialize();
  this->InitializeDataSets();
  // This will create a new multigroup information.
  this->SetMultiGroupDataInformation(0);
}

//----------------------------------------------------------------------------
unsigned int vtkMultiGroupDataSet::GetNumberOfGroups()
{
  return this->Internal->DataSets.size();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::SetNumberOfGroups(unsigned int numGroups)
{
  this->MultiGroupDataInformation->SetNumberOfGroups(numGroups);
  if (numGroups == this->GetNumberOfGroups())
    {
    return;
    }
  this->Internal->DataSets.resize(numGroups);
  this->Modified();
}

//----------------------------------------------------------------------------
unsigned int vtkMultiGroupDataSet::GetNumberOfDataSets(unsigned int group)
{
  if (this->Internal->DataSets.size() <= group)
    {
    return 0;
    }

  vtkMultiGroupDataSetInternal::GroupDataSetsType& ldataSets =
    this->Internal->DataSets[group];

  return ldataSets.size();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::SetNumberOfDataSets(unsigned int group,
                                                 unsigned int numDataSets)
{
  this->MultiGroupDataInformation->SetNumberOfDataSets(group, numDataSets);
  if (numDataSets == this->GetNumberOfDataSets(group))
    {
    return;
    }
  // Make sure that there is a vector allocated for this group
  if (this->Internal->DataSets.size() <= group)
    {
    this->SetNumberOfGroups(group+1);
    }

  vtkMultiGroupDataSetInternal::GroupDataSetsType& ldataSets =
    this->Internal->DataSets[group];

  // We need to delete all extra nodes since we manage memory for them.
  unsigned int curNumDataSets = ldataSets.size();
  ldataSets.resize(numDataSets);

  // Assign NULL to all new pointers. We use this later to figure out
  // whether a node allocated for a particular entry.
  if (curNumDataSets < numDataSets)
    {
    for (unsigned int i=curNumDataSets; i<numDataSets; i++)
      {
      ldataSets[i] = 0;
      }
    }
  this->Modified();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::InitializeNode(unsigned int group,
                                            unsigned int id)
{

  // Make sure that there is a vector allocated for this group
  if (this->Internal->DataSets.size() <= group)
    {
    this->SetNumberOfGroups(group+1);
    }

  vtkMultiGroupDataSetInternal::GroupDataSetsType& ldataSets =
    this->Internal->DataSets[group];

  // Make sure that the size of the vector for this group is big enough.
  if (ldataSets.size() <= id)
    {
    this->SetNumberOfDataSets(group, id+1);
    }

  ldataSets[id] = 0;

  this->Modified();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::SetDataSet(unsigned int group,
                                        unsigned int id,
                                        vtkDataObject* ds)
{
  // Make sure that there is a vector allocated for this group
  if (this->Internal->DataSets.size() <= group)
    {
    this->SetNumberOfGroups(group+1);
    }

  vtkMultiGroupDataSetInternal::GroupDataSetsType& ldataSets =
    this->Internal->DataSets[group];

  // Make sure that the size of the vector for this group is big enough.
  if (ldataSets.size() <= id)
    {
    this->SetNumberOfDataSets(group, id+1);
    }

  ldataSets[id] = ds;
  this->Modified();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::AddDataSet(vtkInformation* index, vtkDataObject* dobj)
{
  if (index->Has(INDEX()) && index->Has(GROUP()))
    {
    this->SetDataSet(index->Get(GROUP()), index->Get(INDEX()), dobj);
    }
}

//----------------------------------------------------------------------------
vtkDataObject* vtkMultiGroupDataSet::GetDataSet(unsigned int group,
                                                  unsigned int id)
{
  if (this->Internal->DataSets.size() <= group)
    {
    return 0;
    }

  vtkMultiGroupDataSetInternal::GroupDataSetsType& ldataSets =
    this->Internal->DataSets[group];
  if (ldataSets.size() <= id)
    {
    return 0;
    }

  if (!ldataSets[id])
    {
    return 0;
    }

  return ldataSets[id];
}

//----------------------------------------------------------------------------
vtkDataObject* vtkMultiGroupDataSet::GetDataSet(vtkInformation* index)
{
  if (index->Has(INDEX()) && index->Has(GROUP()))
    {
    return this->GetDataSet(index->Get(GROUP()), index->Get(INDEX()));
    }
  return 0;
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::ShallowCopy(vtkDataObject *src)
{
  if (src == this)
    {
    return;
    }
  this->InitializeDataSets();
  this->Superclass::ShallowCopy(src);

  vtkMultiGroupDataSet* from = vtkMultiGroupDataSet::SafeDownCast(src);
  if (from)
    {
    this->SetMultiGroupDataInformation(from->MultiGroupDataInformation);
    unsigned int numGroups = from->GetNumberOfGroups();
    this->SetNumberOfGroups(numGroups);
    for (unsigned int i=0; i<numGroups; i++)
      {
      unsigned int numDataSets = from->GetNumberOfDataSets(i);
      this->SetNumberOfDataSets(i, numDataSets);
      for (unsigned int j=0; j<numDataSets; j++)
        {
        this->SetDataSet(i, j, from->GetDataSet(i,j));
        }
      }
    }

  this->Modified();
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::DeepCopy(vtkDataObject *src)
{
  if (src == this)
    {
    return;
    }
  this->InitializeDataSets();
  this->Superclass::ShallowCopy(src);

  // This will create a new multigroup information.
  this->SetMultiGroupDataInformation(0);

  vtkMultiGroupDataSet* from = vtkMultiGroupDataSet::SafeDownCast(src);
  if (from)
    {
    this->MultiGroupDataInformation->DeepCopy(
      from->MultiGroupDataInformation);
    unsigned int numGroups = from->GetNumberOfGroups();
    this->SetNumberOfGroups(numGroups);
    for (unsigned int i=0; i<numGroups; i++)
      {
      unsigned int numDataSets = from->GetNumberOfDataSets(i);
      this->SetNumberOfDataSets(i, numDataSets);
      for (unsigned int j=0; j<numDataSets; j++)
        {
        vtkDataObject* ds = from->GetDataSet(i,j);
        if (ds)
          {
          vtkDataObject* copy = ds->NewInstance();
          copy->DeepCopy(ds);
          this->SetDataSet(i, j, copy);
          }
        }
      }
    }

  this->Modified();
}

//----------------------------------------------------------------------------
vtkIdType vtkMultiGroupDataSet::GetNumberOfPoints()
{
  vtkIdType numPts = 0;

  vtkCompositeDataIterator* iterator = this->NewIterator();
  iterator->InitTraversal();
  while (!iterator->IsDoneWithTraversal())
    {
    vtkDataObject* dObj = iterator->GetCurrentDataObject();
    if (dObj)
      {
      vtkDataSet* ds = vtkDataSet::SafeDownCast(dObj);
      if (ds)
        {
        numPts += ds->GetNumberOfPoints();
        }
      else
        {
        vtkMultiGroupDataSet* hds =
          vtkMultiGroupDataSet::SafeDownCast(dObj);
        if (hds)
          {
          numPts += hds->GetNumberOfPoints();
          }
        }
      }
    iterator->GoToNextItem();
    }
  iterator->Delete();

  return numPts;
}

//----------------------------------------------------------------------------
vtkMultiGroupDataSet* vtkMultiGroupDataSet::GetData(vtkInformation* info)
{
  return
    info? vtkMultiGroupDataSet::SafeDownCast(info->Get(DATA_OBJECT())) : 0;
}

//----------------------------------------------------------------------------
vtkMultiGroupDataSet* vtkMultiGroupDataSet::GetData(vtkInformationVector* v,
                                                    int i)
{
  return vtkMultiGroupDataSet::GetData(v->GetInformationObject(i));
}

//----------------------------------------------------------------------------
void vtkMultiGroupDataSet::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "MultiGroupDataInformation: ";
  if (this->MultiGroupDataInformation)
    {
    os << endl;
    this->MultiGroupDataInformation->PrintSelf(os, indent.GetNextIndent());
    }
  else
    {
    os << "(none)" << endl;
    }
}

<|endoftext|>


<commit_before>/* -*- Mode: C++; c-basic-offset: 2; tab-width: 2; indent-tabs-mode: nil -*-
 *
 * Quadra, an action puzzle game
 * Copyright (C) 1998-2000  Ludus Design
 *
 * This program 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 program 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <string.h>
#include <stdio.h>
#include "input.h"
#include "res.h"
#include "global.h"
#include "crypt.h"
#include "video.h"
#include "config.h"

const int Config::game_version = 19;
int Config::net_version = 23;

const int Config::major = 1;
const int Config::minor = 1;
const int Config::patchlevel = 5;
bool Config::registered = false;
/* FIXME: we should remove all occurence of Config::xtreme */
bool Config::xtreme = false;
char Config::user_name[64] = {""};

Config::Config() {
	fname[0]=0;
}

Config::~Config() {
}

void Config::default_config() {
	memset(&version, 0, sizeof(version));
	memset(&info, 0, sizeof(info));
	memset(player, 0, sizeof(player));
	memset(player2, 0, sizeof(player2));
	memset(&info2, 0, sizeof(info2));
	info.language = 0;
	info.setup_player = 0;
	info.cdmusic = 1; // 0=no music  1=auto-change  2=loop all
	info.multi_level = 1;
	info.unlock_theme = 0;
	info.port_number = 3456;
	info.mouse_speed = 100;
	info.pane[0] = 2;
	info.pane[1] = 0;
	info.pane[2] = 3;
	info.update_rate = 10;
	memset(info.book, sizeof(info.book), 0);
	info.game_name[0] = 0;
	info.game_type = info.level_up = info.level_start = info.combo_min = info.game_end = 0;
	info.game_public = 1;
	info.game_end_value = 1;
	strcpy(info.game_server_address, "");

	for(int i=0; i<3; i++) {
		sprintf(st,"#%i", i+1);
		strcpy(player[i].name, st);
		player[i].color = i;
		player[i].shadow = 0;
		player[i].smooth = 1;
		player[i].repeat = -1;
		player2[i].h_repeat = 2;
		player2[i].v_repeat = 2;
		player2[i].continuous = 1;
		player[i].key[0] = KEY_LEFTARROW;
		player[i].key[1] = KEY_RIGHTARROW;
		player[i].key[2] = KEY_UPARROW;
		player[i].key[3] = KEY_DOWNARROW;
		player[i].key[4] = KEY_UPARROW;
		player2[i].key[0] = KEY_RSHIFT;
		player2[i].key[1] = KEY_SPACE;
	}
}

void Config::read() {
	if(!fname[0])
		snprintf(fname, sizeof(fname) - 1, "%s/%s", quadradir, "quadra.cfg");

	int i;

	Res_dos res(fname, RES_TRY);
	memset(&version, 0, sizeof(version));
	memset(&info, 0, sizeof(info));
	memset(player, 0, sizeof(player));
	memset(player2, 0, sizeof(player2));
	memset(&info2, 0, sizeof(info2));
	warning = 0;
	if(!res.exist) {
		default_config();
		warning = 1;
	} else {
		if(res.size() != (sizeof(version) + sizeof(info) + sizeof(player)) &&
		   res.size() != (sizeof(version) + sizeof(info) + sizeof(player) + sizeof(player2) + sizeof(info2))) {
			default_config();
			warning = 2;
		} else {
			version = -1;
			res.read(&version, sizeof(version));
			if(version != game_version) {
				default_config();
				warning = 2;
			} else {
				res.read(&info, sizeof(info));
				res.read(player, sizeof(player));
				//Those may not be present, but the default is all-zero anyway
				res.read(player2, sizeof(player2));
				res.read(&info2, sizeof(info2));
			}
		}
	}

	for(i=0; i<3; i++) {
		player[i].name[39] = 0;
		if(player[i].color<0 || player[i].color>=MAXTEAMS)
			player[i].color=i;
		if(player[i].shadow<0 || player[i].shadow>1)
			player[i].shadow=1;
		if(player[i].smooth<0 || player[i].smooth>1)
			player[i].smooth=1;
		if(player[i].repeat<-1 || player[i].repeat>3)
			player2[i].h_repeat=player2[i].v_repeat=2;
		else
			if(player[i].repeat>=0) {
				player2[i].h_repeat=player[i].repeat;
				player2[i].v_repeat=player[i].repeat;
			}
		if(player2[i].h_repeat<0 || player2[i].h_repeat>3) {
			player2[i].h_repeat=2;
		}
		if(player2[i].v_repeat<0 || player2[i].v_repeat>3) {
			player2[i].v_repeat=2;
		}
		player[i].repeat=-1;
		if(player2[i].continuous<0 || player2[i].continuous>1)
			player2[i].continuous=1;
		if(player2[i].handicap<0 || player2[i].handicap>4)
			player2[i].handicap=0;
		player2[i].ngPasswd[63]=0;
		player2[i].ngTeam[39]=0;
		player2[i].ngTeamPasswd[63]=0;
	}
	for(i=0; i<10; i++) {
		info.book[i][255] = 0;
	}
}

void Config::check_register() {
  registered = true;
}

void fix_str(char *st, Dword len) {
	bool in_str=true;
	Dword i;
	for(i=0; i<len; i++)
		if(!in_str)
			st[i]=0;
		else
			if(!st[i])
				in_str=false;
	st[len-1]=0;
}

void Config::write() {
	int i;
	if(!fname[0])
		snprintf(fname, sizeof(fname) - 1, "%s/%s", quadradir, "quadra.cfg");

	if(!video_is_dumb) {
		Res_dos res(fname, RES_CREATE);
		if(res.exist) {
			version = game_version;
			res.write(&version, sizeof(version));
			for(i=0; i<10; i++)
				fix_str(info.book[i], 256);
			fix_str(info.game_name, 32);
			fix_str(info.game_server_address, 256);
			res.write(&info, sizeof(info));
			for(i=0; i<3; i++) {
				fix_str(player[i].name, 40);
				fix_str(player2[i].ngPasswd, 64);
				fix_str(player2[i].ngTeam, 40);
				fix_str(player2[i].ngTeamPasswd, 64);
			}
			res.write(player, sizeof(player));
			res.write(player2, sizeof(player2));
			res.write(&info2, sizeof(info2));
		}
	}
}

Config config;
<commit_msg>Forgot to update the version number for 1.1.6!<commit_after>/* -*- Mode: C++; c-basic-offset: 2; tab-width: 2; indent-tabs-mode: nil -*-
 *
 * Quadra, an action puzzle game
 * Copyright (C) 1998-2000  Ludus Design
 *
 * This program 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 program 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <string.h>
#include <stdio.h>
#include "input.h"
#include "res.h"
#include "global.h"
#include "crypt.h"
#include "video.h"
#include "config.h"

const int Config::game_version = 19;
int Config::net_version = 23;

const int Config::major = 1;
const int Config::minor = 1;
const int Config::patchlevel = 6;
bool Config::registered = false;
/* FIXME: we should remove all occurence of Config::xtreme */
bool Config::xtreme = false;
char Config::user_name[64] = {""};

Config::Config() {
	fname[0]=0;
}

Config::~Config() {
}

void Config::default_config() {
	memset(&version, 0, sizeof(version));
	memset(&info, 0, sizeof(info));
	memset(player, 0, sizeof(player));
	memset(player2, 0, sizeof(player2));
	memset(&info2, 0, sizeof(info2));
	info.language = 0;
	info.setup_player = 0;
	info.cdmusic = 1; // 0=no music  1=auto-change  2=loop all
	info.multi_level = 1;
	info.unlock_theme = 0;
	info.port_number = 3456;
	info.mouse_speed = 100;
	info.pane[0] = 2;
	info.pane[1] = 0;
	info.pane[2] = 3;
	info.update_rate = 10;
	memset(info.book, sizeof(info.book), 0);
	info.game_name[0] = 0;
	info.game_type = info.level_up = info.level_start = info.combo_min = info.game_end = 0;
	info.game_public = 1;
	info.game_end_value = 1;
	strcpy(info.game_server_address, "");

	for(int i=0; i<3; i++) {
		sprintf(st,"#%i", i+1);
		strcpy(player[i].name, st);
		player[i].color = i;
		player[i].shadow = 0;
		player[i].smooth = 1;
		player[i].repeat = -1;
		player2[i].h_repeat = 2;
		player2[i].v_repeat = 2;
		player2[i].continuous = 1;
		player[i].key[0] = KEY_LEFTARROW;
		player[i].key[1] = KEY_RIGHTARROW;
		player[i].key[2] = KEY_UPARROW;
		player[i].key[3] = KEY_DOWNARROW;
		player[i].key[4] = KEY_UPARROW;
		player2[i].key[0] = KEY_RSHIFT;
		player2[i].key[1] = KEY_SPACE;
	}
}

void Config::read() {
	if(!fname[0])
		snprintf(fname, sizeof(fname) - 1, "%s/%s", quadradir, "quadra.cfg");

	int i;

	Res_dos res(fname, RES_TRY);
	memset(&version, 0, sizeof(version));
	memset(&info, 0, sizeof(info));
	memset(player, 0, sizeof(player));
	memset(player2, 0, sizeof(player2));
	memset(&info2, 0, sizeof(info2));
	warning = 0;
	if(!res.exist) {
		default_config();
		warning = 1;
	} else {
		if(res.size() != (sizeof(version) + sizeof(info) + sizeof(player)) &&
		   res.size() != (sizeof(version) + sizeof(info) + sizeof(player) + sizeof(player2) + sizeof(info2))) {
			default_config();
			warning = 2;
		} else {
			version = -1;
			res.read(&version, sizeof(version));
			if(version != game_version) {
				default_config();
				warning = 2;
			} else {
				res.read(&info, sizeof(info));
				res.read(player, sizeof(player));
				//Those may not be present, but the default is all-zero anyway
				res.read(player2, sizeof(player2));
				res.read(&info2, sizeof(info2));
			}
		}
	}

	for(i=0; i<3; i++) {
		player[i].name[39] = 0;
		if(player[i].color<0 || player[i].color>=MAXTEAMS)
			player[i].color=i;
		if(player[i].shadow<0 || player[i].shadow>1)
			player[i].shadow=1;
		if(player[i].smooth<0 || player[i].smooth>1)
			player[i].smooth=1;
		if(player[i].repeat<-1 || player[i].repeat>3)
			player2[i].h_repeat=player2[i].v_repeat=2;
		else
			if(player[i].repeat>=0) {
				player2[i].h_repeat=player[i].repeat;
				player2[i].v_repeat=player[i].repeat;
			}
		if(player2[i].h_repeat<0 || player2[i].h_repeat>3) {
			player2[i].h_repeat=2;
		}
		if(player2[i].v_repeat<0 || player2[i].v_repeat>3) {
			player2[i].v_repeat=2;
		}
		player[i].repeat=-1;
		if(player2[i].continuous<0 || player2[i].continuous>1)
			player2[i].continuous=1;
		if(player2[i].handicap<0 || player2[i].handicap>4)
			player2[i].handicap=0;
		player2[i].ngPasswd[63]=0;
		player2[i].ngTeam[39]=0;
		player2[i].ngTeamPasswd[63]=0;
	}
	for(i=0; i<10; i++) {
		info.book[i][255] = 0;
	}
}

void Config::check_register() {
  registered = true;
}

void fix_str(char *st, Dword len) {
	bool in_str=true;
	Dword i;
	for(i=0; i<len; i++)
		if(!in_str)
			st[i]=0;
		else
			if(!st[i])
				in_str=false;
	st[len-1]=0;
}

void Config::write() {
	int i;
	if(!fname[0])
		snprintf(fname, sizeof(fname) - 1, "%s/%s", quadradir, "quadra.cfg");

	if(!video_is_dumb) {
		Res_dos res(fname, RES_CREATE);
		if(res.exist) {
			version = game_version;
			res.write(&version, sizeof(version));
			for(i=0; i<10; i++)
				fix_str(info.book[i], 256);
			fix_str(info.game_name, 32);
			fix_str(info.game_server_address, 256);
			res.write(&info, sizeof(info));
			for(i=0; i<3; i++) {
				fix_str(player[i].name, 40);
				fix_str(player2[i].ngPasswd, 64);
				fix_str(player2[i].ngTeam, 40);
				fix_str(player2[i].ngTeamPasswd, 64);
			}
			res.write(player, sizeof(player));
			res.write(player2, sizeof(player2));
			res.write(&info2, sizeof(info2));
		}
	}
}

Config config;
<|endoftext|>


<commit_before>/*****************************************************************************
* This example demonstrates how to create and work with multiple threads of program
*
*
*
* Code&Robots site:       http://codrob.ru/
* YouTube Channel:        https://www.youtube.com/c/code_robots
* Social networks:        https://vk.com/codrob
*                         https://www.facebook.com/groups/295824740787675/
*
* This example code is in public domain and licensed under MIT license
*****************************************************************************/

#include <iostream>
#include <windows.h>

#include <thread>		//C++11

using namespace std;

void foo(int n)
{
	for (int i = 0; i < 5; i++)
	{
		cout << "Is Foo   " << n << " = " << this_thread::get_id() << endl;
		Sleep(700);
	}
}

void bar(int n)
{
	for (int i = 0; i < 10; i++)
	{
		cout << "Is Bar   " << n << " = " << this_thread::get_id() << endl;
		Sleep(700);
	}
}

int main()
{
	cout << "Hardware concurrency: " << thread::hardware_concurrency() << endl;

	//Establishment of an independent thread
	thread t1 (foo, 1);
	thread t2 (bar, 2);

	//If the thread is active at the moment
	if (t1.joinable())
		//The main thread will wait for the completion of the flow
		t1.join();

	//The main thread will not wait for the completion of this flow. It allows him to work independently
	t2.detach();

	cout << "Main: " << this_thread::get_id() << endl;

	system("pause");
};<commit_msg>Charset<commit_after>/*****************************************************************************
* This example demonstrates how to create and work with multiple threads of program
*
* Этот пример демонстрирует создание и работу с несколькими потоками в программе
*
* Code&Robots site:       http://codrob.ru/
* YouTube Channel:        https://www.youtube.com/c/code_robots
* Social networks:        https://vk.com/codrob
*                         https://www.facebook.com/groups/295824740787675/
*
* This example code is in public domain and licensed under MIT license
*****************************************************************************/

#include <iostream>
#include <windows.h>

#include <thread>		//C++11

using namespace std;

void foo(int n)
{
	for (int i = 0; i < 5; i++)
	{
		cout << "Is Foo   " << n << " = " << this_thread::get_id() << endl;
		Sleep(700);
	}
}

void bar(int n)
{
	for (int i = 0; i < 10; i++)
	{
		cout << "Is Bar   " << n << " = " << this_thread::get_id() << endl;
		Sleep(700);
	}
}

int main()
{
	cout << "Hardware concurrency: " << thread::hardware_concurrency() << endl;

	//Establishment of an independent thread
	thread t1 (foo, 1);
	thread t2 (bar, 2);

	//If the thread is active at the moment
	if (t1.joinable())
		//The main thread will wait for the completion of the flow
		t1.join();

	//The main thread will not wait for the completion of this flow. It allows him to work independently
	t2.detach();

	cout << "Main: " << this_thread::get_id() << endl;

	system("pause");
};<|endoftext|>


<commit_before>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "Dbg.h"

//--- standard modules used ----------------------------------------------------
#include "System.h"
#include "SysLog.h"
#include "StringStream.h"

//--- c-library modules used ---------------------------------------------------

#ifdef DEBUG

//---- Tracer -------------------------------------------------------------------------
int Tracer::fgLevel = 0;
Anything Tracer::fgWDDebugContext(Storage::Global());
ROAnything Tracer::fgROWDDebugContext;
long Tracer::fgLowerBound = 0;
long Tracer::fgUpperBound = 0;
long Tracer::fgAlwaysOn = 0;
bool Tracer::fgDumpAnythings = false;
bool Tracer::fgTerminated = true;
static bool fgIsInitialised = false;

class TracerHelper
{
public:
	TracerHelper(int nLevel, Allocator *pAlloc)
		: fStrBuf(pAlloc)
		, fStream(fStrBuf) {
		Tab(nLevel);
	}
	~TracerHelper() {
		fStream.flush();
		SysLog::WriteToStderr(fStrBuf);
	}
	void Tab(int n) {
		for (int i = 0; i < n; ++i) {
			fStream << "  ";
		}
	}
	ostream &GetStream() {
		return fStream;
	}

private:
	String fStrBuf;
	OStringStream fStream;
};

Tracer::Tracer(const char *trigger)
	: fTrigger(trigger)
	, fpMsg(NULL)
	, fpAlloc(Storage::Current())
{
	fTriggered = CheckWDDebug(fTrigger, fpAlloc);
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": --- entering ---\n";
		++fgLevel;
	}
}

Tracer::Tracer(const char *trigger, const char *msg)
	: fTrigger(trigger)
	, fpMsg(msg)
	, fpAlloc(Storage::Current())
{
	fTriggered = CheckWDDebug(fTrigger, fpAlloc);
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": " << fpMsg << " --- entering ---\n";
		++fgLevel;
	}
}

Tracer::~Tracer()
{
	if (fTriggered) {
		--fgLevel;
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ":";
		if (fpMsg) {
			hlp.GetStream() << " " << fpMsg;
		}
		hlp.GetStream() << " --- leaving ---\n";
	}
}

void Tracer::WDDebug(const char *msg)
{
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": " << msg << "\n";
	}
}

void Tracer::IntAnyWDDebug(const ROAnything &any, TracerHelper &hlp)
{
	hlp.Tab(fgLevel);
	if (fgDumpAnythings) {
		hlp.GetStream() << "--- Start of Anything Dump ------------\n";
		hlp.Tab(fgLevel);
		any.Export(hlp.GetStream(), fgLevel);
		hlp.GetStream() << "\n";
		hlp.Tab(fgLevel);
		hlp.GetStream() << "--- End of Anything Dump --------------";
	} else {
		hlp.GetStream() << "{ ... anything ommitted ... }";
	}
	hlp.GetStream() << "\n";
}

void Tracer::AnyWDDebug(const ROAnything &any, const char *msg)
{
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": "  << msg << "\n";
		IntAnyWDDebug(any, hlp);
	}
}

void Tracer::SubWDDebug(const char *subtrigger, const char *msg)
{
	String trigger(fTrigger, -1, fpAlloc);
	trigger.Append('.').Append(subtrigger);

	if (fTriggered && Tracer::CheckWDDebug(trigger, fpAlloc)) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
	}
}

void Tracer::SubAnyWDDebug(const char *subtrigger, const ROAnything &any, const char *msg)
{
	String trigger(fTrigger, -1, fpAlloc);
	trigger.Append('.').Append(subtrigger);

	if (fTriggered && Tracer::CheckWDDebug(trigger, fpAlloc)) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
		IntAnyWDDebug(any, hlp);
	}
}

void Tracer::StatWDDebug(const char *trigger, const char *msg, Allocator *pAlloc)
{
	if (CheckWDDebug(trigger, pAlloc)) {
		TracerHelper hlp(fgLevel, pAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
	}
}

void Tracer::AnythingWDDebug(const char *trigger, const ROAnything &any, const char *msg, Allocator *pAlloc)
{
	if (CheckWDDebug(trigger, pAlloc)) {
		TracerHelper hlp(fgLevel, pAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
		IntAnyWDDebug(any, hlp);
	}
}

bool Tracer::CheckWDDebug(const char *trigger, Allocator *pAlloc)
{
	if (!fgIsInitialised) {
		fgIsInitialised = true;
		Tracer::fgTerminated = (System::EnvGet("NO_DEBUG") == "true") ? true : false;
	}

	if ( fgTerminated ) {
		return false;
	}
	static bool trying = false;	// FIXME: hack until recursive mutex are implemented

	if (fgWDDebugContext.GetType() == AnyNullType) {
		if ( trying ) {
			return false;
		}
		trying = true;
		Reset();
		// try to read Dbg.any only once
// 		trying= false;
	}

	if (fgLowerBound > 0) {
		return CheckTrigger(trigger, pAlloc);
	}
	return false;
}

bool Tracer::CheckMainSwitch(long mainSwitch, long levelSwitch, long levelAll)
{
	if ( mainSwitch == 0L ) {
		return false;	// 0 is always off
	}
	// main switch out of range -> off
	if (mainSwitch < levelSwitch) {
		return false;
	}
	if ( ( levelAll > 0 ) && (mainSwitch > levelAll) ) {
		return false;
	}
	return true;
}

bool Tracer::DoCheckLevel(const char *trigger, const ROAnything &level, long levelSwitch, long levelAll, long enableAll, Allocator *pAlloc)
{
	// check the main switch if it exists
	if ( level.IsDefined("MainSwitch") ) {
		if ( enableAll ) {
			if ( level["MainSwitch"].AsLong(0) < 0 ) {
				return false;
			} else {
				return DoCheckTrigger(trigger, level, levelSwitch, levelAll, enableAll, pAlloc);
			}
		}
		if (!CheckMainSwitch(level["MainSwitch"].AsLong(0), levelSwitch, levelAll)) {
			return false;
		}
	}
	if ( !enableAll && level.IsDefined("LowerBound") ) {
		if (!CheckMainSwitch(level["LowerBound"].AsLong(0), levelSwitch, levelAll)) {
			return false;
		}
	}

	// check the enable all switch if it exists
	if ( levelAll > 0 ) {
		if (level.IsDefined("EnableAll")) {
			enableAll = level["EnableAll"].AsLong(0L);
			// enable all switch in range -> all on
			if ( ( enableAll > 0L ) && ( enableAll >= levelSwitch ) && ( enableAll <= levelAll ) ) {
				return DoCheckTrigger(trigger, level, levelSwitch, levelAll, enableAll, pAlloc);
			}
			enableAll = 0;
		}
	} else {
		levelAll = fgUpperBound;
	}
	return DoCheckTrigger(trigger, level, levelSwitch, levelAll, enableAll, pAlloc);
}

bool Tracer::DoCheckTrigger(const char *trigger, const ROAnything &level, long levelSwitch, long levelAll, long enableAll, Allocator *pAlloc)
{
	String s(trigger, -1, pAlloc);
	long pos;
	if ( (pos = s.StrChr('.')) != -1 ) {
		String part(s.SubString(0, pos), -1, pAlloc);
		if ( level.IsDefined(part) ) {
			return DoCheckLevel(s.SubString(pos + 1), level[part], levelSwitch, levelAll, enableAll, pAlloc);
		}
	}

	if ( level.IsDefined(s) ) {
		long switchValue;
		if ( level[s].IsDefined("MainSwitch") ) {
			switchValue = level[s]["MainSwitch"].AsLong(levelSwitch);
		} else {
			switchValue = level[s].AsLong(levelSwitch);
		}
		if ( switchValue < 0 ) {
			return false;
		}
		if ( !enableAll ) {
			return DoCheckSwitch(switchValue, levelSwitch, levelAll);
		}
	}
	return (enableAll > 0);
}

bool Tracer::DoCheckSwitch(long switchValue, long levelSwitch, long levelAll)
{
	// check the switch value whether it enables tracing or not
	if ( switchValue >= levelSwitch && switchValue <= levelAll ) {
		return true;
	}
	return false;
}

bool Tracer::CheckTrigger(const char *trigger, Allocator *pAlloc)
{
	return DoCheckLevel(trigger, fgROWDDebugContext, fgLowerBound, 0L, 0L, pAlloc);
}

void Tracer::Reset()
{
	istream *ifp = System::OpenStream("Dbg", "any");
	if (ifp) {
		fgWDDebugContext.Import(*ifp, "Dbg");
		fgROWDDebugContext = fgWDDebugContext;
		delete ifp;
	}
	if (fgWDDebugContext.GetType() != AnyNullType) {
		fgLowerBound = fgWDDebugContext["LowerBound"].AsLong(0);
		fgUpperBound = fgWDDebugContext["UpperBound"].AsLong(0);
		fgAlwaysOn = fgWDDebugContext["AlwaysOn"].AsLong(0);
		fgDumpAnythings = fgWDDebugContext["DumpAnythings"].AsBool(true);
	}
}

void Tracer::Terminate()
{
	fgTerminated = true;
	fgWDDebugContext = Anything();
	fgROWDDebugContext = fgWDDebugContext;
}

#endif
<commit_msg>optimized tracing for speed  - gain is around 40%<commit_after>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "Dbg.h"

//--- standard modules used ----------------------------------------------------
#include "System.h"
#include "SysLog.h"
#include "StringStream.h"

//--- c-library modules used ---------------------------------------------------

#ifdef DEBUG

//---- Tracer -------------------------------------------------------------------------
int Tracer::fgLevel = 0;
Anything Tracer::fgWDDebugContext(Storage::Global());
ROAnything Tracer::fgROWDDebugContext;
long Tracer::fgLowerBound = 0;
long Tracer::fgUpperBound = 0;
long Tracer::fgAlwaysOn = 0;
bool Tracer::fgDumpAnythings = false;
bool Tracer::fgTerminated = true;
static bool fgIsInitialised = false;

class TracerHelper
{
public:
	TracerHelper(int nLevel, Allocator *pAlloc)
		: fStrBuf(128L, pAlloc)
		, fStream(fStrBuf) {
		Tab(nLevel);
	}
	~TracerHelper() {
		fStream.flush();
		SysLog::WriteToStderr(fStrBuf);
	}
	void Tab(int n) {
		for (int i = 0; i < n; ++i) {
			fStream << "  ";
		}
	}
	ostream &GetStream() {
		return fStream;
	}

private:
	String fStrBuf;
	OStringStream fStream;
};

Tracer::Tracer(const char *trigger)
	: fTrigger(trigger)
	, fpMsg(NULL)
	, fpAlloc(Storage::Current())
{
	fTriggered = CheckWDDebug(fTrigger, fpAlloc);
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": --- entering ---\n";
		++fgLevel;
	}
}

Tracer::Tracer(const char *trigger, const char *msg)
	: fTrigger(trigger)
	, fpMsg(msg)
	, fpAlloc(Storage::Current())
{
	fTriggered = CheckWDDebug(fTrigger, fpAlloc);
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": " << fpMsg << " --- entering ---\n";
		++fgLevel;
	}
}

Tracer::~Tracer()
{
	if (fTriggered) {
		--fgLevel;
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ":";
		if (fpMsg) {
			hlp.GetStream() << " " << fpMsg;
		}
		hlp.GetStream() << " --- leaving ---\n";
	}
}

void Tracer::WDDebug(const char *msg)
{
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": " << msg << "\n";
	}
}

void Tracer::IntAnyWDDebug(const ROAnything &any, TracerHelper &hlp)
{
	hlp.Tab(fgLevel);
	if (fgDumpAnythings) {
		hlp.GetStream() << "--- Start of Anything Dump ------------\n";
		hlp.Tab(fgLevel);
		any.Export(hlp.GetStream(), fgLevel);
		hlp.GetStream() << "\n";
		hlp.Tab(fgLevel);
		hlp.GetStream() << "--- End of Anything Dump --------------";
	} else {
		hlp.GetStream() << "{ ... anything ommitted ... }";
	}
	hlp.GetStream() << "\n";
}

void Tracer::AnyWDDebug(const ROAnything &any, const char *msg)
{
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": "  << msg << "\n";
		IntAnyWDDebug(any, hlp);
	}
}

void Tracer::SubWDDebug(const char *subtrigger, const char *msg)
{
	String trigger(fTrigger, -1, fpAlloc);
	trigger.Append('.').Append(subtrigger);

	if (fTriggered && Tracer::CheckWDDebug(trigger, fpAlloc)) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
	}
}

void Tracer::SubAnyWDDebug(const char *subtrigger, const ROAnything &any, const char *msg)
{
	String trigger(fTrigger, -1, fpAlloc);
	trigger.Append('.').Append(subtrigger);

	if (fTriggered && Tracer::CheckWDDebug(trigger, fpAlloc)) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
		IntAnyWDDebug(any, hlp);
	}
}

void Tracer::StatWDDebug(const char *trigger, const char *msg, Allocator *pAlloc)
{
	if (CheckWDDebug(trigger, pAlloc)) {
		TracerHelper hlp(fgLevel, pAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
	}
}

void Tracer::AnythingWDDebug(const char *trigger, const ROAnything &any, const char *msg, Allocator *pAlloc)
{
	if (CheckWDDebug(trigger, pAlloc)) {
		TracerHelper hlp(fgLevel, pAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
		IntAnyWDDebug(any, hlp);
	}
}

bool Tracer::CheckWDDebug(const char *trigger, Allocator *pAlloc)
{
	if (!fgIsInitialised) {
		fgIsInitialised = true;
		Tracer::fgTerminated = (System::EnvGet("NO_DEBUG") == "true") ? true : false;
	}

	if ( fgTerminated ) {
		return false;
	}
	static bool trying = false;	// FIXME: hack until recursive mutex are implemented

	if (fgWDDebugContext.GetType() == AnyNullType) {
		if ( trying ) {
			return false;
		}
		trying = true;
		Reset();
		// try to read Dbg.any only once
// 		trying= false;
	}

	if (fgLowerBound > 0) {
		return CheckTrigger(trigger, pAlloc);
	}
	return false;
}

bool Tracer::CheckMainSwitch(long mainSwitch, long levelSwitch, long levelAll)
{
	if ( mainSwitch == 0L ) {
		return false;	// 0 is always off
	}
	// main switch out of range -> off
	if (mainSwitch < levelSwitch) {
		return false;
	}
	if ( ( levelAll > 0 ) && (mainSwitch > levelAll) ) {
		return false;
	}
	return true;
}

bool Tracer::DoCheckLevel(const char *trigger, const ROAnything &level, long levelSwitch, long levelAll, long enableAll, Allocator *pAlloc)
{
	// check the main switch if it exists
	if ( level.IsDefined("MainSwitch") ) {
		if ( enableAll ) {
			if ( level["MainSwitch"].AsLong(0) < 0 ) {
				return false;
			} else {
				return DoCheckTrigger(trigger, level, levelSwitch, levelAll, enableAll, pAlloc);
			}
		}
		if (!CheckMainSwitch(level["MainSwitch"].AsLong(0), levelSwitch, levelAll)) {
			return false;
		}
	}
	if ( !enableAll && level.IsDefined("LowerBound") ) {
		if (!CheckMainSwitch(level["LowerBound"].AsLong(0), levelSwitch, levelAll)) {
			return false;
		}
	}

	// check the enable all switch if it exists
	if ( levelAll > 0 ) {
		if (level.IsDefined("EnableAll")) {
			enableAll = level["EnableAll"].AsLong(0L);
			// enable all switch in range -> all on
			if ( ( enableAll > 0L ) && ( enableAll >= levelSwitch ) && ( enableAll <= levelAll ) ) {
				return DoCheckTrigger(trigger, level, levelSwitch, levelAll, enableAll, pAlloc);
			}
			enableAll = 0;
		}
	} else {
		levelAll = fgUpperBound;
	}
	return DoCheckTrigger(trigger, level, levelSwitch, levelAll, enableAll, pAlloc);
}

bool Tracer::DoCheckTrigger(const char *trigger, const ROAnything &level, long levelSwitch, long levelAll, long enableAll, Allocator *pAlloc)
{
	char *cPos( strchr(trigger, '.') );
	if ( cPos != NULL ) {
		long lpos(cPos - trigger);
		char pcPart[512] = { 0 };
		memcpy(pcPart, trigger, std::min( lpos, 511L ) );
		if ( level.IsDefined(pcPart) && ( *++cPos != '\0' ) ) {
			return DoCheckLevel(cPos, level[pcPart], levelSwitch, levelAll, enableAll, pAlloc);
		}
	}

	if ( level.IsDefined(trigger) ) {
		long switchValue;
		if ( level[trigger].IsDefined("MainSwitch") ) {
			switchValue = level[trigger]["MainSwitch"].AsLong(levelSwitch);
		} else {
			switchValue = level[trigger].AsLong(levelSwitch);
		}
		if ( switchValue < 0 ) {
			return false;
		}
		if ( !enableAll ) {
			return DoCheckSwitch(switchValue, levelSwitch, levelAll);
		}
	}
	return (enableAll > 0);
}

bool Tracer::DoCheckSwitch(long switchValue, long levelSwitch, long levelAll)
{
	// check the switch value whether it enables tracing or not
	if ( switchValue >= levelSwitch && switchValue <= levelAll ) {
		return true;
	}
	return false;
}

bool Tracer::CheckTrigger(const char *trigger, Allocator *pAlloc)
{
	return DoCheckLevel(trigger, fgROWDDebugContext, fgLowerBound, 0L, 0L, pAlloc);
}

void Tracer::Reset()
{
	istream *ifp = System::OpenStream("Dbg", "any");
	if (ifp) {
		fgWDDebugContext.Import(*ifp, "Dbg");
		fgROWDDebugContext = fgWDDebugContext;
		delete ifp;
	}
	if (fgWDDebugContext.GetType() != AnyNullType) {
		fgLowerBound = fgWDDebugContext["LowerBound"].AsLong(0);
		fgUpperBound = fgWDDebugContext["UpperBound"].AsLong(0);
		fgAlwaysOn = fgWDDebugContext["AlwaysOn"].AsLong(0);
		fgDumpAnythings = fgWDDebugContext["DumpAnythings"].AsBool(true);
	}
}

void Tracer::Terminate()
{
	fgTerminated = true;
	fgWDDebugContext = Anything();
	fgROWDDebugContext = fgWDDebugContext;
}

#endif
<|endoftext|>


<commit_before>// Fl_Rotated_Text.cxx,v 0.1
//
// Copyright 2005 by Roman Kantor.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License
// version 2 as published by the Free Software Foundation.
//
// This library is distributed  WITHOUT ANY WARRANTY;
// WITHOUT even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

#include "Fl_Rotated_Text.H"
#include <string.h>
#include <FL/x.H>
#include <FL/fl_draw.H>
#include <FL/Fl.H>
#include <FL/Enumerations.H>

Fl_Rotated_Text::~Fl_Rotated_Text(){
  delete[] text_;
}
Fl_Rotated_Text::Fl_Rotated_Text(const char *text , Fl_Font font , int size , uchar align , int rotation ):Fl_Bitmap((const uchar *)0, 0, 0), ar2(0){
  text_ = 0;
  set(text, font, size, align, rotation);
}

void Fl_Rotated_Text::set(const char *text, Fl_Font font, int size, uchar align, int rotation){

  uncache();
  if(alloc_array) delete[] ar2;
  ar2 = 0;
  array = 0;
  alloc_array = 0;

  delete[] text_;
  text_=0;
  font_ = font;
  size_ = size;
  align_ = align;

  if(!text || !(*text)){
    w(0);
    h(0);
    return;
  }

  text_ = new char[strlen(text) + 1];
  strcpy(text_, text);

  if(rotation >9)
    rot_ = (uchar)(((rotation+45)/90) % 4);
  else
    rot_ = (uchar) (rotation & 3);
  int w_ = 0;
  int h_ = 0;
  int old_font = fl_font();
  int old_size = fl_size();
  fl_font(font,size);
  fl_measure(text_,w_,h_,0); // assure that w() and h() are always available
  fl_font(old_font,old_size);
  h_ += fl_height()/2;
  if(rot_ & 1){
    w(h_);
    h(w_);
  }else{
    w(w_);
    h(h_);
  }

};

void Fl_Rotated_Text::draw(int x, int y, int W, int H, int cx, int cy){

  if(!text_) return;
  if(!rot_){ // standard drawing)
    int olf_font = fl_font();
    int old_size = fl_size();
    fl_font(font_,size_);
    fl_push_clip(x, y, W-cx, H-cy);
    fl_draw(text_, x - cx, y - cy, w(), h(), (Fl_Align)align_, (Fl_Image *) 0, 0);
    fl_pop_clip();
    fl_font(olf_font, old_size);
    return;
  }
  if(!array){ // not drawn yet, building rotated bitmap "cache"
    int w_, h_;
    if(rot_ & 1){
      w_ = h();
      h_ = w();
    }else{
      w_ = w();
      h_ = h();
    }
    int bsize = ((w()+7)/8)  * h();
    array = ar2 = new uchar[bsize];
    alloc_array = 1;
    //memset(ar2, 0, bsize);

    int old_font = fl_font();
    int old_size = fl_size();

    Fl_Color old_color = fl_color();
    Fl_Offscreen offscreen = fl_create_offscreen(w_,h_);
    fl_begin_offscreen(offscreen);
    fl_color(0x000000);
    fl_rectf(0,0,w_,h_);
    fl_font(font_, size_);
    fl_color(0x00FF0000); // we use green color to plot to the offscreen

    fl_draw(text_,0, 0, w_, h_, (Fl_Align)align_, (Fl_Image *)0, 0);
    uchar * rgb = fl_read_image(0, 0, 0, w_, h_, 0);
    fl_end_offscreen();
    fl_delete_offscreen(offscreen);
    fl_font(old_font, old_size);
    fl_color(old_color);

    int i,j;

    uchar * start = rgb;
    int i_iter = 0;
    int j_iter = 0;
    switch(rot_){
    case 3:
      start +=  w_ * (h_ - 1)*3 + 1;
      i_iter = - w_ * 3;
      j_iter =  3;
      break;
    case 2:
      start +=  (w_ * h_ - 1)*3 + 1;
      i_iter = -3;
      j_iter = - w_ * 3;
      break;
    case 1:
      start +=  (w_ - 1)*3 + 1;
      i_iter = w_ * 3;
      j_iter = -3;
      break;
    }

    uchar * stj = start;
    uchar c;
    uchar * where;
    uchar * sti;

    for(j = 0; j< h(); j++, stj += j_iter){
      uchar val = 0;
      c = 8;
      where = ar2 + j*((w()+7)/8);
      for(i = 0, sti = stj; i< w(); i++, sti +=i_iter){
        if(*sti >127) val |= c;
        if(c & (uchar)128){ // pushing value to the array
          *where = val;
          where++;
          c =1;
          val = 0;
        }else
          c <<=1;
      }
      if(w() % 8){ //need to push last byte
        * where = val;
        where++;
      }
    }

    delete[] rgb;
  }

  Fl_Bitmap::draw(x, y, W, H, cx, cy); // finaly drawing the bitmap

};

<commit_msg>removed trailing semicolons. sigh<commit_after>// Fl_Rotated_Text.cxx,v 0.1
//
// Copyright 2005 by Roman Kantor.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License
// version 2 as published by the Free Software Foundation.
//
// This library is distributed  WITHOUT ANY WARRANTY;
// WITHOUT even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

#include "Fl_Rotated_Text.H"
#include <string.h>
#include <FL/x.H>
#include <FL/fl_draw.H>
#include <FL/Fl.H>
#include <FL/Enumerations.H>

Fl_Rotated_Text::~Fl_Rotated_Text(){
  delete[] text_;
}
Fl_Rotated_Text::Fl_Rotated_Text(const char *text , Fl_Font font , int size , uchar align , int rotation ):Fl_Bitmap((const uchar *)0, 0, 0), ar2(0){
  text_ = 0;
  set(text, font, size, align, rotation);
}

void Fl_Rotated_Text::set(const char *text, Fl_Font font, int size, uchar align, int rotation){

  uncache();
  if(alloc_array) delete[] ar2;
  ar2 = 0;
  array = 0;
  alloc_array = 0;

  delete[] text_;
  text_=0;
  font_ = font;
  size_ = size;
  align_ = align;

  if(!text || !(*text)){
    w(0);
    h(0);
    return;
  }

  text_ = new char[strlen(text) + 1];
  strcpy(text_, text);

  if(rotation >9)
    rot_ = (uchar)(((rotation+45)/90) % 4);
  else
    rot_ = (uchar) (rotation & 3);
  int w_ = 0;
  int h_ = 0;
  int old_font = fl_font();
  int old_size = fl_size();
  fl_font(font,size);
  fl_measure(text_,w_,h_,0); // assure that w() and h() are always available
  fl_font(old_font,old_size);
  h_ += fl_height()/2;
  if(rot_ & 1){
    w(h_);
    h(w_);
  }else{
    w(w_);
    h(h_);
  }

}

void Fl_Rotated_Text::draw(int x, int y, int W, int H, int cx, int cy){

  if(!text_) return;
  if(!rot_){ // standard drawing)
    int olf_font = fl_font();
    int old_size = fl_size();
    fl_font(font_,size_);
    fl_push_clip(x, y, W-cx, H-cy);
    fl_draw(text_, x - cx, y - cy, w(), h(), (Fl_Align)align_, (Fl_Image *) 0, 0);
    fl_pop_clip();
    fl_font(olf_font, old_size);
    return;
  }
  if(!array){ // not drawn yet, building rotated bitmap "cache"
    int w_, h_;
    if(rot_ & 1){
      w_ = h();
      h_ = w();
    }else{
      w_ = w();
      h_ = h();
    }
    int bsize = ((w()+7)/8)  * h();
    array = ar2 = new uchar[bsize];
    alloc_array = 1;
    //memset(ar2, 0, bsize);

    int old_font = fl_font();
    int old_size = fl_size();

    Fl_Color old_color = fl_color();
    Fl_Offscreen offscreen = fl_create_offscreen(w_,h_);
    fl_begin_offscreen(offscreen);
    fl_color(0x000000);
    fl_rectf(0,0,w_,h_);
    fl_font(font_, size_);
    fl_color(0x00FF0000); // we use green color to plot to the offscreen

    fl_draw(text_,0, 0, w_, h_, (Fl_Align)align_, (Fl_Image *)0, 0);
    uchar * rgb = fl_read_image(0, 0, 0, w_, h_, 0);
    fl_end_offscreen();
    fl_delete_offscreen(offscreen);
    fl_font(old_font, old_size);
    fl_color(old_color);

    int i,j;

    uchar * start = rgb;
    int i_iter = 0;
    int j_iter = 0;
    switch(rot_){
    case 3:
      start +=  w_ * (h_ - 1)*3 + 1;
      i_iter = - w_ * 3;
      j_iter =  3;
      break;
    case 2:
      start +=  (w_ * h_ - 1)*3 + 1;
      i_iter = -3;
      j_iter = - w_ * 3;
      break;
    case 1:
      start +=  (w_ - 1)*3 + 1;
      i_iter = w_ * 3;
      j_iter = -3;
      break;
    }

    uchar * stj = start;
    uchar c;
    uchar * where;
    uchar * sti;

    for(j = 0; j< h(); j++, stj += j_iter){
      uchar val = 0;
      c = 8;
      where = ar2 + j*((w()+7)/8);
      for(i = 0, sti = stj; i< w(); i++, sti +=i_iter){
        if(*sti >127) val |= c;
        if(c & (uchar)128){ // pushing value to the array
          *where = val;
          where++;
          c =1;
          val = 0;
        }else
          c <<=1;
      }
      if(w() % 8){ //need to push last byte
        * where = val;
        where++;
      }
    }

    delete[] rgb;
  }

  Fl_Bitmap::draw(x, y, W, H, cx, cy); // finaly drawing the bitmap

}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "Dbg.h"

//--- standard modules used ----------------------------------------------------
#include "System.h"
#include "SysLog.h"
#include "StringStream.h"

//--- c-library modules used ---------------------------------------------------
#include <cstring>

#ifdef COAST_TRACE

//---- Tracer -------------------------------------------------------------------------
int Tracer::fgLevel = 0;
Anything Tracer::fgWDDebugContext(Storage::Global());
ROAnything Tracer::fgROWDDebugContext;
long Tracer::fgLowerBound = 0;
long Tracer::fgUpperBound = 0;
bool Tracer::fgDumpAnythings = false;
bool Tracer::fgTerminated = true;
static bool fgIsInitialised = false;

//! Utility class to keep track of trace indent
class TracerHelper
{
public:
	TracerHelper(int nLevel, Allocator *pAlloc)
		: fStrBuf(128L, pAlloc)
		, fStream(fStrBuf) {
		Tab(nLevel);
	}
	~TracerHelper() {
		fStream.flush();
		SysLog::WriteToStderr(fStrBuf);
	}
	void Tab(int n) {
		for (int i = 0; i < n; ++i) {
			fStream << "  ";
		}
	}
	ostream &GetStream() {
		return fStream;
	}

private:
	String fStrBuf;
	OStringStream fStream;
};

Tracer::Tracer(const char *trigger)
	: fTrigger(trigger)
	, fTriggered(false)
	, fpMsg(NULL)
	, fpAlloc(Storage::Current())
{
	fTriggered = CheckWDDebug(fTrigger, fpAlloc);
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": --- entering ---\n";
		++fgLevel;
	}
}

Tracer::Tracer(const char *trigger, const char *msg)
	: fTrigger(trigger)
	, fTriggered(false)
	, fpMsg(msg)
	, fpAlloc(Storage::Current())
{
	fTriggered = CheckWDDebug(fTrigger, fpAlloc);
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": " << fpMsg << " --- entering ---\n";
		++fgLevel;
	}
}

Tracer::~Tracer()
{
	if (fTriggered) {
		--fgLevel;
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ":";
		if (fpMsg) {
			hlp.GetStream() << " " << fpMsg;
		}
		hlp.GetStream() << " --- leaving ---\n";
	}
}

void Tracer::WDDebug(const char *msg)
{
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": " << msg << "\n";
	}
}

void Tracer::IntAnyWDDebug(const ROAnything &any, TracerHelper &hlp)
{
	hlp.Tab(fgLevel);
	if (fgDumpAnythings) {
		hlp.GetStream() << "--- Start of Anything Dump ------------\n";
		hlp.Tab(fgLevel);
		any.Export(hlp.GetStream(), fgLevel);
		hlp.GetStream() << "\n";
		hlp.Tab(fgLevel);
		hlp.GetStream() << "--- End of Anything Dump --------------";
	} else {
		hlp.GetStream() << "{ ... anything ommitted ... }";
	}
	hlp.GetStream() << "\n";
}

void Tracer::AnyWDDebug(const ROAnything &any, const char *msg)
{
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": "  << msg << "\n";
		IntAnyWDDebug(any, hlp);
	}
}

void Tracer::SubWDDebug(const char *subtrigger, const char *msg)
{
	String trigger(fTrigger, -1, fpAlloc);
	trigger.Append('.').Append(subtrigger);

	if (fTriggered && Tracer::CheckWDDebug(trigger, fpAlloc)) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
	}
}

void Tracer::SubAnyWDDebug(const char *subtrigger, const ROAnything &any, const char *msg)
{
	String trigger(fTrigger, -1, fpAlloc);
	trigger.Append('.').Append(subtrigger);

	if (fTriggered && Tracer::CheckWDDebug(trigger, fpAlloc)) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
		IntAnyWDDebug(any, hlp);
	}
}

void Tracer::StatWDDebug(const char *trigger, const char *msg, Allocator *pAlloc)
{
	if (CheckWDDebug(trigger, pAlloc)) {
		TracerHelper hlp(fgLevel, pAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
	}
}

void Tracer::AnythingWDDebug(const char *trigger, const ROAnything &any, const char *msg, Allocator *pAlloc)
{
	if (CheckWDDebug(trigger, pAlloc)) {
		TracerHelper hlp(fgLevel, pAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
		IntAnyWDDebug(any, hlp);
	}
}

bool Tracer::CheckWDDebug(const char *trigger, Allocator *pAlloc)
{
	if (!fgIsInitialised) {
		fgIsInitialised = true;
		Tracer::fgTerminated = (System::EnvGet("NO_DEBUG") == "true") ? true : false;
	}

	if ( fgTerminated ) {
		return false;
	}
	static bool trying( false );	// FIXME: hack until recursive mutex are implemented

	if (fgWDDebugContext.GetType() == AnyNullType) {
		if ( trying ) {
			return false;
		}
		trying = true;
		Reset();
		// try to read Dbg.any only once
// 		trying= false;
	}

	if (fgLowerBound > 0) {
		return CheckTrigger(trigger, pAlloc);
	}
	return false;
}

bool Tracer::CheckMainSwitch(long mainSwitch, long levelSwitch, long levelAll)
{
	if ( mainSwitch == 0L ) {
		return false;	// 0 is always off
	}
	// main switch out of range -> off
	if (mainSwitch < levelSwitch) {
		return false;
	}
	if ( ( levelAll > 0 ) && (mainSwitch > levelAll) ) {
		return false;
	}
	return true;
}

bool Tracer::DoCheckLevel(const char *trigger, const ROAnything &level, long levelSwitch, long levelAll, long enableAll, Allocator *pAlloc)
{
	// check the main switch if it exists
	if ( level.IsDefined("MainSwitch") ) {
		if ( enableAll ) {
			if ( level["MainSwitch"].AsLong(0) < 0 ) {
				return false;
			} else {
				return DoCheckTrigger(trigger, level, levelSwitch, levelAll, enableAll, pAlloc);
			}
		}
		if (!CheckMainSwitch(level["MainSwitch"].AsLong(0), levelSwitch, levelAll)) {
			return false;
		}
	}
	if ( !enableAll && level.IsDefined("LowerBound") ) {
		if (!CheckMainSwitch(level["LowerBound"].AsLong(0), levelSwitch, levelAll)) {
			return false;
		}
	}

	// check the enable all switch if it exists
	if ( levelAll > 0 ) {
		if (level.IsDefined("EnableAll")) {
			enableAll = level["EnableAll"].AsLong(0L);
			// enable all switch in range -> all on
			if ( ( enableAll > 0L ) && ( enableAll >= levelSwitch ) && ( enableAll <= levelAll ) ) {
				return DoCheckTrigger(trigger, level, levelSwitch, levelAll, enableAll, pAlloc);
			}
			enableAll = 0;
		}
	} else {
		levelAll = fgUpperBound;
	}
	return DoCheckTrigger(trigger, level, levelSwitch, levelAll, enableAll, pAlloc);
}

bool Tracer::DoCheckTrigger(const char *trigger, const ROAnything &level, long levelSwitch, long levelAll, long enableAll, Allocator *pAlloc)
{
	const char *cPos( strchr(trigger, '.') );
	if ( cPos != NULL ) {
		long lpos(cPos - trigger);
		char pcPart[512] = { 0 };
		memcpy(pcPart, trigger, std::min( lpos, 511L ) );
		if ( level.IsDefined(pcPart) && ( *++cPos != '\0' ) ) {
			return DoCheckLevel(cPos, level[pcPart], levelSwitch, levelAll, enableAll, pAlloc);
		}
	}

	if ( level.IsDefined(trigger) ) {
		long switchValue;
		if ( level[trigger].IsDefined("MainSwitch") ) {
			switchValue = level[trigger]["MainSwitch"].AsLong(levelSwitch);
		} else {
			switchValue = level[trigger].AsLong(levelSwitch);
		}
		if ( switchValue < 0 ) {
			return false;
		}
		if ( !enableAll ) {
			return DoCheckSwitch(switchValue, levelSwitch, levelAll);
		}
	}
	return (enableAll > 0);
}

bool Tracer::DoCheckSwitch(long switchValue, long levelSwitch, long levelAll)
{
	// check the switch value whether it enables tracing or not
	if ( switchValue >= levelSwitch && switchValue <= levelAll ) {
		return true;
	}
	return false;
}

bool Tracer::CheckTrigger(const char *trigger, Allocator *pAlloc)
{
	return DoCheckLevel(trigger, fgROWDDebugContext, fgLowerBound, 0L, 0L, pAlloc);
}

void Tracer::Reset()
{
	istream *ifp = System::OpenStream("Dbg", "any");
	if (ifp) {
		fgWDDebugContext.Import(*ifp, "Dbg");
		fgROWDDebugContext = fgWDDebugContext;
		delete ifp;
	}
	if (fgWDDebugContext.GetType() != AnyNullType) {
		fgLowerBound = fgWDDebugContext["LowerBound"].AsLong(0);
		fgUpperBound = fgWDDebugContext["UpperBound"].AsLong(0);
		fgDumpAnythings = fgWDDebugContext["DumpAnythings"].AsBool(true);
	}
}

void Tracer::Terminate()
{
	fgTerminated = true;
	fgWDDebugContext = Anything();
	fgROWDDebugContext = fgWDDebugContext;
}

#endif
<commit_msg>eliminated error in tracing (needed line was commented out)<commit_after>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "Dbg.h"

//--- standard modules used ----------------------------------------------------
#include "System.h"
#include "SysLog.h"
#include "StringStream.h"

//--- c-library modules used ---------------------------------------------------
#include <cstring>

#ifdef COAST_TRACE

//---- Tracer -------------------------------------------------------------------------
int Tracer::fgLevel = 0;
Anything Tracer::fgWDDebugContext(Storage::Global());
ROAnything Tracer::fgROWDDebugContext;
long Tracer::fgLowerBound = 0;
long Tracer::fgUpperBound = 0;
bool Tracer::fgDumpAnythings = false;
bool Tracer::fgTerminated = true;
static bool fgIsInitialised = false;

//! Utility class to keep track of trace indent
class TracerHelper
{
public:
	TracerHelper(int nLevel, Allocator *pAlloc)
		: fStrBuf(128L, pAlloc)
		, fStream(fStrBuf) {
		Tab(nLevel);
	}
	~TracerHelper() {
		fStream.flush();
		SysLog::WriteToStderr(fStrBuf);
	}
	void Tab(int n) {
		for (int i = 0; i < n; ++i) {
			fStream << "  ";
		}
	}
	ostream &GetStream() {
		return fStream;
	}

private:
	String fStrBuf;
	OStringStream fStream;
};

Tracer::Tracer(const char *trigger)
	: fTrigger(trigger)
	, fTriggered(false)
	, fpMsg(NULL)
	, fpAlloc(Storage::Current())
{
	fTriggered = CheckWDDebug(fTrigger, fpAlloc);
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": --- entering ---\n";
		++fgLevel;
	}
}

Tracer::Tracer(const char *trigger, const char *msg)
	: fTrigger(trigger)
	, fTriggered(false)
	, fpMsg(msg)
	, fpAlloc(Storage::Current())
{
	fTriggered = CheckWDDebug(fTrigger, fpAlloc);
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": " << fpMsg << " --- entering ---\n";
		++fgLevel;
	}
}

Tracer::~Tracer()
{
	if (fTriggered) {
		--fgLevel;
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ":";
		if (fpMsg) {
			hlp.GetStream() << " " << fpMsg;
		}
		hlp.GetStream() << " --- leaving ---\n";
	}
}

void Tracer::WDDebug(const char *msg)
{
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": " << msg << "\n";
	}
}

void Tracer::IntAnyWDDebug(const ROAnything &any, TracerHelper &hlp)
{
	hlp.Tab(fgLevel);
	if (fgDumpAnythings) {
		hlp.GetStream() << "--- Start of Anything Dump ------------\n";
		hlp.Tab(fgLevel);
		any.Export(hlp.GetStream(), fgLevel);
		hlp.GetStream() << "\n";
		hlp.Tab(fgLevel);
		hlp.GetStream() << "--- End of Anything Dump --------------";
	} else {
		hlp.GetStream() << "{ ... anything ommitted ... }";
	}
	hlp.GetStream() << "\n";
}

void Tracer::AnyWDDebug(const ROAnything &any, const char *msg)
{
	if (fTriggered) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << fTrigger << ": "  << msg << "\n";
		IntAnyWDDebug(any, hlp);
	}
}

void Tracer::SubWDDebug(const char *subtrigger, const char *msg)
{
	String trigger(fTrigger, -1, fpAlloc);
	trigger.Append('.').Append(subtrigger);

	if (fTriggered && Tracer::CheckWDDebug(trigger, fpAlloc)) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
	}
}

void Tracer::SubAnyWDDebug(const char *subtrigger, const ROAnything &any, const char *msg)
{
	String trigger(fTrigger, -1, fpAlloc);
	trigger.Append('.').Append(subtrigger);

	if (fTriggered && Tracer::CheckWDDebug(trigger, fpAlloc)) {
		TracerHelper hlp(fgLevel, fpAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
		IntAnyWDDebug(any, hlp);
	}
}

void Tracer::StatWDDebug(const char *trigger, const char *msg, Allocator *pAlloc)
{
	if (CheckWDDebug(trigger, pAlloc)) {
		TracerHelper hlp(fgLevel, pAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
	}
}

void Tracer::AnythingWDDebug(const char *trigger, const ROAnything &any, const char *msg, Allocator *pAlloc)
{
	if (CheckWDDebug(trigger, pAlloc)) {
		TracerHelper hlp(fgLevel, pAlloc);
		hlp.GetStream() << trigger << ": " << msg << "\n";
		IntAnyWDDebug(any, hlp);
	}
}

bool Tracer::CheckWDDebug(const char *trigger, Allocator *pAlloc)
{
	if (!fgIsInitialised) {
		fgIsInitialised = true;
		Tracer::fgTerminated = (System::EnvGet("NO_DEBUG") == "true") ? true : false;
	}

	if ( fgTerminated ) {
		return false;
	}
	static bool trying( false );	// FIXME: hack until recursive mutex are implemented

	if (fgWDDebugContext.GetType() == AnyNullType) {
		if ( trying ) {
			return false;
		}
		trying = true;
		Reset();
		// try to read Dbg.any only once <<- doesn't work as expected
		trying = false;
	}

	if (fgLowerBound > 0) {
		return CheckTrigger(trigger, pAlloc);
	}
	return false;
}

bool Tracer::CheckMainSwitch(long mainSwitch, long levelSwitch, long levelAll)
{
	if ( mainSwitch == 0L ) {
		return false;	// 0 is always off
	}
	// main switch out of range -> off
	if (mainSwitch < levelSwitch) {
		return false;
	}
	if ( ( levelAll > 0 ) && (mainSwitch > levelAll) ) {
		return false;
	}
	return true;
}

bool Tracer::DoCheckLevel(const char *trigger, const ROAnything &level, long levelSwitch, long levelAll, long enableAll, Allocator *pAlloc)
{
	// check the main switch if it exists
	if ( level.IsDefined("MainSwitch") ) {
		if ( enableAll ) {
			if ( level["MainSwitch"].AsLong(0) < 0 ) {
				return false;
			} else {
				return DoCheckTrigger(trigger, level, levelSwitch, levelAll, enableAll, pAlloc);
			}
		}
		if (!CheckMainSwitch(level["MainSwitch"].AsLong(0), levelSwitch, levelAll)) {
			return false;
		}
	}
	if ( !enableAll && level.IsDefined("LowerBound") ) {
		if (!CheckMainSwitch(level["LowerBound"].AsLong(0), levelSwitch, levelAll)) {
			return false;
		}
	}

	// check the enable all switch if it exists
	if ( levelAll > 0 ) {
		if (level.IsDefined("EnableAll")) {
			enableAll = level["EnableAll"].AsLong(0L);
			// enable all switch in range -> all on
			if ( ( enableAll > 0L ) && ( enableAll >= levelSwitch ) && ( enableAll <= levelAll ) ) {
				return DoCheckTrigger(trigger, level, levelSwitch, levelAll, enableAll, pAlloc);
			}
			enableAll = 0;
		}
	} else {
		levelAll = fgUpperBound;
	}
	return DoCheckTrigger(trigger, level, levelSwitch, levelAll, enableAll, pAlloc);
}

bool Tracer::DoCheckTrigger(const char *trigger, const ROAnything &level, long levelSwitch, long levelAll, long enableAll, Allocator *pAlloc)
{
	const char *cPos( strchr(trigger, '.') );
	if ( cPos != NULL ) {
		long lpos(cPos - trigger);
		char pcPart[512] = { 0 };
		memcpy(pcPart, trigger, std::min( lpos, 511L ) );
		if ( level.IsDefined(pcPart) && ( *++cPos != '\0' ) ) {
			return DoCheckLevel(cPos, level[pcPart], levelSwitch, levelAll, enableAll, pAlloc);
		}
	}

	if ( level.IsDefined(trigger) ) {
		long switchValue;
		if ( level[trigger].IsDefined("MainSwitch") ) {
			switchValue = level[trigger]["MainSwitch"].AsLong(levelSwitch);
		} else {
			switchValue = level[trigger].AsLong(levelSwitch);
		}
		if ( switchValue < 0 ) {
			return false;
		}
		if ( !enableAll ) {
			return DoCheckSwitch(switchValue, levelSwitch, levelAll);
		}
	}
	return (enableAll > 0);
}

bool Tracer::DoCheckSwitch(long switchValue, long levelSwitch, long levelAll)
{
	// check the switch value whether it enables tracing or not
	if ( switchValue >= levelSwitch && switchValue <= levelAll ) {
		return true;
	}
	return false;
}

bool Tracer::CheckTrigger(const char *trigger, Allocator *pAlloc)
{
	return DoCheckLevel(trigger, fgROWDDebugContext, fgLowerBound, 0L, 0L, pAlloc);
}

void Tracer::Reset()
{
	istream *ifp = System::OpenStream("Dbg", "any");
	if (ifp) {
		fgWDDebugContext.Import(*ifp, "Dbg");
		fgROWDDebugContext = fgWDDebugContext;
		delete ifp;
	}
	if (fgWDDebugContext.GetType() != AnyNullType) {
		fgLowerBound = fgWDDebugContext["LowerBound"].AsLong(0);
		fgUpperBound = fgWDDebugContext["UpperBound"].AsLong(0);
		fgDumpAnythings = fgWDDebugContext["DumpAnythings"].AsBool(true);
	}
}

void Tracer::Terminate()
{
	fgTerminated = true;
	fgWDDebugContext = Anything();
	fgROWDDebugContext = fgWDDebugContext;
}

#endif
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkPath.h"

// Reproduces bug found here: http://jsfiddle.net/R8Cu5/1/
//
#include "SkGradientShader.h"
static void test_grad(SkCanvas* canvas) {
    SkPoint pts[] = {
        { 478.544067f, -84.2041016f },
        { 602.455933f, 625.204102f },
    };
    SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, SK_ColorRED, SK_ColorRED };
    SkScalar pos[] = { 0, 0.3f, 0.3f, 1.0f };
    SkShader* s = SkGradientShader::CreateLinear(pts, colors, pos, 4, SkShader::kClamp_TileMode);
    SkPaint p;
    p.setShader(s)->unref();
    canvas->drawPaint(p);
}

static SkCanvas* MakeCanvas(const SkIRect& bounds) {
    SkBitmap bm;
    bm.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(), bounds.height());
    bm.allocPixels();
    bm.eraseColor(SK_ColorTRANSPARENT);

    SkCanvas* canvas = new SkCanvas(bm);
    canvas->translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
    return canvas;
}

#ifdef SK_DEBUG
static void GetBitmap(const SkCanvas* canvas, SkBitmap* bm) {
    *bm = canvas->getDevice()->accessBitmap(false);
}
#endif

static void compare_canvas(const SkCanvas* a, const SkCanvas* b) {
#ifdef SK_DEBUG
    SkBitmap bma, bmb;
    GetBitmap(a, &bma);
    GetBitmap(b, &bmb);

    SkASSERT(bma.width() == bmb.width());
    SkASSERT(bma.height() == bmb.height());

    bma.lockPixels();
    bmb.lockPixels();
    for (int y = 0; y < bma.height(); ++y) {
        const SkPMColor* rowa = bma.getAddr32(0, y);
        const SkPMColor* rowb = bmb.getAddr32(0, y);
        SkASSERT(!memcmp(rowa, rowb, bma.width() << 2));

        for (int x = 1; x < bma.width() - 1; ++x) {
            SkASSERT(0xFF000000 == rowa[x]);
            SkASSERT(0xFF000000 == rowb[x]);
        }
    }
#endif
}

static void drawRectAsPath(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
    SkPath path;
    path.addRect(r);
    canvas->drawPath(path, p);
}

static void test_maskFromPath(const SkPath& path) {
    SkIRect bounds;
    path.getBounds().roundOut(&bounds);

    SkPaint paint;
    paint.setAntiAlias(true);

    SkAutoTUnref<SkCanvas> path_canvas(MakeCanvas(bounds));
    path_canvas->drawPath(path, paint);

    SkAutoTUnref<SkCanvas> rect_canvas(MakeCanvas(bounds));
    drawRectAsPath(rect_canvas, path.getBounds(), paint);

    compare_canvas(path_canvas, rect_canvas);
}

static void test_mask() {
    for (int i = 1; i <= 20; ++i) {
        const SkScalar dx = SK_Scalar1 / i;
        const SkRect constr = SkRect::MakeWH(dx, SkIntToScalar(2));
        for (int n = 2; n < 20; ++n) {
            SkPath path;
            path.setFillType(SkPath::kEvenOdd_FillType);
            SkRect r = constr;
            while (r.fRight < SkIntToScalar(4)) {
                path.addRect(r);
                r.offset(dx, 0);
            }
            test_maskFromPath(path);
        }
    }
}

namespace skiagm {

/** Draw a 2px border around the target, then red behind the target;
    set the clip to match the target, then draw >> the target in blue.
*/

static void draw (SkCanvas* canvas, SkRect& target, int x, int y) {
    SkPaint borderPaint;
    borderPaint.setColor(SkColorSetRGB(0x0, 0xDD, 0x0));
    borderPaint.setAntiAlias(true);
    SkPaint backgroundPaint;
    backgroundPaint.setColor(SkColorSetRGB(0xDD, 0x0, 0x0));
    backgroundPaint.setAntiAlias(true);
    SkPaint foregroundPaint;
    foregroundPaint.setColor(SkColorSetRGB(0x0, 0x0, 0xDD));
    foregroundPaint.setAntiAlias(true);

    canvas->save();
    canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
    target.inset(SkIntToScalar(-2), SkIntToScalar(-2));
    canvas->drawRect(target, borderPaint);
    target.inset(SkIntToScalar(2), SkIntToScalar(2));
    canvas->drawRect(target, backgroundPaint);
    canvas->clipRect(target, SkRegion::kIntersect_Op, true);
    target.inset(SkIntToScalar(-4), SkIntToScalar(-4));
    canvas->drawRect(target, foregroundPaint);
    canvas->restore();
}

static void draw_square (SkCanvas* canvas, int x, int y) {
    SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 10 * SK_Scalar1));
    draw(canvas, target, x, y);
}

static void draw_column (SkCanvas* canvas, int x, int y) {
    SkRect target (SkRect::MakeWH(1 * SK_Scalar1, 10 * SK_Scalar1));
    draw(canvas, target, x, y);
}

static void draw_bar (SkCanvas* canvas, int x, int y) {
    SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 1 * SK_Scalar1));
    draw(canvas, target, x, y);
}

static void draw_rect_tests (SkCanvas* canvas) {
    draw_square(canvas, 10, 10);
    draw_column(canvas, 30, 10);
    draw_bar(canvas, 10, 30);
}

/**
   Test a set of clipping problems discovered while writing blitAntiRect,
   and test all the code paths through the clipping blitters.
   Each region should show as a blue center surrounded by a 2px green
   border, with no red.
*/

class AAClipGM : public GM {
public:
    AAClipGM() {

    }

protected:
    virtual SkString onShortName() {
        return SkString("aaclip");
    }

    virtual SkISize onISize() {
        return make_isize(640, 480);
    }

    virtual void onDraw(SkCanvas* canvas) {
        if (false) {
            test_grad(canvas); return;
        }
        if (false) { // avoid bit rot, suppress warning
            test_mask();
        }

        // Initial pixel-boundary-aligned draw
        draw_rect_tests(canvas);

        // Repeat 4x with .2, .4, .6, .8 px offsets
        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);

        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);

        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);

        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);
    }

    virtual uint32_t onGetFlags() const { return kSkipPipe_Flag; }

private:
    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static GM* MyFactory(void*) { return new AAClipGM; }
static GMRegistry reg(MyFactory);

}
<commit_msg>add (disabled) test for big dashing<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkPath.h"

#include "SkDashPathEffect.h"
static void test_giant_dash(SkCanvas* canvas) {
    SkPaint paint;
    const SkScalar intervals[] = { SK_Scalar1, SK_Scalar1 };

    paint.setStrokeWidth(2);
    paint.setPathEffect(new SkDashPathEffect(intervals, 2, 0))->unref();

    SkScalar big = 500 * 1000;

    canvas->drawLine(10, 10, big, 10, paint);
    canvas->drawLine(-big, 20, 500, 20, paint);
    canvas->drawLine(-big, 30, big, 30, paint);

    const SkScalar intervals2[] = { 20, 5, 10, 5 };
    paint.setPathEffect(new SkDashPathEffect(intervals2, 4, 17))->unref();

    canvas->translate(0, 40);
    SkScalar x = -500;
    SkScalar width = 3173;
    for (int i = 0; i < 40; ++i) {
        if (i > 10)
        canvas->drawLine(x, 0, x + width, 0, paint);
        x += 1;
        canvas->translate(0, 4);
    }
}

// Reproduces bug found here: http://jsfiddle.net/R8Cu5/1/
//
#include "SkGradientShader.h"
static void test_grad(SkCanvas* canvas) {
    SkPoint pts[] = {
        { 478.544067f, -84.2041016f },
        { 602.455933f, 625.204102f },
    };
    SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, SK_ColorRED, SK_ColorRED };
    SkScalar pos[] = { 0, 0.3f, 0.3f, 1.0f };
    SkShader* s = SkGradientShader::CreateLinear(pts, colors, pos, 4, SkShader::kClamp_TileMode);
    SkPaint p;
    p.setShader(s)->unref();
    canvas->drawPaint(p);
}

static SkCanvas* MakeCanvas(const SkIRect& bounds) {
    SkBitmap bm;
    bm.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(), bounds.height());
    bm.allocPixels();
    bm.eraseColor(SK_ColorTRANSPARENT);

    SkCanvas* canvas = new SkCanvas(bm);
    canvas->translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop));
    return canvas;
}

#ifdef SK_DEBUG
static void GetBitmap(const SkCanvas* canvas, SkBitmap* bm) {
    *bm = canvas->getDevice()->accessBitmap(false);
}
#endif

static void compare_canvas(const SkCanvas* a, const SkCanvas* b) {
#ifdef SK_DEBUG
    SkBitmap bma, bmb;
    GetBitmap(a, &bma);
    GetBitmap(b, &bmb);

    SkASSERT(bma.width() == bmb.width());
    SkASSERT(bma.height() == bmb.height());

    bma.lockPixels();
    bmb.lockPixels();
    for (int y = 0; y < bma.height(); ++y) {
        const SkPMColor* rowa = bma.getAddr32(0, y);
        const SkPMColor* rowb = bmb.getAddr32(0, y);
        SkASSERT(!memcmp(rowa, rowb, bma.width() << 2));

        for (int x = 1; x < bma.width() - 1; ++x) {
            SkASSERT(0xFF000000 == rowa[x]);
            SkASSERT(0xFF000000 == rowb[x]);
        }
    }
#endif
}

static void drawRectAsPath(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
    SkPath path;
    path.addRect(r);
    canvas->drawPath(path, p);
}

static void test_maskFromPath(const SkPath& path) {
    SkIRect bounds;
    path.getBounds().roundOut(&bounds);

    SkPaint paint;
    paint.setAntiAlias(true);

    SkAutoTUnref<SkCanvas> path_canvas(MakeCanvas(bounds));
    path_canvas->drawPath(path, paint);

    SkAutoTUnref<SkCanvas> rect_canvas(MakeCanvas(bounds));
    drawRectAsPath(rect_canvas, path.getBounds(), paint);

    compare_canvas(path_canvas, rect_canvas);
}

static void test_mask() {
    for (int i = 1; i <= 20; ++i) {
        const SkScalar dx = SK_Scalar1 / i;
        const SkRect constr = SkRect::MakeWH(dx, SkIntToScalar(2));
        for (int n = 2; n < 20; ++n) {
            SkPath path;
            path.setFillType(SkPath::kEvenOdd_FillType);
            SkRect r = constr;
            while (r.fRight < SkIntToScalar(4)) {
                path.addRect(r);
                r.offset(dx, 0);
            }
            test_maskFromPath(path);
        }
    }
}

namespace skiagm {

/** Draw a 2px border around the target, then red behind the target;
    set the clip to match the target, then draw >> the target in blue.
*/

static void draw (SkCanvas* canvas, SkRect& target, int x, int y) {
    SkPaint borderPaint;
    borderPaint.setColor(SkColorSetRGB(0x0, 0xDD, 0x0));
    borderPaint.setAntiAlias(true);
    SkPaint backgroundPaint;
    backgroundPaint.setColor(SkColorSetRGB(0xDD, 0x0, 0x0));
    backgroundPaint.setAntiAlias(true);
    SkPaint foregroundPaint;
    foregroundPaint.setColor(SkColorSetRGB(0x0, 0x0, 0xDD));
    foregroundPaint.setAntiAlias(true);

    canvas->save();
    canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
    target.inset(SkIntToScalar(-2), SkIntToScalar(-2));
    canvas->drawRect(target, borderPaint);
    target.inset(SkIntToScalar(2), SkIntToScalar(2));
    canvas->drawRect(target, backgroundPaint);
    canvas->clipRect(target, SkRegion::kIntersect_Op, true);
    target.inset(SkIntToScalar(-4), SkIntToScalar(-4));
    canvas->drawRect(target, foregroundPaint);
    canvas->restore();
}

static void draw_square (SkCanvas* canvas, int x, int y) {
    SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 10 * SK_Scalar1));
    draw(canvas, target, x, y);
}

static void draw_column (SkCanvas* canvas, int x, int y) {
    SkRect target (SkRect::MakeWH(1 * SK_Scalar1, 10 * SK_Scalar1));
    draw(canvas, target, x, y);
}

static void draw_bar (SkCanvas* canvas, int x, int y) {
    SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 1 * SK_Scalar1));
    draw(canvas, target, x, y);
}

static void draw_rect_tests (SkCanvas* canvas) {
    draw_square(canvas, 10, 10);
    draw_column(canvas, 30, 10);
    draw_bar(canvas, 10, 30);
}

/**
   Test a set of clipping problems discovered while writing blitAntiRect,
   and test all the code paths through the clipping blitters.
   Each region should show as a blue center surrounded by a 2px green
   border, with no red.
*/

class AAClipGM : public GM {
public:
    AAClipGM() {

    }

protected:
    virtual SkString onShortName() {
        return SkString("aaclip");
    }

    virtual SkISize onISize() {
        return make_isize(640, 480);
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        if (false) {
            test_giant_dash(canvas); return;
        }
        if (false) {
            test_grad(canvas); return;
        }
        if (false) { // avoid bit rot, suppress warning
            test_mask();
        }

        // Initial pixel-boundary-aligned draw
        draw_rect_tests(canvas);

        // Repeat 4x with .2, .4, .6, .8 px offsets
        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);

        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);

        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);

        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
        canvas->translate(SkIntToScalar(50), 0);
        draw_rect_tests(canvas);
    }

    virtual uint32_t onGetFlags() const { return kSkipPipe_Flag; }

private:
    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static GM* MyFactory(void*) { return new AAClipGM; }
static GMRegistry reg(MyFactory);

}
<|endoftext|>