use of com.quran.labs.androidquran.common.AyahBounds in project quran_android by quran.
the class ImageAyahUtils method getToolBarPosition.
public static AyahToolBar.AyahToolBarPosition getToolBarPosition(@NonNull List<AyahBounds> bounds, @NonNull Matrix matrix, int screenWidth, int screenHeight, int toolBarWidth, int toolBarHeight) {
boolean isToolBarUnderAyah = false;
AyahToolBar.AyahToolBarPosition result = null;
final int size = bounds.size();
RectF chosenRect;
if (size > 0) {
RectF firstRect = new RectF();
AyahBounds chosen = bounds.get(0);
matrix.mapRect(firstRect, chosen.getBounds());
chosenRect = new RectF(firstRect);
float y = firstRect.top - toolBarHeight;
if (y < toolBarHeight) {
// too close to the top, let's move to the bottom
chosen = bounds.get(size - 1);
matrix.mapRect(chosenRect, chosen.getBounds());
y = chosenRect.bottom;
if (y > (screenHeight - toolBarHeight)) {
y = firstRect.bottom;
chosenRect = firstRect;
}
isToolBarUnderAyah = true;
}
final float midpoint = chosenRect.centerX();
float x = midpoint - (toolBarWidth / 2);
if (x < 0 || x + toolBarWidth > screenWidth) {
x = chosenRect.left;
if (x + toolBarWidth > screenWidth) {
x = screenWidth - toolBarWidth;
}
}
result = new AyahToolBar.AyahToolBarPosition();
result.x = x;
result.y = y;
result.pipOffset = midpoint - x;
result.pipPosition = isToolBarUnderAyah ? AyahToolBar.PipPosition.UP : AyahToolBar.PipPosition.DOWN;
}
return result;
}
use of com.quran.labs.androidquran.common.AyahBounds in project quran_android by quran.
the class HighlightingImageView method onDraw.
@Override
protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
final Drawable d = getDrawable();
if (d == null) {
// no image, forget it.
return;
}
final Matrix matrix = getImageMatrix();
// Draw overlay text
didDraw = false;
if (overlayParams != null) {
overlayText(canvas, matrix);
}
// Draw each ayah highlight
if (coordinatesData != null && !currentHighlights.isEmpty()) {
alreadyHighlighted.clear();
for (Map.Entry<HighlightType, Set<String>> entry : currentHighlights.entrySet()) {
Paint paint = getPaintForHighlightType(entry.getKey());
for (String ayah : entry.getValue()) {
if (alreadyHighlighted.contains(ayah))
continue;
List<AyahBounds> rangesToDraw = coordinatesData.get(ayah);
if (rangesToDraw != null && !rangesToDraw.isEmpty()) {
for (AyahBounds b : rangesToDraw) {
matrix.mapRect(scaledRect, b.getBounds());
scaledRect.offset(0, getPaddingTop());
canvas.drawRect(scaledRect, paint);
}
alreadyHighlighted.add(ayah);
}
}
}
}
}
use of com.quran.labs.androidquran.common.AyahBounds in project quran_android by quran.
the class CoordinatesModel method consolidate.
private List<AyahBounds> consolidate(AyahBounds top, AyahBounds bottom) {
final RectF firstRect = top.getBounds();
final RectF lastRect = bottom.getBounds();
AyahBounds middle = null;
// only 2 lines - let's see if any of them are full lines
boolean firstIsFullLine = Math.abs(firstRect.right - lastRect.right) < PIXEL_THRESHOLD;
boolean secondIsFullLine = Math.abs(firstRect.left - lastRect.left) < PIXEL_THRESHOLD;
if (firstIsFullLine && secondIsFullLine) {
top.engulf(bottom);
return Collections.singletonList(top);
} else if (firstIsFullLine) {
lastRect.top = firstRect.bottom;
float bestStartOfLine = Math.max(firstRect.right, lastRect.right);
firstRect.right = bestStartOfLine;
lastRect.right = bestStartOfLine;
top = top.withBounds(firstRect);
bottom = bottom.withBounds(lastRect);
} else if (secondIsFullLine) {
firstRect.bottom = lastRect.top;
float bestEndOfLine = Math.min(firstRect.left, lastRect.left);
firstRect.left = bestEndOfLine;
lastRect.left = bestEndOfLine;
top = top.withBounds(firstRect);
bottom = bottom.withBounds(lastRect);
} else {
// anything in common (i.e. any part of them intersects)
if (lastRect.left < firstRect.right) {
RectF middleBounds = new RectF(lastRect.left, /* top= */
firstRect.bottom, firstRect.right, /* bottom= */
lastRect.top);
middle = new AyahBounds(top.getLine(), top.getPosition(), middleBounds);
}
}
List<AyahBounds> result = new ArrayList<>();
result.add(top);
if (middle != null) {
result.add(middle);
}
result.add(bottom);
return result;
}
use of com.quran.labs.androidquran.common.AyahBounds in project quran_android by quran.
the class ImageAyahUtils method getYBoundsForHighlight.
public static RectF getYBoundsForHighlight(Map<String, List<AyahBounds>> coordinateData, int sura, int ayah) {
final List<AyahBounds> ayahBounds = coordinateData.get(sura + ":" + ayah);
if (ayahBounds == null) {
return null;
}
RectF ayahBoundsRect = null;
for (AyahBounds bounds : ayahBounds) {
if (ayahBoundsRect == null) {
ayahBoundsRect = bounds.getBounds();
} else {
ayahBoundsRect.union(bounds.getBounds());
}
}
return ayahBoundsRect;
}
use of com.quran.labs.androidquran.common.AyahBounds in project quran_android by quran.
the class ImageAyahUtils method getAyahFromCoordinates.
public static SuraAyah getAyahFromCoordinates(Map<String, List<AyahBounds>> coords, HighlightingImageView imageView, float xc, float yc) {
if (coords == null || imageView == null) {
return null;
}
float[] pageXY = getPageXY(xc, yc, imageView);
if (pageXY == null) {
return null;
}
float x = pageXY[0];
float y = pageXY[1];
int closestLine = -1;
int closestDelta = -1;
final SparseArray<List<String>> lineAyahs = new SparseArray<>();
final Set<String> keys = coords.keySet();
for (String key : keys) {
List<AyahBounds> bounds = coords.get(key);
if (bounds == null) {
continue;
}
for (AyahBounds b : bounds) {
// only one AyahBound will exist for an ayah on a particular line
int line = b.getLine();
List<String> items = lineAyahs.get(line);
if (items == null) {
items = new ArrayList<>();
}
items.add(key);
lineAyahs.put(line, items);
final RectF boundsRect = b.getBounds();
if (boundsRect.contains(x, y)) {
return getAyahFromKey(key);
}
int delta = Math.min((int) Math.abs(boundsRect.bottom - y), (int) Math.abs(boundsRect.top - y));
if (closestDelta == -1 || delta < closestDelta) {
closestLine = b.getLine();
closestDelta = delta;
}
}
}
if (closestLine > -1) {
int leastDeltaX = -1;
String closestAyah = null;
List<String> ayat = lineAyahs.get(closestLine);
if (ayat != null) {
Timber.d("no exact match, %d candidates.", ayat.size());
for (String ayah : ayat) {
List<AyahBounds> bounds = coords.get(ayah);
if (bounds == null) {
continue;
}
for (AyahBounds b : bounds) {
if (b.getLine() > closestLine) {
// this is the last ayah in ayat list
break;
}
final RectF boundsRect = b.getBounds();
if (b.getLine() == closestLine) {
// if x is within the x of this ayah, that's our answer
if (boundsRect.right >= x && boundsRect.left <= x) {
return getAyahFromKey(ayah);
}
// otherwise, keep track of the least delta and return it
int delta = Math.min((int) Math.abs(boundsRect.right - x), (int) Math.abs(boundsRect.left - x));
if (leastDeltaX == -1 || delta < leastDeltaX) {
closestAyah = ayah;
leastDeltaX = delta;
}
}
}
}
}
if (closestAyah != null) {
Timber.d("fell back to closest ayah of %s", closestAyah);
return getAyahFromKey(closestAyah);
}
}
return null;
}
Aggregations