text: // Copyright (C) 2008  Davis E. King (davis@dlib.net)
  // License: Boost Software License   See LICENSE.txt for the full license.
  #ifndef DLIB_DRAW_IMAGe_
  #define DLIB_DRAW_IMAGe_
  
  #include "draw_abstract.h"
  #include "../algs.h"
  #include "../pixel.h"
  #include <cmath>
  
  namespace dlib
  {
  
  // ----------------------------------------------------------------------------------------
  
      template <
          typename image_type,
          typename pixel_type
          >
      void draw_line (
          long x1,
          long y1,
          long x2,
          long y2,
          image_type& c,
          const pixel_type& val
      ) 
      {
          if (x1 == x2)
          {
              // make sure y1 comes before y2
              if (y1 > y2)
                  swap(y1,y2);
  
              if (x1 < 0 || x1 >= c.nc())
                  return;
  
  
              // this is a vertical line
              for (long y = y1; y <= y2; ++y)
              {
                  if (y < 0 || y >= c.nr())
                      continue;
  
                  assign_pixel(c[y][x1], val);
              }
          }
          else if (y1 == y2)
          {
  
              // make sure x1 comes before x2
              if (x1 > x2)
                  swap(x1,x2);
  
              if (y1 < 0 || y1 >= c.nr())
                  return;
  
              // this is a horizontal line
              for (long x = x1; x <= x2; ++x)
              {
                  if (x < 0 || x >= c.nc())
                      continue;
  
                  assign_pixel(c[y1][x] , val);
              }
          }
          else
          {
              const long rise = (((long)y2) - ((long)y1));
              const long run = (((long)x2) - ((long)x1));
              if (std::abs(rise) < std::abs(run))
              {
                  const double slope = ((double)rise)/run;
  
  
                  double first, last;
  
  
                  if (x1 > x2)                
                  {
                      first = x2;
                      last = x1;
                  }
                  else
                  {
                      first = x1;
                      last = x2;
                  }                             
  
                  long y;
                  long x;
                  const double x1f = x1;
                  const double y1f = y1;
                  for (double i = first; i <= last; ++i)
                  {   
                      y = static_cast<long>(slope*(i-x1f) + y1f);
                      x = static_cast<long>(i);
  
  
                      if (y < 0 || y >= c.nr())
                          continue;
  
                      if (x < 0 || x >= c.nc())
                          continue;
  
  
                      assign_pixel(c[y][x] , val);
                  }         
              }
              else
              {
                  const double slope = ((double)run)/rise;
  
  
                  double first, last;
  
  
                  if (y1 > y2)                
                  {
                      first = y2;
                      last = y1;
                  }
                  else
                  {
                      first = y1;
                      last = y2;
                  }                             
  
  
                  long x;
                  long y;
                  const double x1f = x1;
                  const double y1f = y1;
                  for (double i = first; i <= last; ++i)
                  {   
                      x = static_cast<long>(slope*(i-y1f) + x1f);
                      y = static_cast<long>(i);
  
  
                      if (x < 0 || x >= c.nc())
                          continue;
  
                      if (y < 0 || y >= c.nr())
                          continue;
  
                      assign_pixel(c[y][x] , val);
                  } 
              }
          }
  
      }
  
  // ----------------------------------------------------------------------------------------
  
      template <
          typename image_type,
          typename pixel_type
          >
      void draw_line (
          image_type& c,
          const point& p1,
          const point& p2,
          const pixel_type& val
      ) 
      {
          draw_line(p1.x(),p1.y(),p2.x(),p2.y(),c,val);
      }
  
  // ----------------------------------------------------------------------------------------
  
      template <
          typename image_type,
          typename pixel_type
          >
      void fill_rect (
          image_type& img,
          const rectangle& rect,
          const pixel_type& pixel
      )
      {
          rectangle area = rect.intersect(get_rect(img));
  
          for (long r = area.top(); r <= area.bottom(); ++r)
          {
              for (long c = area.left(); c <= area.right(); ++c)
              {
                  assign_pixel(img[r][c], pixel);
              }
          }
      }
  
  // ----------------------------------------------------------------------------------------
  
  }
  
  #endif // DLIB_DRAW_IMAGe_
  
  
  
  
  