diff options
Diffstat (limited to 'pdf-as-lib')
| -rw-r--r-- | pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java | 641 | 
1 files changed, 319 insertions, 322 deletions
| diff --git a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java index a851e18..138f334 100644 --- a/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java +++ b/pdf-as-lib/src/main/java/at/knowcenter/wag/egov/egiz/pdf/PDFPage.java @@ -73,80 +73,83 @@ import at.knowcenter.wag.egov.egiz.pdf.operator.path.painting.StrokePath;   * This method is called when processing the FileStream. By calling the method
   * {@link org.pdfbox.util.PDFStreamEngine#processStream(org.pdfbox.pdmodel.PDPage, org.pdfbox.pdmodel.PDResources, org.pdfbox.cos.COSStream)}
   * the implemented method showCharacter is called.
 - *
 + * 
   * @author wlackner
   * @see PDFTextStripper
   */
 -public class PDFPage extends PDFTextStripper
 -{
 -  /**
 -   * The logger definition.
 -   */
 -  private static final Logger logger_ = ConfigLogger.getLogger(PDFPage.class);
 -
 -  /**
 -   * The maximum (lowest) y position of a character.
 -   */
 -  protected float max_character_ypos = Float.NEGATIVE_INFINITY;
 -
 -  /**
 -   * The maximum (lowest y position of an image.
 -   */
 -  protected float max_image_ypos = Float.NEGATIVE_INFINITY;
 -
 -  /**
 -   * The effective page height.
 -   */
 -  protected float effectivePageHeight;
 -
 -  /**
 -   * The path currently being constructed.
 -   */
 -  private GeneralPath currentPath = new GeneralPath();
 -
 -  /**
 -   * The lowest position of a drawn path (originating from top).
 -   */
 -  private float maxPathRelatedYPositionFromTop = Float.NEGATIVE_INFINITY;
 -
 -  /**
 -   * Constructor.
 -   *
 -   * @param effectivePageHeight The height of the page to be evaluated. PDF elements outside this height will not be considered.
 -   *
 -   * @throws IOException
 -   */
 -  public PDFPage(float effectivePageHeight) throws IOException
 -  {
 -    super();
 -
 -    this.effectivePageHeight = effectivePageHeight;
 -
 -    OperatorProcessor newInvoke = new MyInvoke();
 -    newInvoke.setContext(this);
 -    operators.put("Do", newInvoke);
 -
 -    boolean legacy = false;
 -    
 -    try {
 -    	String leg = SettingsReader.getInstance().getSetting("legacy_positioning", "false");
 -    	if("true".equals(leg)) {
 -    		legacy = true;
 -    	}
 -    } catch (SettingsException e) {
 -		// TODO Auto-generated catch block
 -		e.printStackTrace();
 -	} 
 -    
 -    if(!legacy) {
 -    	registerCustomPathOperators();
 -    }
 -  }
 +public class PDFPage extends PDFTextStripper {
 +	/**
 +	 * The logger definition.
 +	 */
 +	private static final Logger logger_ = ConfigLogger.getLogger(PDFPage.class);
  	/**
 -	 * Registers operators responsible for path construction and painting in order to fix auto positioning on pages with
 -	 * path elements.
 -	 *
 +	 * The maximum (lowest) y position of a character.
 +	 */
 +	protected float max_character_ypos = Float.NEGATIVE_INFINITY;
 +
 +	/**
 +	 * The maximum (lowest y position of an image.
 +	 */
 +	protected float max_image_ypos = Float.NEGATIVE_INFINITY;
 +
 +	/**
 +	 * The effective page height.
 +	 */
 +	protected float effectivePageHeight;
 +
 +	/**
 +	 * The path currently being constructed.
 +	 */
 +	private GeneralPath currentPath = new GeneralPath();
 +
 +	/**
 +	 * The lowest position of a drawn path (originating from top).
 +	 */
 +	private float maxPathRelatedYPositionFromTop = Float.NEGATIVE_INFINITY;
 +
 +	/**
 +	 * Constructor.
 +	 * 
 +	 * @param effectivePageHeight
 +	 *            The height of the page to be evaluated. PDF elements outside
 +	 *            this height will not be considered.
 +	 * 
 +	 * @throws IOException
 +	 */
 +	public PDFPage(float effectivePageHeight) throws IOException {
 +		super();
 +
 +		this.effectivePageHeight = effectivePageHeight;
 +
 +		OperatorProcessor newInvoke = new MyInvoke();
 +		newInvoke.setContext(this);
 +		operators.put("Do", newInvoke);
 +
 +		boolean legacy = false;
 +
 +		try {
 +			String leg = SettingsReader.getInstance().getSetting("legacy.pos",
 +					"false");
 +			if (leg != null) {
 +				if ("true".equals(leg.trim())) {
 +					legacy = true;
 +				}
 +			}
 +		} catch (SettingsException e) {
 +			// TODO Auto-generated catch block
 +			e.printStackTrace();
 +		}
 +
 +		if (!legacy) {
 +			registerCustomPathOperators();
 +		}
 +	}
 +
 +	/**
 +	 * Registers operators responsible for path construction and painting in
 +	 * order to fix auto positioning on pages with path elements.
 +	 * 
  	 * @author Datentechnik Innovation GmbH
  	 */
  	@SuppressWarnings("unchecked")
 @@ -175,16 +178,19 @@ public class PDFPage extends PDFTextStripper  		operators.put("B*", new FillEvenOddAndStrokePath(this));
  		operators.put("n", new EndPath(this));
 -		// Note: The graphic context (org.pdfbox.pdmodel.graphics.PDGraphicsState) of the underlying pdfbox library does
 -		// not yet support clipping. This prevents feasible usage of clipping operators (W, W*).
 -//		operators.put("W", new ...(this));
 -//		operators.put("W*", new ...(this));
 +		// Note: The graphic context
 +		// (org.pdfbox.pdmodel.graphics.PDGraphicsState) of the underlying
 +		// pdfbox library does
 +		// not yet support clipping. This prevents feasible usage of clipping
 +		// operators (W, W*).
 +		// operators.put("W", new ...(this));
 +		// operators.put("W*", new ...(this));
  	}
  	/**
  	 * Returns the path currently being constructed.
 -	 *
 +	 * 
  	 * @return The path currently being constructed.
  	 */
  	public GeneralPath getCurrentPath() {
 @@ -193,7 +199,9 @@ public class PDFPage extends PDFTextStripper  	/**
  	 * Sets the current path.
 -	 * @param currentPath The new current path.
 +	 * 
 +	 * @param currentPath
 +	 *            The new current path.
  	 */
  	public void setCurrentPath(GeneralPath currentPath) {
  		this.currentPath = currentPath;
 @@ -201,9 +209,10 @@ public class PDFPage extends PDFTextStripper  	/**
  	 * Registers a rectangle that bounds the path currently being drawn.
 -	 *
 +	 * 
  	 * @param bounds
 -	 *            A rectangle depicting the bounds (coordinates originating from bottom left).
 +	 *            A rectangle depicting the bounds (coordinates originating from
 +	 *            bottom left).
  	 * @author Datentechnik Innovation GmbH
  	 */
  	public void registerPathBounds(Rectangle bounds) {
 @@ -233,257 +242,250 @@ public class PDFPage extends PDFTextStripper  				break;
  			case 270: // CCW
  				pageHeight = boundaryBox.getWidth();
 -				upperBoundYPositionFromTop = pageHeight - (float) bounds.getMaxX();
 -				lowerBoundYPositionFromTop = pageHeight - (float) bounds.getMinX();
 +				upperBoundYPositionFromTop = pageHeight
 +						- (float) bounds.getMaxX();
 +				lowerBoundYPositionFromTop = pageHeight
 +						- (float) bounds.getMinX();
  				break;
  			default:
  				pageHeight = boundaryBox.getHeight();
 -				upperBoundYPositionFromTop = pageHeight - (float) bounds.getMaxY();
 -				lowerBoundYPositionFromTop = pageHeight - (float) bounds.getMinY();
 +				upperBoundYPositionFromTop = pageHeight
 +						- (float) bounds.getMaxY();
 +				lowerBoundYPositionFromTop = pageHeight
 +						- (float) bounds.getMinY();
  				break;
  			}
  			// new maximum ?
  			if (lowerBoundYPositionFromTop > maxPathRelatedYPositionFromTop) {
 -				// Is the rectangle (at least partly) located above the footer line?
 +				// Is the rectangle (at least partly) located above the footer
 +				// line?
  				// (effective page height := page height - footer line)
  				if (upperBoundYPositionFromTop <= effectivePageHeight) {
  					// yes: update current end of path-related page content
  					maxPathRelatedYPositionFromTop = lowerBoundYPositionFromTop;
 -					logger_.trace("New max path related y position (from top): " + maxPathRelatedYPositionFromTop);
 +					logger_.trace("New max path related y position (from top): "
 +							+ maxPathRelatedYPositionFromTop);
  				} else {
 -					// no: rectangle is fully located below the footer line -> ignore
 +					// no: rectangle is fully located below the footer line ->
 +					// ignore
  					logger_.trace("Ignoring path bound below the footer line.");
  				}
  			}
  		}
  	}
 -  protected void processOperator(PDFOperator operator, List arguments) throws IOException
 -  {
 -//    logger_.debug("operator = " + operator);
 -	  super.processOperator(operator, arguments);
 -  }
 -
 -  // exthex
 -  /**
 -   * A method provided as an event interface to allow a subclass to perform some
 -   * specific functionality when a character needs to be displayed. This method
 -   * is used to calculate the latest position of a text in the page. Sorry for
 -   * this missinterpretation of the method, but it is the only way to do this
 -   * (provided by PDFBox)!!!
 -   *
 -   * @param text
 -   *          the character to be displayed -> calculate there y position.
 -   */
 -  protected void showCharacter(TextPosition text)
 -  {
 -    float current_y = text.getY();
 -    final String character = text.getCharacter();
 -
 -    int pageRotation = page.findRotation();
 -    //logger_.debug("PageRotation = " + pageRotation);
 -    if (pageRotation == 0)
 -    {
 -    	current_y = text.getY();
 -    }
 -    if (pageRotation == 90)
 -    {
 -    	current_y = text.getX();
 -    }
 -    if (pageRotation == 180)
 -    {
 -      float page_height = page.findMediaBox().getHeight();
 -      current_y = page_height - text.getY();
 -    }
 -    if (pageRotation == 270)
 -    {
 -    	float page_height = page.findMediaBox().getHeight();
 -        current_y = page_height - text.getX();
 -    }
 -
 -    if (current_y > this.effectivePageHeight)
 -    {
 -      //logger_.debug("character is below footer_line. footer_line = " + this.footer_line + ", text.character=" + character + ", y=" + current_y);
 -      return;
 -    }
 -
 -    // store ypos of the char if it is not empty
 -    if (!character.equals(" ") && current_y > this.max_character_ypos)
 -    {
 -      this.max_character_ypos = current_y;
 -    }
 -
 -  }
 -
 -  // use this funtion getting an unsorted text output
 -  // public void showString(byte[] string) {
 -  // logger_.debug(new String(string));
 -  // }
 +	protected void processOperator(PDFOperator operator, List arguments)
 +			throws IOException {
 +		// logger_.debug("operator = " + operator);
 +		super.processOperator(operator, arguments);
 +	}
 +
 +	// exthex
 +	/**
 +	 * A method provided as an event interface to allow a subclass to perform
 +	 * some specific functionality when a character needs to be displayed. This
 +	 * method is used to calculate the latest position of a text in the page.
 +	 * Sorry for this missinterpretation of the method, but it is the only way
 +	 * to do this (provided by PDFBox)!!!
 +	 * 
 +	 * @param text
 +	 *            the character to be displayed -> calculate there y position.
 +	 */
 +	protected void showCharacter(TextPosition text) {
 +		float current_y = text.getY();
 +		final String character = text.getCharacter();
 +
 +		int pageRotation = page.findRotation();
 +		// logger_.debug("PageRotation = " + pageRotation);
 +		if (pageRotation == 0) {
 +			current_y = text.getY();
 +		}
 +		if (pageRotation == 90) {
 +			current_y = text.getX();
 +		}
 +		if (pageRotation == 180) {
 +			float page_height = page.findMediaBox().getHeight();
 +			current_y = page_height - text.getY();
 +		}
 +		if (pageRotation == 270) {
 +			float page_height = page.findMediaBox().getHeight();
 +			current_y = page_height - text.getX();
 +		}
 +
 +		if (current_y > this.effectivePageHeight) {
 +			// logger_.debug("character is below footer_line. footer_line = " +
 +			// this.footer_line + ", text.character=" + character + ", y=" +
 +			// current_y);
 +			return;
 +		}
 +
 +		// store ypos of the char if it is not empty
 +		if (!character.equals(" ") && current_y > this.max_character_ypos) {
 +			this.max_character_ypos = current_y;
 +		}
 +
 +	}
 +
 +	// use this funtion getting an unsorted text output
 +	// public void showString(byte[] string) {
 +	// logger_.debug(new String(string));
 +	// }
  	/**
  	 * Returns the calculated page length.
 -	 *
 +	 * 
  	 * @return the max page length value
  	 */
  	public float getMaxPageLength() {
  		if (logger_.isDebugEnabled()) {
 -			logger_.debug("Determining page content length: text=" + max_character_ypos + ", image=" + max_image_ypos
 +			logger_.debug("Determining page content length: text="
 +					+ max_character_ypos + ", image=" + max_image_ypos
  					+ ", path=" + maxPathRelatedYPositionFromTop);
  		}
 -		return NumberUtils.max(max_character_ypos, max_image_ypos, maxPathRelatedYPositionFromTop);
 +		return NumberUtils.max(max_character_ypos, max_image_ypos,
 +				maxPathRelatedYPositionFromTop);
 +	}
 +
 +	public class MyInvoke extends OperatorProcessor {
 +
 +		public void process(PDFOperator operator, List arguments)
 +				throws IOException {
 +			COSName name = (COSName) arguments.get(0);
 +
 +			// PDResources res = context.getResources();
 +
 +			Map xobjects = context.getXObjects();
 +			PDXObject xobject = (PDXObject) xobjects.get(name.getName());
 +
 +			PDStream stream = xobject.getPDStream();
 +			COSStream cos_stream = stream.getStream();
 +
 +			COSName subtype = (COSName) cos_stream
 +					.getDictionaryObject(COSName.SUBTYPE);
 +			if (subtype.equals(COSName.IMAGE)) {
 +				logger_.debug("XObject Image");
 +
 +				Matrix ctm = context.getGraphicsState()
 +						.getCurrentTransformationMatrix();
 +				logger_.debug("ctm = " + ctm);
 +
 +				Pos[] coordinates = new Pos[] { new Pos(0, 0, 1),
 +						new Pos(1, 0, 1), new Pos(0, 1, 1), new Pos(1, 1, 1) };
 +
 +				Pos[] transformed_coordinates = transtormCoordinates(
 +						coordinates, ctm);
 +
 +				/**********************************************************
 +				 * pdf-as fix: calculating min and max point of an image to look
 +				 * where the signature should be placed fix solves problems with
 +				 * footer and images and placement of the signature in an image
 +				 * only pdf document
 +				 **********************************************************/
 +
 +				float actual_lowest_point = Float.NaN;
 +				float actual_starting_point = Float.NaN;
 +
 +				int pageRotation = page.findRotation();
 +				logger_.debug("PageRotation = " + pageRotation);
 +				if (pageRotation == 0) {
 +					float min_y = findMinY(transformed_coordinates);
 +					logger_.debug("min_y = " + min_y);
 +					float page_height = page.findMediaBox().getHeight();
 +					logger_.debug("page_height = " + page_height);
 +
 +					actual_lowest_point = page_height - min_y;
 +					actual_starting_point = page_height
 +							- findMaxY(transformed_coordinates);
 +				}
 +				if (pageRotation == 90) {
 +					float max_x = findMaxX(transformed_coordinates);
 +					logger_.debug("max_x = " + max_x);
 +					float page_width = page.findMediaBox().getWidth();
 +					logger_.debug("page_width = " + page_width);
 +
 +					actual_lowest_point = max_x;
 +					actual_starting_point = findMinX(transformed_coordinates);
 +				}
 +				if (pageRotation == 180) {
 +					float min_y = findMinY(transformed_coordinates);
 +					logger_.debug("min_y = " + min_y);
 +					float page_height = page.findMediaBox().getHeight();
 +					actual_lowest_point = page_height
 +							- findMaxY(transformed_coordinates);
 +					actual_starting_point = page_height - min_y;
 +				}
 +				if (pageRotation == 270) {
 +					float min_x = findMinX(transformed_coordinates);
 +					logger_.debug("min_x = " + min_x);
 +
 +					float page_width = page.findMediaBox().getWidth();
 +					logger_.debug("page_width = " + page_width);
 +
 +					actual_lowest_point = page_width - min_x;
 +					actual_starting_point = page_width
 +							- findMaxX(transformed_coordinates);
 +				}
 +
 +				logger_.debug("actual_lowest_point = " + actual_lowest_point);
 +
 +				if (actual_lowest_point > PDFPage.this.effectivePageHeight
 +						&& actual_starting_point > PDFPage.this.effectivePageHeight) {
 +					logger_.debug("image is below footer_line");
 +					return;
 +				}
 +
 +				if (actual_lowest_point > PDFPage.this.max_image_ypos) {
 +					PDFPage.this.max_image_ypos = actual_lowest_point;
 +				}
 +
 +				return;
 +			}
 +
 +			if (xobject instanceof PDXObjectForm) {
 +				PDXObjectForm form = (PDXObjectForm) xobject;
 +				COSStream invoke = (COSStream) form.getCOSObject();
 +				PDResources pdResources = form.getResources();
 +				PDPage page = context.getCurrentPage();
 +				if (pdResources == null) {
 +					pdResources = page.findResources();
 +				}
 +
 +				getContext().processSubStream(page, pdResources, invoke);
 +			}
 +		}
 +	}
 +
 +	public static Pos[] transtormCoordinates(Pos[] coordinates, Matrix m) {
 +		Pos[] transformed = new Pos[coordinates.length];
 +		for (int i = 0; i < coordinates.length; i++) {
 +			transformed[i] = transtormCoordinate(coordinates[i], m);
 +		}
 +		return transformed;
 +	}
 +
 +	public static Pos transtormCoordinate(Pos pos, Matrix m) {
 +		Pos transformed = new Pos();
 +		transformed.x = pos.x * m.getValue(0, 0) + pos.y * m.getValue(1, 0)
 +				+ pos.z * m.getValue(2, 0);
 +		transformed.y = pos.x * m.getValue(0, 1) + pos.y * m.getValue(1, 1)
 +				+ pos.z * m.getValue(2, 1);
 +		transformed.z = pos.x * m.getValue(0, 2) + pos.y * m.getValue(1, 2)
 +				+ pos.z * m.getValue(2, 2);
 +
 +		logger_.debug(" transformed " + pos + " --> " + transformed);
 +		return transformed;
  	}
 -  public class MyInvoke extends OperatorProcessor
 -  {
 -
 -    public void process(PDFOperator operator, List arguments) throws IOException
 -    {
 -      COSName name = (COSName) arguments.get(0);
 -
 -      // PDResources res = context.getResources();
 -
 -      Map xobjects = context.getXObjects();
 -      PDXObject xobject = (PDXObject) xobjects.get(name.getName());
 -
 -      PDStream stream = xobject.getPDStream();
 -      COSStream cos_stream = stream.getStream();
 -
 -      COSName subtype = (COSName) cos_stream.getDictionaryObject(COSName.SUBTYPE);
 -      if (subtype.equals(COSName.IMAGE))
 -      {
 -        logger_.debug("XObject Image");
 -
 -        Matrix ctm = context.getGraphicsState().getCurrentTransformationMatrix();
 -        logger_.debug("ctm = " + ctm);
 -
 -        Pos [] coordinates = new Pos [] {
 -        new Pos(0, 0, 1),
 -        new Pos(1, 0, 1),
 -        new Pos(0, 1, 1),
 -        new Pos(1, 1, 1) };
 -
 -        Pos [] transformed_coordinates = transtormCoordinates(coordinates, ctm);
 -
 -        /**********************************************************
 -         * pdf-as fix:
 -         * calculating min and max point of an image to look where
 -         * the signature should be placed
 -         * fix solves problems with footer and images and
 -         * placement of the signature in an image only pdf document
 -         **********************************************************/
 -
 -        float actual_lowest_point = Float.NaN;
 -        float actual_starting_point = Float.NaN;
 -
 -        int pageRotation = page.findRotation();
 -        logger_.debug("PageRotation = " + pageRotation);
 -        if (pageRotation == 0)
 -        {
 -          float min_y = findMinY(transformed_coordinates);
 -          logger_.debug("min_y = " + min_y);
 -          float page_height = page.findMediaBox().getHeight();
 -          logger_.debug("page_height = " + page_height);
 -
 -          actual_lowest_point = page_height - min_y;
 -          actual_starting_point = page_height - findMaxY(transformed_coordinates);
 -        }
 -        if (pageRotation == 90)
 -        {
 -          float max_x = findMaxX(transformed_coordinates);
 -          logger_.debug("max_x = " + max_x);
 -          float page_width = page.findMediaBox().getWidth();
 -          logger_.debug("page_width = " + page_width);
 -
 -          actual_lowest_point = max_x;
 -          actual_starting_point = findMinX(transformed_coordinates);
 -        }
 -        if (pageRotation == 180)
 -        {
 -          float min_y = findMinY(transformed_coordinates);
 -          logger_.debug("min_y = " + min_y);
 -          float page_height = page.findMediaBox().getHeight();
 -          actual_lowest_point = page_height - findMaxY(transformed_coordinates);
 -          actual_starting_point = page_height - min_y;
 -        }
 -        if (pageRotation == 270)
 -        {
 -          float min_x = findMinX(transformed_coordinates);
 -          logger_.debug("min_x = " + min_x);
 -
 -          float page_width = page.findMediaBox().getWidth();
 -          logger_.debug("page_width = " + page_width);
 -
 -          actual_lowest_point = page_width - min_x;
 -          actual_starting_point = page_width - findMaxX(transformed_coordinates);
 -        }
 -
 -
 -        logger_.debug("actual_lowest_point = " + actual_lowest_point);
 -
 -        if (actual_lowest_point > PDFPage.this.effectivePageHeight && actual_starting_point > PDFPage.this.effectivePageHeight)
 -        {
 -          logger_.debug("image is below footer_line");
 -          return;
 -        }
 -
 -        if (actual_lowest_point > PDFPage.this.max_image_ypos)
 -        {
 -          PDFPage.this.max_image_ypos = actual_lowest_point;
 -        }
 -
 -        return;
 -      }
 -
 -      if (xobject instanceof PDXObjectForm)
 -      {
 -        PDXObjectForm form = (PDXObjectForm) xobject;
 -        COSStream invoke = (COSStream) form.getCOSObject();
 -        PDResources pdResources = form.getResources();
 -        PDPage page = context.getCurrentPage();
 -        if (pdResources == null)
 -        {
 -          pdResources = page.findResources();
 -        }
 -
 -        getContext().processSubStream(page, pdResources, invoke);
 -      }
 -    }
 -  }
 -
 -  public static Pos [] transtormCoordinates (Pos [] coordinates, Matrix m)
 -  {
 -    Pos [] transformed = new Pos [coordinates.length];
 -    for (int i = 0; i < coordinates.length; i++)
 -    {
 -      transformed[i] = transtormCoordinate(coordinates[i], m);
 -    }
 -    return transformed;
 -  }
 -
 -  public static Pos transtormCoordinate (Pos pos, Matrix m)
 -  {
 -    Pos transformed = new Pos();
 -    transformed.x = pos.x * m.getValue(0, 0) + pos.y * m.getValue(1, 0) + pos.z * m.getValue(2, 0);
 -    transformed.y = pos.x * m.getValue(0, 1) + pos.y * m.getValue(1, 1) + pos.z * m.getValue(2, 1);
 -    transformed.z = pos.x * m.getValue(0, 2) + pos.y * m.getValue(1, 2) + pos.z * m.getValue(2, 2);
 -
 -    logger_.debug(" transformed " + pos + " --> " + transformed);
 -    return transformed;
 -  }
 -
 -  public static float findMinY (Pos [] coordinates)
 -  {
 -    float min = Float.POSITIVE_INFINITY;
 -    for (int i = 0; i < coordinates.length; i++)
 -    {
 -      if (coordinates[i].y < min)
 -      {
 -        min = coordinates[i].y;
 -      }
 -    }
 -    return min;
 -  }
 +	public static float findMinY(Pos[] coordinates) {
 +		float min = Float.POSITIVE_INFINITY;
 +		for (int i = 0; i < coordinates.length; i++) {
 +			if (coordinates[i].y < min) {
 +				min = coordinates[i].y;
 +			}
 +		}
 +		return min;
 +	}
  	public static float findMaxY(Pos[] coordinates) {
  		float max = 0;
 @@ -495,29 +497,24 @@ public class PDFPage extends PDFTextStripper  		return max;
  	}
 -  public static float findMaxX (Pos [] coordinates)
 -  {
 -    float max = Float.NEGATIVE_INFINITY;
 -    for (int i = 0; i < coordinates.length; i++)
 -    {
 -      if (coordinates[i].x > max)
 -      {
 -        max = coordinates[i].x;
 -      }
 -    }
 -    return max;
 -  }
 -  public static float findMinX (Pos [] coordinates)
 -  {
 -    float min = Float.POSITIVE_INFINITY;
 -    for (int i = 0; i < coordinates.length; i++)
 -    {
 -      if (coordinates[i].x < min)
 -      {
 -        min = coordinates[i].x;
 -      }
 -    }
 -    return min;
 -  }
 +	public static float findMaxX(Pos[] coordinates) {
 +		float max = Float.NEGATIVE_INFINITY;
 +		for (int i = 0; i < coordinates.length; i++) {
 +			if (coordinates[i].x > max) {
 +				max = coordinates[i].x;
 +			}
 +		}
 +		return max;
 +	}
 +
 +	public static float findMinX(Pos[] coordinates) {
 +		float min = Float.POSITIVE_INFINITY;
 +		for (int i = 0; i < coordinates.length; i++) {
 +			if (coordinates[i].x < min) {
 +				min = coordinates[i].x;
 +			}
 +		}
 +		return min;
 +	}
  }
\ No newline at end of file | 
