Skip to content

Commit

Permalink
Fix highlight overlapping (#1098)
Browse files Browse the repository at this point in the history
This patch fixes highlight overlapping by removing rectangles that
overlap each other. It also changes the threshold of considering a line
to be a "full line" to be a percentage of the page size, which should
help fix some cases where the highlighting on the left or right side
does not form a straight vertical line. Fixes #951.
  • Loading branch information
ahmedre authored Mar 15, 2019
1 parent 94dc038 commit e015f9a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package com.quran.labs.androidquran.data;

import android.content.Context;
import androidx.annotation.Nullable;

import com.quran.labs.androidquran.di.ActivityScope;
import com.quran.labs.androidquran.util.QuranFileUtils;

import javax.inject.Inject;

import androidx.annotation.Nullable;

@ActivityScope
public class AyahInfoDatabaseProvider {
private final Context context;
Expand All @@ -31,4 +32,8 @@ public AyahInfoDatabaseHandler getAyahInfoHandler() {
}
return databaseHandler;
}

public int getPageWidth() {
return Integer.valueOf(widthParameter.substring(1));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import android.graphics.RectF;

import com.crashlytics.android.Crashlytics;
import com.quran.labs.androidquran.data.AyahInfoDatabaseHandler;
import com.quran.labs.androidquran.data.AyahInfoDatabaseProvider;
import com.quran.labs.androidquran.di.ActivityScope;
Expand All @@ -25,7 +24,7 @@

@ActivityScope
public class CoordinatesModel {
private static final int PIXEL_THRESHOLD = 10;
private static final float THRESHOLD_PERCENTAGE = 0.015f;

private final AyahInfoDatabaseProvider ayahInfoDatabaseProvider;

Expand All @@ -45,8 +44,7 @@ public Observable<PageCoordinates> getPageCoordinates(boolean wantPageBounds, In
.subscribeOn(Schedulers.computation());
}

public Observable<AyahCoordinates> getAyahCoordinates(
Integer... pages) {
public Observable<AyahCoordinates> getAyahCoordinates(Integer... pages) {
AyahInfoDatabaseHandler database = ayahInfoDatabaseProvider.getAyahInfoHandler();
if (database == null) {
return Observable.error(new NoSuchElementException("No AyahInfoDatabaseHandler found!"));
Expand All @@ -64,12 +62,14 @@ private AyahCoordinates normalizePageAyahs(AyahCoordinates ayahCoordinates) {
final Set<String> keys = original.keySet();
for (String key : keys) {
List<AyahBounds> normalBounds = original.get(key);
normalizedMap.put(key, normalizeAyahBounds(key, normalBounds));
if (normalBounds != null) {
normalizedMap.put(key, normalizeAyahBounds(normalBounds));
}
}
return new AyahCoordinates(ayahCoordinates.getPage(), normalizedMap);
}

private List<AyahBounds> normalizeAyahBounds(String key, List<AyahBounds> ayahBounds) {
private List<AyahBounds> normalizeAyahBounds(List<AyahBounds> ayahBounds) {
final int total = ayahBounds.size();
if (total < 2) {
return ayahBounds;
Expand All @@ -90,10 +90,40 @@ private List<AyahBounds> normalizeAyahBounds(String key, List<AyahBounds> ayahBo
if (topSize == 1) {
return bottom;
} else if (topSize + bottom.size() > 4) {
Crashlytics.log("current verse: " + key);
Crashlytics.logException(new IllegalStateException("Lines not properly joined for verse"));
result.addAll(top);
result.addAll(bottom);
// this happens when a verse spans 3 incomplete lines (i.e. starts towards the end of
// one line, takes one or more whole lines, and ends early on in the line). in this case,
// just remove the duplicates.

// add the first parts of top
for (int i = 0; i < topSize - 1; i++) {
result.add(top.get(i));
}

// resolve the middle part which may overlap with bottom
final AyahBounds lastTop = top.get(topSize - 1);
final AyahBounds firstBottom = bottom.get(0);
if (lastTop.equals(firstBottom)) {
// only add one if they're both the same
result.add(lastTop);
} else {
// if one contains the other, add the larger one
final RectF topRect = lastTop.getBounds();
final RectF bottomRect = firstBottom.getBounds();
if (topRect.contains(bottomRect)) {
result.add(lastTop);
} else if (bottomRect.contains(topRect)) {
result.add(firstBottom);
} else {
// otherwise add both
result.add(lastTop);
result.add(firstBottom);
}
}

// add everything except the first bottom entry
for (int i = 1, size = bottom.size(); i < size; i++) {
result.add(bottom.get(i));
}
return result;
} else {
// re-consolidate top and middle again, since middle may have changed
Expand All @@ -114,8 +144,11 @@ private List<AyahBounds> consolidate(AyahBounds top, AyahBounds bottom) {
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;
final int pageWidth = ayahInfoDatabaseProvider.getPageWidth();
int threshold = (int) (THRESHOLD_PERCENTAGE * pageWidth);

boolean firstIsFullLine = Math.abs(firstRect.right - lastRect.right) < threshold;
boolean secondIsFullLine = Math.abs(firstRect.left - lastRect.left) < threshold;
if (firstIsFullLine && secondIsFullLine) {
top.engulf(bottom);
return Collections.singletonList(top);
Expand All @@ -141,7 +174,7 @@ private List<AyahBounds> consolidate(AyahBounds top, AyahBounds bottom) {
if (lastRect.left < firstRect.right) {
RectF middleBounds = new RectF(lastRect.left,
/* top= */ firstRect.bottom,
firstRect.right,
Math.min(firstRect.right, lastRect.right),
/* bottom= */ lastRect.top);
middle = new AyahBounds(top.getLine(), top.getPosition(), middleBounds);
}
Expand Down

0 comments on commit e015f9a

Please sign in to comment.