Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) Canvas

 

STLQt CreatorLubuntuWindows

 

Canvas is the (abstract) base class of an ASCII art canvas. derived classes are, among others, DrawCanvas, ImageCanvas and TextCanvas.

Technical facts

 

 

 

 

 

 

./CppCanvas/CppCanvas.pri

 

INCLUDEPATH += \
    ../../Classes/CppCanvas

SOURCES += \
    ../../Classes/CppCanvas/canvas.cpp \
    ../../Classes/CppCanvas/canvascolorsystem.cpp \
    ../../Classes/CppCanvas/canvascoordinatsystem.cpp \
    ../../Classes/CppCanvas/canvascoordinatsystems.cpp \
    ../../Classes/CppCanvas/canvascolorsystems.cpp

HEADERS  += \
    ../../Classes/CppCanvas/canvas.h \
    ../../Classes/CppCanvas/canvascolorsystem.h \
    ../../Classes/CppCanvas/canvascoordinatsystem.h \
    ../../Classes/CppCanvas/canvascoordinatsystems.h \
    ../../Classes/CppCanvas/canvascolorsystems.h

OTHER_FILES += \
    ../../Classes/CppCanvas/Licence.txt

 

 

 

 

 

./CppCanvas/canvas.h

 

//---------------------------------------------------------------------------
/*
Canvas, ASCII art painting surface class
Copyright (C) 2008-2015 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl/CppCanvas.htm
//---------------------------------------------------------------------------
#ifndef RIBI_CANVAS_H
#define RIBI_CANVAS_H

#include <iosfwd>
#include <string>
#include <vector>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <boost/signals2.hpp>
#include "canvascolorsystem.h"
#include "canvascoordinatsystem.h"
#pragma GCC diagnostic pop

struct QRegExp;

namespace ribi {

///A Canvas is an ASCII art class for drawing (DrawCanvas),
///displaying images (ImageCanvas) and displaying text (TextCanvas)
struct Canvas
{
  Canvas();
  virtual ~Canvas() noexcept {}

  //From http://www.richelbilderbeek.nl/CppGetAsciiArtGradient.htm
  static std::vector<char> GetAsciiArtGradient() noexcept;

  ///Obtain the height of the canvas is characters
  virtual int GetHeight() const noexcept = 0;

  ///Obtain the version of this class
  static std::string GetVersion() noexcept;

  ///Obtain the version history of this class
  static std::vector<std::string> GetVersionHistory() noexcept;

  ///Obtain the width of the canvas is characters
  virtual int GetWidth() const noexcept = 0;

  ///Load a Canvas from std::strings
  ///DON'T: make it a constructor instead
  ///virtual void Load(const std::vector<std::string>& v) = 0;

  ///Convert the Canvas to std::strings
  virtual std::vector<std::string> ToStrings() const noexcept = 0;

  ///This signal is emitted when any member variable changes
  boost::signals2::signal<void(Canvas*)> m_signal_changed;

  private:
  ///From http://www.richelbilderbeek.nl/CppGetRegexMatches.htm
  //static std::vector<std::string> GetRegexMatches(
  //  const std::string& s,
  //  const QRegExp& r
  //) noexcept;

  ///Check if a coordinat is in the range of the Canvas
  bool IsInRange(const int x, const int y) const;

  //Obtains the minimum element of a 2D container
  //From http://www.richelbilderbeek.nl/CppMinElement.htm
  template <class Container>
  static typename Container::value_type::value_type MinElement(const Container& v);

  //Obtains the maximal element of a 2D container
  //From http://www.richelbilderbeek.nl/CppMaxElement.htm
  template <class Container>
  static typename Container::value_type::value_type MaxElement(const Container& v);

  #ifndef NDEBUG
  static void Test() noexcept;
  #endif
};

} //~namespace ribi

#endif // RIBI_CANVAS_H

 

 

 

 

 

./CppCanvas/canvas.cpp

 

//---------------------------------------------------------------------------
/*
Canvas, ASCII art painting surface class
Copyright (C) 2008-2015 Richel Bilderbeek

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
//---------------------------------------------------------------------------
// From http://www.richelbilderbeek.nl/CppCanvas.htm
//---------------------------------------------------------------------------
#include "canvas.h"

#include <iostream>
#include <cassert>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iterator>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
#include <boost/math/constants/constants.hpp>
#include <boost/algorithm/string/split.hpp>

#include <QString>
#include <QRegExp>

#include "canvascolorsystems.h"
#include "canvascoordinatsystems.h"
#include "fileio.h"
#include "trace.h"

#pragma GCC diagnostic pop

ribi::Canvas::Canvas()
  : m_signal_changed{}
{

}

std::vector<char> ribi::Canvas::GetAsciiArtGradient() noexcept
{
  return { 'M','N','m','d','h','y','s','o','+','/',':','-','.','`',' ' };
}

std::string ribi::Canvas::GetVersion() noexcept
{
  return "1.0";
}

std::vector<std::string> ribi::Canvas::GetVersionHistory() noexcept
{
  return {
    "2014-01-10: version 1.0: initial version, split up from DrawCanvas"
  };
}

template <class Container>
typename Container::value_type::value_type ribi::Canvas::MinElement(const Container& v)
{
  assert(v.empty() == false && "Container must have a size");
  //Obtain an initial lowest value
  typename Container::value_type::value_type minValue
    = *(std::min_element(v[0].begin(),v[0].end()));

  //Set the iterators
  const typename Container::const_iterator rowEnd = v.end();
  typename Container::const_iterator row = v.begin();
  ++row; //Move to the next position, as index 0 is already read from

  for ( ; row != rowEnd; ++row) //row is already initialized
  {
    const typename Container::value_type::value_type localMinVal
      = *(std::min_element(row->begin(),row->end()));
    if (localMinVal < minValue) minValue = localMinVal;
  }
  return minValue;
}

template <class Container>
typename Container::value_type::value_type ribi::Canvas::MaxElement(const Container& v)
{
  assert(v.empty() == false && "Container must have a size");

  //Obtain an initial heighest value
  typename Container::value_type::value_type maxValue
    = *(std::max_element(v[0].begin(),v[0].end()));

  //Set the iterators
  const typename Container::const_iterator rowEnd = v.end();
  typename Container::const_iterator row = v.begin();
  ++row; //Move to the next position, as index 0 is already read from
  for ( ; row != rowEnd; ++row) //row is already initialized
  {
    const typename Container::value_type::value_type localMaxVal
      = *(std::max_element(row->begin(),row->end()));
    if (localMaxVal > maxValue) maxValue = localMaxVal;
  }
  return maxValue;
}

 

 

 

 

 

./CppCanvas/canvascolorsystem.h

 

#ifndef RIBI_CANVASCOLORSYSTEM_H
#define RIBI_CANVASCOLORSYSTEM_H

namespace ribi {

///The color system used to draw on a Canvas:
///- normal: full/drawn is displayed by M
///- invert: empty/non-drawn is displayed by M
enum class CanvasColorSystem
{
  normal,
  invert,

  n_types //Used for testing
};

} //~namespace ribi

#endif // RIBI_CANVASCOLORSYSTEM_H

 

 

 

 

 

./CppCanvas/canvascolorsystem.cpp

 

#include "canvascolorsystem.h"

 

 

 

 

 

./CppCanvas/canvascolorsystems.h

 

#ifndef RIBI_CANVASCOLORSYSTEMS_H
#define RIBI_CANVASCOLORSYSTEMS_H

#include <string>
#include <vector>

#include "canvascolorsystem.h"

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <boost/bimap.hpp>
#pragma GCC diagnostic pop

namespace ribi {

struct CanvasColorSystems
{
  CanvasColorSystems();

  std::vector<CanvasColorSystem> GetAll() const noexcept;
  std::string ToStr(const CanvasColorSystem s) const noexcept;
  CanvasColorSystem ToType(const std::string& s) const;

  private:
  static boost::bimap<CanvasColorSystem,std::string> m_map;
  static boost::bimap<CanvasColorSystem,std::string> CreateMap();

  #ifndef NDEBUG
  static void Test() noexcept;
  #endif
};

} //~namespace ribi

#endif // RIBI_CANVASCOLORSYSTEMS_H

 

 

 

 

 

./CppCanvas/canvascolorsystems.cpp

 

#include "canvascolorsystems.h"

#include <cassert>

#include "testtimer.h"
#include "trace.h"

boost::bimap<ribi::CanvasColorSystem,std::string> ribi::CanvasColorSystems::m_map;

ribi::CanvasColorSystems::CanvasColorSystems()
{
  #ifndef NDEBUG
  Test();
  #endif
}

boost::bimap<ribi::CanvasColorSystem,std::string> ribi::CanvasColorSystems::CreateMap()
{
  boost::bimap<CanvasColorSystem,std::string> m;
  m.insert(boost::bimap<CanvasColorSystem,std::string>::value_type(
    CanvasColorSystem::invert,"invert"));
  m.insert(boost::bimap<CanvasColorSystem,std::string>::value_type(
    CanvasColorSystem::normal,"normal"));
  return m;
}

std::vector<ribi::CanvasColorSystem> ribi::CanvasColorSystems::GetAll() const noexcept
{
  const std::vector<CanvasColorSystem> v {
    CanvasColorSystem::invert,
    CanvasColorSystem::normal
  };
  assert(static_cast<int>(v.size()) == static_cast<int>(CanvasColorSystem::n_types));
  return v;
}

#ifndef NDEBUG
void ribi::CanvasColorSystems::Test() noexcept
{
  {
    static bool is_tested{false};
    if (is_tested) return;
    is_tested = true;
  }
  const TestTimer test_timer(__func__,__FILE__,1.0);
  const std::vector<CanvasColorSystem> v = CanvasColorSystems().GetAll();
  const std::size_t sz = v.size();
  for (std::size_t i=0; i!=sz; ++i)
  {
    assert(i < v.size());
    const CanvasColorSystem t = v[i];
    const std::string s = CanvasColorSystems().ToStr(t);
    assert(!s.empty());
    const CanvasColorSystem u = CanvasColorSystems().ToType(s);
    assert(u == t);
  }
}
#endif

std::string ribi::CanvasColorSystems::ToStr(const CanvasColorSystem type) const noexcept
{
  if (m_map.left.empty()) m_map = CreateMap();
  assert(!m_map.left.empty());
  assert(m_map.left.count(type));
  const std::string s = m_map.left.find(type)->second;
  return s;
}

ribi::CanvasColorSystem ribi::CanvasColorSystems::ToType(const std::string& s) const
{
  if (m_map.right.empty()) m_map = CreateMap();
  assert(!m_map.right.empty());
  assert(m_map.right.count(s) == 1);
  const CanvasColorSystem t = m_map.right.find(s)->second;
  return t;
}

 

 

 

 

 

./CppCanvas/canvascoordinatsystem.h

 

#ifndef RIBI_CANVASCOORDINATSYSTEM_H
#define RIBI_CANVASCOORDINATSYSTEM_H

namespace ribi {

///The coordinat system used in displayal:
///- screen: origin is at top-left of the screen
///- graph: origin is at bottom-left of the screen
enum class CanvasCoordinatSystem
{
  graph,
  screen,

  n_types //Used for testing
};

///View canvascoordinatsystem.h for functions to work with this enum class

} //~namespace ribi

#endif // RIBI_CANVASCOORDINATSYSTEM_H

 

 

 

 

 

./CppCanvas/canvascoordinatsystem.cpp

 

#include "canvascoordinatsystem.h"

 

 

 

 

 

./CppCanvas/canvascoordinatsystems.h

 

#ifndef RIBI_CANVASCOORDINATSYSTEMS_H
#define RIBI_CANVASCOORDINATSYSTEMS_H

#include <string>
#include <vector>


#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <boost/bimap.hpp>

#include "canvascoordinatsystem.h"
#pragma GCC diagnostic pop

namespace ribi {

struct CanvasCoordinatSystems
{
  CanvasCoordinatSystems();

  std::vector<CanvasCoordinatSystem> GetAll() const noexcept;
  std::string ToStr(const CanvasCoordinatSystem s) const noexcept;
  CanvasCoordinatSystem ToType(const std::string& s) const;

  private:
  static boost::bimap<CanvasCoordinatSystem,std::string> m_map;
  static boost::bimap<CanvasCoordinatSystem,std::string> CreateMap();

  #ifndef NDEBUG
  static void Test() noexcept;
  #endif
};

} //~namespace ribi

#endif // RIBI_CANVASCOORDINATSYSTEMS_H

 

 

 

 

 

./CppCanvas/canvascoordinatsystems.cpp

 

#include "canvascoordinatsystems.h"

#include <cassert>

#include "testtimer.h"
#include "trace.h"

boost::bimap<ribi::CanvasCoordinatSystem,std::string> ribi::CanvasCoordinatSystems::m_map;

ribi::CanvasCoordinatSystems::CanvasCoordinatSystems()
{
  #ifndef NDEBUG
  Test();
  #endif
}

boost::bimap<ribi::CanvasCoordinatSystem,std::string> ribi::CanvasCoordinatSystems::CreateMap()
{
  boost::bimap<CanvasCoordinatSystem,std::string> m;
  m.insert(boost::bimap<CanvasCoordinatSystem,std::string>::value_type(
    CanvasCoordinatSystem::graph,"graph"));
  m.insert(boost::bimap<CanvasCoordinatSystem,std::string>::value_type(
    CanvasCoordinatSystem::screen,"screen"));
  return m;
}

std::vector<ribi::CanvasCoordinatSystem> ribi::CanvasCoordinatSystems::GetAll() const noexcept
{
  const std::vector<CanvasCoordinatSystem> v {
    CanvasCoordinatSystem::graph,
    CanvasCoordinatSystem::screen
  };
  assert(static_cast<int>(v.size()) == static_cast<int>(CanvasCoordinatSystem::n_types));
  return v;
}

#ifndef NDEBUG
void ribi::CanvasCoordinatSystems::Test() noexcept
{
  {
    static bool is_tested{false};
    if (is_tested) return;
    is_tested = true;
  }
  const TestTimer test_timer(__func__,__FILE__,1.0);
  const std::vector<CanvasCoordinatSystem> v = CanvasCoordinatSystems().GetAll();
  const std::size_t sz = v.size();
  for (std::size_t i=0; i!=sz; ++i)
  {
    assert(i < v.size());
    const CanvasCoordinatSystem t = v[i];
    const std::string s = CanvasCoordinatSystems().ToStr(t);
    assert(!s.empty());
    const CanvasCoordinatSystem u = CanvasCoordinatSystems().ToType(s);
    assert(u == t);
  }
}
#endif


std::string ribi::CanvasCoordinatSystems::ToStr(const CanvasCoordinatSystem type) const noexcept
{
  if (m_map.left.empty()) m_map = CreateMap();
  assert(!m_map.left.empty());
  assert(m_map.left.count(type));
  const std::string s = m_map.left.find(type)->second;
  return s;
}

ribi::CanvasCoordinatSystem ribi::CanvasCoordinatSystems::ToType(const std::string& s) const
{
  if (m_map.right.empty()) m_map = CreateMap();
  assert(!m_map.right.empty());
  assert(m_map.right.count(s) == 1);
  const CanvasCoordinatSystem t = m_map.right.find(s)->second;
  return t;
}

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict

This page has been created by the tool CodeToHtml