void DoRegionFillingByEdgeTracing(int* image, int x, int y,
                                  int image_width, int image_height,
                                  int filling_colour) {
  int index_cen = y * image_width + x;
  int index[8];
  index[0] = std::max(y - 1, 0) * image_width + std::min(x + 1, image_width);
  index[1] = std::max(y - 1, 0) * image_width + x;
  index[2] = std::max(y - 1, 0) * image_width + std::max(x - 1, 0);
  index[3] = y * image_width + std::max(x - 1, 0);
  index[4] = y * image_width + std::min(x + 1, image_width);
  index[5] = std::min(y + 1, image_height) * image_width + std::min(x + 1, image_width);
  index[6] = std::min(y + 1, image_height) * image_width + x;
  index[7] = std::min(y + 1, image_height) * image_width + std::max(x - 1, 0);

  int firstPoint = 0;
  if (image[index_cen] == WHITE) {
    firstPoint = index_cen;
    int previous_index_cen = 0;
    int next_index_cen = 0;
    for (int i = 0; i < 8; i++) {
      if (image[index[i]] == WHITE) {
        previous_index_cen = index[i];
        break;
      }
    }

    std::vector<int> start_points;
    std::vector<int> end_points;
    int delt_angle = 0;
    int clockwise = 0;
    int* tmp_array = new int[image_width * image_height];
    while (previous_index_cen != 0) {
      int findPoint = FindNextPoint(image, previous_index_cen,
                                    index_cen, image_width,
                                    &next_index_cen, &delt_angle);
      if (findPoint == 1) {
        if (index_cen == firstPoint && image[next_index_cen] != WHITE) {

          Filling(image, start_points, end_points, clockwise, filling_colour);
          
          start_points.clear();
          end_points.clear();
          delt_angle = 0;
          delete [] tmp_array;
          return;
        }
        SetColourForPoints(image, tmp_array, previous_index_cen,
                           index_cen, next_index_cen, image_width,
                           &start_points, &end_points);
      } else {
        delete [] tmp_array;
        return;
      }
      previous_index_cen = index_cen;
      index_cen = next_index_cen;
    }
    delete [] tmp_array;
  }
}
Example #2
0
// ****************************************************************************
//
//  Function Name:	FollowOutline()
//
//  Description:		Follow the outline from a starting point in a DIB.
//
//  Returns:			TRUE if points added to Polygon, FALSE if not
//
//  Exceptions:		Memory exception
//
// ****************************************************************************
static BOOLEAN FollowOutline (const RIntPoint& StartPoint,
						  uBYTE InitialDirection,
						  const DIBINFO& Dib,
						  CPixelGrid& PixelGrid,
						  RPolyPolygon& rPolyPoly)
{

	uBYTE			Direction, PreviousDirection;
	RIntPoint	LastPoint, NextPoint;		

	if (PixelGrid.IsPointDirty (StartPoint))
	{
		// This point has already been used
		return FALSE;
	}

	Direction = InitialDirection;
	PreviousDirection = NULL_DIRECTION;
	LastPoint = StartPoint;
	rPolyPoly.NewPolygon();	
	do
	{
		Direction = FindNextPoint (LastPoint, NextPoint, Direction, Dib);
		
		if (Direction == NULL_DIRECTION)
		{
			// There is only one pixel in this shape									
			rPolyPoly.AddPoint (LastPoint);			
		}
		else if (Direction != PreviousDirection)
		{				
			rPolyPoly.AddPoint (LastPoint);
		}

		PreviousDirection = Direction;
		// Adjust direction
		if (Direction & 0x01)
		{
			// Direction is odd
			Direction = (uBYTE)((Direction + 2) & 0x07);
		}
		else
		{
			// Direction is even
			Direction = (uBYTE)((Direction + 1) & 0x07);
		}

		LastPoint	= NextPoint;
		
		// Must add all points traversed to pixel grid so they are not
		// considered as part of another shape			
		PixelGrid.MarkPoint (LastPoint);		
	}
	while ( LastPoint != StartPoint );
	
	// Make sure that start point is also end point of polyline
	rPolyPoly.AddPoint (LastPoint);
	//	Notify class this polygon is done
	rPolyPoly.EndPolygon();
	
	return TRUE;
}