org.jpedal.text.TextLines Maven / Gradle / Ivy
Show all versions of OpenViewerFX Show documentation
/*
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info: http://www.idrsolutions.com
* Help section for developers at http://www.idrsolutions.com/support/
*
* (C) Copyright 1997-2017 IDRsolutions and Contributors.
*
* This file is part of JPedal/JPDF2HTML5
*
@LICENSE@
*
* ---------------
* TextLines.java
* ---------------
*/
package org.jpedal.text;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.jpedal.objects.PdfData;
import org.jpedal.utils.LogWriter;
import org.jpedal.utils.repositories.generic.Vector_Rectangle_Int;
public class TextLines {
/**
* stores area of arrays in which text should be highlighted
*/
private Map> lineAreas = new HashMap>();
private Map> lineWritingMode = new HashMap>();
/**
* Highlight Areas stored here
*/
public Map areas = new HashMap();
/**
* Track if highlgiht localAreas has changed since last call to getHighlightedAreas(int)
*/
boolean hasHighlightAreasUpdated;
/**
* Highlights a section of lines that form a paragraph and
* returns the area that encloses all highlight localAreas.
*
* @param x Coord x value to begin looking for a paragraph
* @param y Coord y value to begin looking for a paragraph
* @param page Page number of page to look for a paragraph on
* @return int[] that contains x,y,w,h of all localAreas highlighted
*/
public int[] setFoundParagraphAsArray(final int x, final int y, final int page) {
final int[][] lines = getLineAreasAs2DArray(page);
if (lines != null) {
final int[] point = {x, y, 1, 1};
final int[] current = {0, 0, 0, 0};
boolean lineFound = false;
int selectedLine = 0;
for (int i = 0; i != lines.length; i++) {
if (intersects(lines[i], point)) {
selectedLine = i;
lineFound = true;
break;
}
}
if (lineFound) {
int left = lines[selectedLine][0];
int cx = lines[selectedLine][0] + (lines[selectedLine][2] / 2);
int right = lines[selectedLine][0] + lines[selectedLine][2];
int cy = lines[selectedLine][1] + (lines[selectedLine][3] / 2);
int h = lines[selectedLine][3];
current[0] = lines[selectedLine][0];
current[1] = lines[selectedLine][1];
current[2] = lines[selectedLine][2];
current[3] = lines[selectedLine][3];
boolean foundTop = true;
boolean foundBottom = true;
final Vector_Rectangle_Int selected = new Vector_Rectangle_Int(0);
selected.addElement(lines[selectedLine]);
while (foundTop) {
foundTop = false;
for (int i = 0; i != lines.length; i++) {
if (contains(left, cy + h, lines[i]) || contains(cx, cy + h, lines[i]) || contains(right, cy + h, lines[i])) {
selected.addElement(lines[i]);
foundTop = true;
cy = lines[i][1] + (lines[i][3] / 2);
h = lines[i][3];
if (current[0] > lines[i][0]) {
current[2] = (current[0] + current[2]) - lines[i][0];
current[0] = lines[i][0];
}
if ((current[0] + current[2]) < (lines[i][0] + lines[i][2])) {
current[2] = (lines[i][0] + lines[i][2]) - current[0];
}
if (current[1] > lines[i][1]) {
current[3] = (current[1] + current[3]) - lines[i][1];
current[1] = lines[i][1];
}
if ((current[1] + current[3]) < (lines[i][1] + lines[i][3])) {
current[3] = (lines[i][1] + lines[i][3]) - current[1];
}
break;
}
}
}
//Return to selected item else we have duplicate highlights
left = lines[selectedLine][0];
cx = lines[selectedLine][0] + (lines[selectedLine][2] / 2);
right = lines[selectedLine][0] + lines[selectedLine][2];
cy = lines[selectedLine][1] + (lines[selectedLine][3] / 2);
h = lines[selectedLine][3];
while (foundBottom) {
foundBottom = false;
for (int i = 0; i != lines.length; i++) {
if (contains(left, cy - h, lines[i]) || contains(cx, cy - h, lines[i]) || contains(right, cy - h, lines[i])) {
selected.addElement(lines[i]);
foundBottom = true;
cy = lines[i][1] + (lines[i][3] / 2);
h = lines[i][3];
if (current[0] > lines[i][0]) {
current[2] = (current[0] + current[2]) - lines[i][0];
current[0] = lines[i][0];
}
if ((current[0] + current[2]) < (lines[i][0] + lines[i][2])) {
current[2] = (lines[i][0] + lines[i][2]) - current[0];
}
if (current[1] > lines[i][1]) {
current[3] = (current[1] + current[3]) - lines[i][1];
current[1] = lines[i][1];
}
if ((current[1] + current[3]) < (lines[i][1] + lines[i][3])) {
current[3] = (lines[i][1] + lines[i][3]) - current[1];
}
break;
}
}
}
selected.trim();
addHighlights(selected.get(), true, page);
return current;
}
return null;
}
return null;
}
public void addToLineAreas(final int[] area, final int writingMode, final int page) {
boolean addNew = true;
if (lineAreas == null) { //If null, create array
lineAreas = new HashMap>();
lineWritingMode = new HashMap>();
}
ArrayList lastAreas = lineAreas.get(page);
ArrayList lastWritingMode = (lineWritingMode.get(page));
//Check for objects close to or intersecting each other
if (area != null) { //Ensure actual area is selected
if (lastAreas != null) {
int cx;
int cy;
int cw;
int ch;
//int cm = cy+(ch/2);
int lx;
int ly;
int lw;
int lh;
for (int i = 0; i != lastAreas.size(); i++) {
final int[] lastArea = lastAreas.get(i);
final int lwm = lastWritingMode.get(i);
cx = area[0];
cy = area[1];
cw = area[2];
ch = area[3];
//int cm = cy+(ch/2);
lx = lastArea[0];
ly = lastArea[1];
lw = lastArea[2];
lh = lastArea[3];
//int lm = ly+(lh/2);
final int currentBaseLine;
final int lastBaseLine;
final float heightMod = 5f;
final float widthMod = 1.1f;
switch (writingMode) {
case PdfData.HORIZONTAL_LEFT_TO_RIGHT:
if (lwm == writingMode && ((ly > (cy - (ch / heightMod))) && (ly < (cy + (ch / heightMod)))) && //Ensure this is actually the same line and are about the same size
(((lh < ch + (ch / heightMod) && lh > ch - (ch / heightMod))) && //Check text is the same height
(((lx > (cx + cw - (ch * widthMod))) && (lx < (cx + cw + (ch * widthMod)))) || //Check for object at end of this object
((lx + lw > (cx - (ch * widthMod))) && (lx + lw < (cx + (ch * widthMod)))) || //Check for object at start of this object
intersects(lastArea, area)))//Check to see if it intersects at all
) {
addNew = false;
//No need to reset the writing mode as already set
lastAreas.set(i, mergePartLines(lastArea, area));
}
break;
case PdfData.HORIZONTAL_RIGHT_TO_LEFT:
lx = lastArea[0];
ly = lastArea[1];
lw = lastArea[2];
lh = lastArea[3];
cx = area[0];
cy = area[1];
cw = area[2];
ch = area[3];
if (lwm == writingMode && ((ly > (cy - 5)) && (ly < (cy + 5)) && lh <= (ch + (ch / 5)) && lh >= (ch - (ch / 5))) && //Ensure this is actually the same line and are about the same size
(((lx > (cx + cw - (ch * 0.6))) && (lx < (cx + cw + (ch * 0.6)))) || //Check for object at end of this object
((lx + lw > (cx - (ch * 0.6))) && (lx + lw < (cx + (ch * 0.6)))) || //Check for object at start of this object
intersects(lastArea, area))//Check to see if it intersects at all
) {
addNew = false;
//No need to reset the writing mode as already set
lastAreas.set(i, mergePartLines(lastArea, area));
}
break;
case PdfData.VERTICAL_TOP_TO_BOTTOM:
lx = lastArea[1];
ly = lastArea[0];
lw = lastArea[3];
lh = lastArea[2];
cx = area[1];
cy = area[0];
cw = area[3];
ch = area[2];
if (lwm == writingMode && ((ly > (cy - 5)) && (ly < (cy + 5)) && lh <= (ch + (ch / 5)) && lh >= (ch - (ch / 5))) && //Ensure this is actually the same line and are about the same size
(((lx > (cx + cw - (ch * 0.6))) && (lx < (cx + cw + (ch * 0.6)))) || //Check for object at end of this object
((lx + lw > (cx - (ch * 0.6))) && (lx + lw < (cx + (ch * 0.6)))) || //Check for object at start of this object
intersects(lastArea, area))//Check to see if it intersects at all
) {
addNew = false;
//No need to reset the writing mode as already set
lastAreas.set(i, mergePartLines(lastArea, area));
}
break;
case PdfData.VERTICAL_BOTTOM_TO_TOP:
//Calculate the coord value at the bottom of the text
currentBaseLine = cx + cw;
lastBaseLine = lx + lw;
if (lwm == writingMode //Check the current writing mode
&& (currentBaseLine >= (lastBaseLine - (lw / 3))) && (currentBaseLine <= (lastBaseLine + (lw / 3))) //Check is same line
&& //Only check left or right if the same line is shared
((//Check for text on either side
((ly + (lh + (lw * 0.6)) > cy) && (ly + (lh - (lw * 0.6)) < cy))// Check for text to left of current area
|| ((ly + (lw * 0.6) > (cy + ch)) && (ly - (lw * 0.6) < (cy + ch)))// Check for text to right of current area
)
|| intersects(area, lastArea))) {
addNew = false;
//No need to reset the writing mode as already set
lastAreas.set(i, mergePartLines(lastArea, area));
}
break;
}
}
} else {
lastAreas = new ArrayList();
lineAreas.put(page, lastAreas);
lastWritingMode = new ArrayList();
lineWritingMode.put(page, lastWritingMode);
addNew = true;
}
//If no object near enough to merge, start a new area
if (addNew) {
lastAreas.add(area);
lastWritingMode.add(writingMode);
}
}
}
/**
* remove zone on page for text localAreas if present
*
* @param rectArea Text area to remove
* @param page Page to check for these localAreas
*/
public void removeFoundTextArea(final int[] rectArea, final int page) {
//clearHighlights();
if (rectArea == null || areas == null) {
return;
}
final Integer p = page;
final int[][] localAreas = this.areas.get(p);
if (localAreas != null) {
final int size = localAreas.length;
for (int i = 0; i < size; i++) {
if (localAreas[i] != null && (contains(rectArea[0], rectArea[1], localAreas[i]) || (localAreas[i][0] == rectArea[0] && localAreas[i][1] == rectArea[1] && localAreas[i][2] == rectArea[2] &&
localAreas[i][3] == rectArea[3]))) {
localAreas[i] = null;
i = size;
}
}
this.areas.put(p, localAreas);
//Flag that highlights have changed
hasHighlightAreasUpdated = true;
}
}
/**
* remove highlight zones on page for text localAreas on single pages null value will totally reset
*
* @param rectArea Text localAreas to remove
* @param page Page to check for these localAreas
*/
public void removeFoundTextAreas(final int[][] rectArea, final int page) {
if (rectArea == null) {
areas = null;
} else {
for (final int[] aRectArea : rectArea) {
removeFoundTextArea(aRectArea, page);
}
boolean allNull = true;
final Integer p = page;
int[][] localAreas = this.areas.get(p);
if (localAreas != null) {
for (int ii = 0; ii < localAreas.length; ii++) {
if (localAreas[ii] != null) {
allNull = false;
ii = localAreas.length;
}
}
if (allNull) {
localAreas = null;
this.areas.put(p, localAreas);
//Flag that highlights have changed
hasHighlightAreasUpdated = true;
}
}
}
}
/**
* Clear all highlights that are being displayed
*/
public void clearHighlights() {
areas = null;
//Flag that highlights have changed
hasHighlightAreasUpdated = true;
}
/**
* Method to highlight text on page.
*
* If areaSelect = true then the Rectangle array will be highlgihted on screen unmodified.
* areaSelect should be true if being when used with values returned from the search as these localAreas
* are already corrected and modified for display.
*
* If areaSelect = false then all lines between the top left point and bottom right point
* will be selected including two partial lines the top line starting from the top left point of the rectangle
* and the bottom line ending at the bottom right point of the rectangle.
*
* @param highlights :: The 2DArray contains the raw x,y,w,h params of a set of rectangles that you wish to have highlighted
* @param areaSelect :: The flag that will either select text as line between points if false or characters within an area if true.
* @param page :: The page to add highlights to.
*/
public void addHighlights(final int[][] highlights, final boolean areaSelect, final int page) {
if (highlights != null) { //If null do nothing to clear use the clear method
//Flag that highlights have changed
hasHighlightAreasUpdated = true;
for (int j = 0; j != highlights.length; j++) {
final int[][] values = getHighlightableInArea(highlights[j], areaSelect, page);
if (values != null) {
this.areas.put(page, values);
}
}
}
}
public int[][] getHighlightableInArea(final int[] highlights, final boolean areaSelect, final int page) {
if (!areaSelect) {
if (highlights != null) {
//Ensure that the points are adjusted so that they are within line area if that is sent as rectangle
int[] startPoint = {highlights[0] + 1, highlights[1] + 1};
int[] endPoint = {highlights[0] + highlights[2] - 1, highlights[1] + highlights[3] - 1};
//both null flushes localAreas
if (areas == null) {
areas = new HashMap();
}
final int[][] lines = getLineAreasAs2DArray(page);
final int[] writingMode = this.getLineWritingMode(page);
int start = -1;
int finish = -1;
boolean backward = false;
//Find the first selected line and the last selected line.
if (lines != null) {
for (int i = 0; i != lines.length; i++) {
if (contains(startPoint[0], startPoint[1], lines[i])) {
start = i;
}
if (contains(endPoint[0], endPoint[1], lines[i])) {
finish = i;
}
if (start != -1 && finish != -1) {
break;
}
}
if (start > finish) {
final int temp = start;
start = finish;
finish = temp;
backward = true;
}
if (start == finish) {
if (startPoint[0] > endPoint[0]) {
final int[] temp = startPoint;
startPoint = endPoint;
endPoint = temp;
}
}
if (start != -1 && finish != -1) {
//Fill in all the lines between
final int[][] localAreas = new int[finish - start + 1][4];
System.arraycopy(lines, start + 0, localAreas, 0, finish - start + 1);
if (localAreas.length > 0) {
final int top = 0;
final int bottom = localAreas.length - 1;
if (localAreas[top] != null && localAreas[bottom] != null) {
switch (writingMode[start]) {
case PdfData.HORIZONTAL_LEFT_TO_RIGHT:
// if going backwards
if (backward) {
if ((endPoint[0] - 15) <= localAreas[top][0]) {
//Do nothing to localAreas as we want to pick up the start of a line
} else {
localAreas[top][2] -= (endPoint[0] - localAreas[top][0]);
localAreas[top][0] = endPoint[0];
}
} else {
if ((startPoint[0] - 15) <= localAreas[top][0]) {
//Do nothing to localAreas as we want to pick up the start of a line
} else {
localAreas[top][2] -= (startPoint[0] - localAreas[top][0]);
localAreas[top][0] = startPoint[0];
}
}
break;
case PdfData.HORIZONTAL_RIGHT_TO_LEFT:
LogWriter.writeLog("THIS TEXT DIRECTION HAS NOT BEEN IMPLEMENTED YET (Right to Left)");
break;
case PdfData.VERTICAL_TOP_TO_BOTTOM:
if (backward) {
if ((endPoint[1] - 15) <= localAreas[top][1]) {
//Do nothing to localAreas as we want to pick up the start of a line
} else {
localAreas[top][3] -= (endPoint[1] - localAreas[top][1]);
localAreas[top][1] = endPoint[1];
}
} else {
if ((startPoint[1] - 15) <= localAreas[top][1]) {
//Do nothing to localAreas as we want to pick up the start of a line
} else {
localAreas[top][3] -= (startPoint[1] - localAreas[top][1]);
localAreas[top][1] = startPoint[1];
}
}
break;
case PdfData.VERTICAL_BOTTOM_TO_TOP:
if (backward) {
if ((endPoint[1] - 15) <= localAreas[top][1]) {
//Do nothing to localAreas as we want to pick up the start of a line
} else {
localAreas[top][3] -= (endPoint[1] - localAreas[top][1]);
localAreas[top][1] = endPoint[1];
}
} else {
if ((startPoint[1] - 15) <= localAreas[top][1]) {
//Do nothing to localAreas as we want to pick up the start of a line
} else {
localAreas[top][3] -= (startPoint[1] - localAreas[top][1]);
localAreas[top][1] = startPoint[1];
}
}
break;
}
switch (writingMode[finish]) {
case PdfData.HORIZONTAL_LEFT_TO_RIGHT:
// if going backwards
if (backward) {
if ((startPoint[0] + 15) >= localAreas[bottom][0] + localAreas[bottom][2]) {
//Do nothing to localAreas as we want to pick up the end of a line
} else {
localAreas[bottom][2] = startPoint[0] - localAreas[bottom][0];
}
} else {
if ((endPoint[0] + 15) >= localAreas[bottom][0] + localAreas[bottom][2]) {
//Do nothing to localAreas as we want to pick up the end of a line
} else {
localAreas[bottom][2] = endPoint[0] - localAreas[bottom][0];
}
}
break;
case PdfData.HORIZONTAL_RIGHT_TO_LEFT:
LogWriter.writeLog("THIS TEXT DIRECTION HAS NOT BEEN IMPLEMENTED YET (Right to Left)");
break;
case PdfData.VERTICAL_TOP_TO_BOTTOM:
// if going backwards
if (backward) {
if ((startPoint[1] + 15) >= localAreas[bottom][1] + localAreas[bottom][3]) {
//Do nothing to localAreas as we want to pick up the end of a line
} else {
localAreas[bottom][3] = startPoint[1] - localAreas[bottom][1];
}
} else {
if ((endPoint[1] + 15) >= localAreas[bottom][1] + localAreas[bottom][3]) {
//Do nothing to localAreas as we want to pick up the end of a line
} else {
localAreas[bottom][3] = endPoint[1] - localAreas[bottom][1];
}
}
break;
case PdfData.VERTICAL_BOTTOM_TO_TOP:
// if going backwards
if (backward) {
if ((startPoint[1] + 15) >= localAreas[bottom][1] + localAreas[bottom][3]) {
//Do nothing to localAreas as we want to pick up the end of a line
} else {
localAreas[bottom][3] = startPoint[1] - localAreas[bottom][1];
}
} else {
if ((endPoint[1] + 15) >= localAreas[bottom][1] + localAreas[bottom][3]) {
//Do nothing to localAreas as we want to pick up the end of a line
} else {
localAreas[bottom][3] = endPoint[1] - localAreas[bottom][1];
}
}
break;
}
}
}
return localAreas;
}
}
}
} else {
//if inset add in difference transparently
if (highlights != null) {
if (highlights[2] < 0) {
highlights[2] = -highlights[2];
highlights[0] -= highlights[2];
}
if (highlights[3] < 0) {
highlights[3] = -highlights[3];
highlights[1] -= highlights[3];
}
if (areas != null) {
final Integer p = page;
int[][] localAreas = this.areas.get(p);
if (localAreas != null) {
boolean matchFound = false;
//see if already added
final int size = localAreas.length;
for (int i = 0; i < size; i++) {
if (localAreas[i] != null) {
//If area has been added before please ignore
if (localAreas[i] != null && (localAreas[i][0] == highlights[0] && localAreas[i][1] == highlights[1] && localAreas[i][2] == highlights[2]
&& localAreas[i][3] == highlights[3])) {
matchFound = true;
i = size;
}
}
}
if (!matchFound) {
final int newSize = localAreas.length + 1;
final int[][] newAreas = new int[newSize][4];
for (int i = 0; i < localAreas.length; i++) {
if (localAreas[i] != null) {
newAreas[i] = new int[]{localAreas[i][0], localAreas[i][1], localAreas[i][2], localAreas[i][3]};
}
}
localAreas = newAreas;
localAreas[localAreas.length - 1] = highlights;
}
return localAreas;
} else {
return new int[][]{highlights};
}
} else {
areas = new HashMap();
final int[][] localAreas = new int[1][4];
localAreas[0] = highlights;
return localAreas;
}
}
}
return null;
}
public boolean hasHighlightAreasUpdated() {
return hasHighlightAreasUpdated;
}
/**
* Get all the highlights currently stored. The returned Map
* using the page numbers as the keys for the values.
*
* @return A Map containing all highlights currently stored.
*/
public Map getAllHighlights() {
hasHighlightAreasUpdated = false;
if (areas == null) {
return null;
} else {
return Collections.unmodifiableMap(areas);
}
}
/**
* Creates a two-dimensional int array containing x,y,width and height
* values for each rectangle that is stored in the localAreas map,
* which allows us to create a swing/fx rectangle on these values.
*
* @param page of type int.
* @return an int[][] Containing x,y,w,h of Highlights on Page.
*/
public int[][] getHighlightedAreasAs2DArray(final int page) {
if (areas == null) {
return null;
} else {
final Integer p = page;
final int[][] localAreas = this.areas.get(p);
if (localAreas != null) {
final int count = localAreas.length;
final int[][] returnValue = new int[count][4];
for (int ii = 0; ii < count; ii++) {
if (localAreas[ii] == null) {
returnValue[ii] = null;
} else {
returnValue[ii] = new int[]{localAreas[ii][0], localAreas[ii][1],
localAreas[ii][2], localAreas[ii][3]};
}
}
//Reset flag as localAreas has been retrieved
hasHighlightAreasUpdated = false;
return returnValue;
} else {
return null;
}
}
}
public void setLineAreas(final Map la) {
if (la == null || la.keySet().isEmpty()) {
lineAreas = null;
} else {
final Set keys = la.keySet();
for (final int i : keys) {
final int[][] values = la.get(i);
final ArrayList list = new ArrayList(Arrays.asList(values));
lineAreas.put(i, list);
}
}
}
@SuppressWarnings("UnusedDeclaration")
public void setLineWritingMode(final Map lineOrientation) {
if (lineOrientation == null || lineOrientation.keySet().isEmpty()) {
lineWritingMode = null;
} else {
final Set keys = lineOrientation.keySet();
for (final int i : keys) {
final int[] values = lineOrientation.get(i);
final ArrayList list = new ArrayList();
for (final int ii : values) {
list.add(ii);
}
lineWritingMode.put(i, list);
}
}
}
/**
* Creates a two-dimensional int array containing x,y,width and height
* values for each rectangle that is stored in the localLineAreas map,
* which allows us to create a swing/fx rectangle on these values.
*
* @param page of type int.
* @return an int[][] Containing x,y,w,h of line localAreas on Page.
*/
public int[][] getLineAreasAs2DArray(final int page) {
if (lineAreas == null || lineAreas.get(page) == null) {
return null;
} else {
final ArrayList localLineAreas = this.lineAreas.get(page);
if (localLineAreas == null) {
return null;
}
final int count = localLineAreas.size();
final int[][] returnValue = new int[count][4];
for (int ii = 0; ii < count; ii++) {
if (localLineAreas.get(ii) == null) {
returnValue[ii] = null;
} else {
returnValue[ii] = new int[]{localLineAreas.get(ii)[0], localLineAreas.get(ii)[1],
localLineAreas.get(ii)[2], localLineAreas.get(ii)[3]};
}
}
return returnValue;
}
}
public int[] getLineWritingMode(final int page) {
if (lineWritingMode == null) {
return null;
} else {
final ArrayList localLineWritingMode = (this.lineWritingMode.get(page));
if (localLineWritingMode == null) {
return null;
}
final int count = localLineWritingMode.size();
final int[] returnValue = new int[count];
for (int i = 0; i != count; i++) {
returnValue[i] = localLineWritingMode.get(i);
}
return returnValue;
}
}
private static int[] mergePartLines(final int[] lastArea, final int[] area) {
/*
* Check coords from both areas and merge them to make
* a single larger area containing contents of both
*/
final int x1 = area[0];
final int x2 = area[0] + area[2];
final int y1 = area[1];
final int y2 = area[1] + area[3];
final int lx1 = lastArea[0];
final int lx2 = lastArea[0] + lastArea[2];
final int ly1 = lastArea[1];
final int ly2 = lastArea[1] + lastArea[3];
//Ensure the highest and lowest values are selected
if (x1 < lx1) {
area[0] = x1;
} else {
area[0] = lx1;
}
if (y1 < ly1) {
area[1] = y1;
} else {
area[1] = ly1;
}
if (y2 > ly2) {
area[3] = y2 - area[1];
} else {
area[3] = ly2 - area[1];
}
if (x2 > lx2) {
area[2] = x2 - area[0];
} else {
area[2] = lx2 - area[0];
}
return area;
}
/**
* Checks whether two rectangles intersect
* Takes the raw x,y,w,h data of the rectangles in array form.
*
* @param paramsOne
* @param paramsTwo
* @return boolean
*/
public static boolean intersects(final int[] paramsOne, final int[] paramsTwo) {
final int X1 = paramsOne[0];
final int Y1 = paramsOne[1];
final int W1 = paramsOne[2];
final int H1 = paramsOne[3];
final int X2 = paramsTwo[0];
final int Y2 = paramsTwo[1];
final int W2 = paramsTwo[2];
final int H2 = paramsTwo[3];
return !(X1 + W1 < X2 || X2 + W2 < X1 || Y1 + H1 < Y2 || Y2 + H2 < Y1);
}
/**
* Checks whether a point at (x,y) lies within the
* bounds of an unrotated rectangles raw x,y,w,h values.
*
* @return
*/
private static boolean contains(final int x, final int y, final int[] rectParams) {
final int minX = rectParams[0]; //x
final int minY = rectParams[1]; //y
final int maxX = rectParams[0] + rectParams[2]; //x + width
final int maxY = rectParams[1] + rectParams[3]; //y + height
return (x >= minX && x <= maxX) && (y >= minY && y <= maxY);
}
}