Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef RASTER_EDGE_ITERATOR_HPP
Toshihiro Shimizu 890ddd
#define RASTER_EDGE_ITERATOR_HPP
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "raster_edge_iterator.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace TRop {
Shinya Kitaoka 120a6e
namespace borders {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Toshihiro Shimizu 890ddd
RasterEdgeIterator<pixelselector>::RasterEdgeIterator(</pixelselector>
Shinya Kitaoka 120a6e
    const raster_typeP &rin, const selector_type &selector, const TPoint &pos,
Shinya Kitaoka 120a6e
    const TPoint &dir, int adherence)
Shinya Kitaoka 120a6e
    : m_ras(rin)
Shinya Kitaoka 120a6e
    , m_lx_1(rin->getLx() - 1)
Shinya Kitaoka 120a6e
    , m_ly_1(rin->getLy() - 1)
Shinya Kitaoka 120a6e
    , m_wrap(rin->getWrap())
Shinya Kitaoka 120a6e
    , m_selector(selector)
Shinya Kitaoka 120a6e
    , m_pos(pos)
Shinya Kitaoka 120a6e
    , m_dir(dir)
Shinya Kitaoka 120a6e
    , m_elbowColor(selector.transparent())
Shinya Kitaoka 120a6e
    , m_rightSide(adherence == RIGHT)
Shinya Kitaoka 120a6e
    , m_turn(UNKNOWN) {
Shinya Kitaoka 120a6e
  pixels(m_leftPix, m_rightPix);
Shinya Kitaoka 120a6e
  colors(m_leftColor, m_rightColor);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
void RasterEdgeIterator<pixelselector>::setEdge(const TPoint &pos,</pixelselector>
Shinya Kitaoka 120a6e
                                                const TPoint &dir) {
Shinya Kitaoka 120a6e
  m_pos = pos, m_dir = dir;
Shinya Kitaoka 120a6e
  pixels(m_leftPix, m_rightPix);
Shinya Kitaoka 120a6e
  colors(m_leftColor, m_rightColor);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
inline void RasterEdgeIterator<pixelselector>::pixels(pixel_type *&pixLeft,</pixelselector>
Shinya Kitaoka 120a6e
                                                      pixel_type *&pixRight) {
Shinya Kitaoka 120a6e
  pixel_type *pix = m_ras->pixels(0) + m_pos.y * m_wrap + m_pos.x;
Shinya Kitaoka 120a6e
  if (m_dir.y)
Shinya Kitaoka 120a6e
    if (m_dir.y > 0)
Shinya Kitaoka 120a6e
      pixLeft = pix - 1, pixRight = pix;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      pixLeft = pix - m_wrap, pixRight = pixLeft - 1;
Shinya Kitaoka 120a6e
  else if (m_dir.x > 0)
Shinya Kitaoka 120a6e
    pixLeft = pix, pixRight = pix - m_wrap;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    pixRight = pix - 1, pixLeft = pixRight - m_wrap;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
inline void RasterEdgeIterator<pixelselector>::colors(value_type &leftColor,</pixelselector>
Shinya Kitaoka 120a6e
                                                      value_type &rightColor) {
Shinya Kitaoka 120a6e
  if (m_dir.y)
Shinya Kitaoka 120a6e
    if (m_dir.y > 0) {
Shinya Kitaoka 120a6e
      if (m_pos.y > m_ly_1)
Shinya Kitaoka 120a6e
        leftColor = rightColor = m_selector.transparent();
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        leftColor = (m_pos.x > 0) ? m_selector.value(*m_leftPix)
Shinya Kitaoka 120a6e
                                  : m_selector.transparent();
Shinya Kitaoka 120a6e
        rightColor = (m_pos.x <= m_lx_1) ? m_selector.value(*m_rightPix)
Shinya Kitaoka 120a6e
                                         : m_selector.transparent();
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      if (m_pos.y < 1)
Shinya Kitaoka 120a6e
        leftColor = rightColor = m_selector.transparent();
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        leftColor = (m_pos.x <= m_lx_1) ? m_selector.value(*m_leftPix)
Shinya Kitaoka 120a6e
                                        : m_selector.transparent();
Shinya Kitaoka 120a6e
        rightColor = (m_pos.x > 0) ? m_selector.value(*m_rightPix)
Shinya Kitaoka 120a6e
                                   : m_selector.transparent();
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  else if (m_dir.x > 0) {
Shinya Kitaoka 120a6e
    if (m_pos.x > m_lx_1)
Shinya Kitaoka 120a6e
      leftColor = rightColor = m_selector.transparent();
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      leftColor = (m_pos.y <= m_ly_1) ? m_selector.value(*m_leftPix)
Shinya Kitaoka 120a6e
                                      : m_selector.transparent();
Shinya Kitaoka 120a6e
      rightColor = (m_pos.y > 0) ? m_selector.value(*m_rightPix)
Shinya Kitaoka 120a6e
                                 : m_selector.transparent();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (m_pos.x < 1)
Shinya Kitaoka 120a6e
      leftColor = rightColor = m_selector.transparent();
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      leftColor = (m_pos.y > 0) ? m_selector.value(*m_leftPix)
Shinya Kitaoka 120a6e
                                : m_selector.transparent();
Shinya Kitaoka 120a6e
      rightColor = (m_pos.y <= m_ly_1) ? m_selector.value(*m_rightPix)
Shinya Kitaoka 120a6e
                                       : m_selector.transparent();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
inline void RasterEdgeIterator<pixelselector>::turn(</pixelselector>
Shinya Kitaoka 120a6e
    const value_type &newLeftColor, const value_type &newRightColor) {
Shinya Kitaoka 120a6e
  if (m_rightSide) {
Shinya Kitaoka 120a6e
    if (newLeftColor == m_rightColor) {
Shinya Kitaoka 120a6e
      if (newRightColor == m_leftColor)
Shinya Kitaoka 120a6e
        turnAmbiguous(newLeftColor, newRightColor);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        turnLeft();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      if (newRightColor != m_rightColor)
Shinya Kitaoka 120a6e
        turnRight();
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        m_turn = STRAIGHT;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_elbowColor = newLeftColor;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (newRightColor == m_leftColor) {
Shinya Kitaoka 120a6e
      if (newLeftColor == m_rightColor)
Shinya Kitaoka 120a6e
        turnAmbiguous(newLeftColor, newRightColor);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        turnRight();
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      if (newLeftColor != m_leftColor)
Shinya Kitaoka 120a6e
        turnLeft();
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        m_turn = STRAIGHT;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    m_elbowColor = newRightColor;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pixels(m_leftPix, m_rightPix);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Toshihiro Shimizu 890ddd
inline void RasterEdgeIterator<pixelselector>::turnAmbiguous(</pixelselector>
Shinya Kitaoka 120a6e
    const value_type &newLeftColor, const value_type &newRightColor) {
Shinya Kitaoka 120a6e
  pixel_type *pix = m_ras->pixels(0) + m_pos.y * m_wrap + m_pos.x;
Shinya Kitaoka 120a6e
  UCHAR count1 = 0, count2 = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  value_type val;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Check the 4x4 neighbourhood and connect the minority color
Shinya Kitaoka 120a6e
  if (m_pos.x > 2) {
Shinya Kitaoka 120a6e
    val = m_selector.value(*(pix - 2));
Shinya Kitaoka 120a6e
    if (val == m_leftColor)
Shinya Kitaoka 120a6e
      ++count1;
Shinya Kitaoka 120a6e
    else if (val == m_rightColor)
Shinya Kitaoka 120a6e
      ++count2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    val = m_selector.value(*(pix - 2 - m_wrap));
Shinya Kitaoka 120a6e
    if (val == m_leftColor)
Shinya Kitaoka 120a6e
      ++count1;
Shinya Kitaoka 120a6e
    else if (val == m_rightColor)
Shinya Kitaoka 120a6e
      ++count2;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_pos.x < m_lx_1) {
Shinya Kitaoka 120a6e
    val = m_selector.value(*(pix + 1));
Shinya Kitaoka 120a6e
    if (val == m_leftColor)
Shinya Kitaoka 120a6e
      ++count1;
Shinya Kitaoka 120a6e
    else if (val == m_rightColor)
Shinya Kitaoka 120a6e
      ++count2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    val = m_selector.value(*(pix + 1 - m_wrap));
Shinya Kitaoka 120a6e
    if (val == m_leftColor)
Shinya Kitaoka 120a6e
      ++count1;
Shinya Kitaoka 120a6e
    else if (val == m_rightColor)
Shinya Kitaoka 120a6e
      ++count2;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_pos.y > 2) {
Shinya Kitaoka 120a6e
    int wrap2 = m_wrap << 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    val = m_selector.value(*(pix - wrap2));
Shinya Kitaoka 120a6e
    if (val == m_leftColor)
Shinya Kitaoka 120a6e
      ++count1;
Shinya Kitaoka 120a6e
    else if (val == m_rightColor)
Shinya Kitaoka 120a6e
      ++count2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    val = m_selector.value(*(pix - wrap2 - 1));
Shinya Kitaoka 120a6e
    if (val == m_leftColor)
Shinya Kitaoka 120a6e
      ++count1;
Shinya Kitaoka 120a6e
    else if (val == m_rightColor)
Shinya Kitaoka 120a6e
      ++count2;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_pos.y < m_ly_1) {
Shinya Kitaoka 120a6e
    val = m_selector.value(*(pix + m_wrap));
Shinya Kitaoka 120a6e
    if (val == m_leftColor)
Shinya Kitaoka 120a6e
      ++count1;
Shinya Kitaoka 120a6e
    else if (val == m_rightColor)
Shinya Kitaoka 120a6e
      ++count2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    val = m_selector.value(*(pix + m_wrap - 1));
Shinya Kitaoka 120a6e
    if (val == m_leftColor)
Shinya Kitaoka 120a6e
      ++count1;
Shinya Kitaoka 120a6e
    else if (val == m_rightColor)
Shinya Kitaoka 120a6e
      ++count2;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Minority connection - join the one with less count
Shinya Kitaoka 120a6e
  if (count1 < count2)
Shinya Kitaoka 120a6e
    turnRight();  // Join m_leftColor == newRightColor
Shinya Kitaoka 120a6e
  else if (count1 > count2)
Shinya Kitaoka 120a6e
    turnLeft();  // Join m_rightColor == newLeftColor
Shinya Kitaoka 120a6e
  else if (m_rightColor < m_leftColor)
Shinya Kitaoka 120a6e
    turnLeft();
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    turnRight();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_turn |= AMBIGUOUS;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixelselector=""></typename>
Shinya Kitaoka 120a6e
RasterEdgeIterator<pixelselector></pixelselector>
Shinya Kitaoka 120a6e
    &RasterEdgeIterator<pixelselector>::operator++() {</pixelselector>
Shinya Kitaoka 120a6e
  value_type newLeftColor = m_leftColor, newRightColor = m_rightColor;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int pixAdd = m_dir.y * m_wrap + m_dir.x;
Shinya Kitaoka 120a6e
  if (m_rightSide) {
Shinya Kitaoka 120a6e
    do {
Shinya Kitaoka 120a6e
      m_pos.x += m_dir.x, m_pos.y += m_dir.y;
Shinya Kitaoka 120a6e
      m_leftPix += pixAdd, m_rightPix += pixAdd;
Shinya Kitaoka 120a6e
      m_leftColor = newLeftColor;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      colors(newLeftColor, newRightColor);
Shinya Kitaoka 120a6e
    } while ((newRightColor == m_rightColor) &&
Shinya Kitaoka 120a6e
             (newLeftColor != newRightColor) &&
Shinya Kitaoka 120a6e
             m_selector.skip(m_leftColor, newLeftColor));
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    do {
Shinya Kitaoka 120a6e
      m_pos.x += m_dir.x, m_pos.y += m_dir.y;
Shinya Kitaoka 120a6e
      m_leftPix += pixAdd, m_rightPix += pixAdd;
Shinya Kitaoka 120a6e
      m_rightColor = newRightColor;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      colors(newLeftColor, newRightColor);
Shinya Kitaoka 120a6e
    } while ((newLeftColor == m_leftColor) && (newLeftColor != newRightColor) &&
Shinya Kitaoka 120a6e
             m_selector.skip(m_rightColor, newRightColor));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  turn(newLeftColor, newRightColor);
Shinya Kitaoka 120a6e
  colors(m_leftColor, m_rightColor);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
}  //  namespace TRop::borders
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // RASTER_EDGE_ITERATOR_HPP