From b84a11abc97142903a6e0a38224ced6b4739bcb4 Mon Sep 17 00:00:00 2001 From: Nikolay Pultsin Date: Thu, 7 Apr 2011 01:30:55 +0100 Subject: [PATCH] view paint refactoring --- .../fbreader/fbreader/FBView.java | 20 ++-- .../fbreader/fbreader/TurnPageAction.java | 38 +++----- .../fbreader/VolumeKeyTurnPageAction.java | 18 ++-- .../core/application/ZLApplication.java | 13 +-- .../core/application/ZLApplicationWindow.java | 2 +- .../zlibrary/core/view/ZLView.java | 24 ++++- .../zlibrary/text/view/ZLTextView.java | 8 ++ .../ZLAndroidApplicationWindow.java | 14 +-- .../ui/android/view/AnimationProvider.java | 20 ++-- .../ui/android/view/BitmapManager.java | 97 +++++++++++++++++++ .../android/view/CurlAnimationProvider.java | 10 +- .../android/view/NoneAnimationProvider.java | 17 +++- .../android/view/ShiftAnimationProvider.java | 16 +-- .../android/view/SimpleAnimationProvider.java | 6 +- .../android/view/SlideAnimationProvider.java | 14 +-- .../ui/android/view/ZLAndroidWidget.java | 86 ++++------------ 16 files changed, 241 insertions(+), 162 deletions(-) create mode 100644 src/org/geometerplus/zlibrary/ui/android/view/BitmapManager.java diff --git a/src/org/geometerplus/fbreader/fbreader/FBView.java b/src/org/geometerplus/fbreader/fbreader/FBView.java index 67b506bad..c62b417b7 100644 --- a/src/org/geometerplus/fbreader/fbreader/FBView.java +++ b/src/org/geometerplus/fbreader/fbreader/FBView.java @@ -93,6 +93,7 @@ public final class FBView extends ZLTextView { final ZLTextElementRegion region = findRegion(x, y, 10, ZLTextElementRegion.HyperlinkFilter); if (region != null) { selectRegion(region); + myReader.resetView(); myReader.repaintView(); myReader.doAction(ActionCode.PROCESS_HYPERLINK); return true; @@ -183,7 +184,7 @@ public final class FBView extends ZLTextView { final boolean horizontal = ScrollingPreferences.Instance().HorizontalOption.getValue(); final int diff = horizontal ? x - myStartX : y - myStartY; final Direction direction = horizontal ? Direction.rightToLeft : Direction.up; - if (diff > 0) { + if (diff >= 0) { final ZLTextWordCursor cursor = getStartCursor(); if (cursor == null || cursor.isNull()) { return false; @@ -191,7 +192,7 @@ public final class FBView extends ZLTextView { if (!cursor.isStartOfParagraph() || !cursor.getParagraphCursor().isFirst()) { myReader.scrollViewManually(myStartX, myStartY, x, y, direction); } - } else if (diff < 0) { + } else { final ZLTextWordCursor cursor = getEndCursor(); if (cursor == null || cursor.isNull()) { return false; @@ -199,8 +200,6 @@ public final class FBView extends ZLTextView { if (!cursor.isEndOfParagraph() || !cursor.getParagraphCursor().isLast()) { myReader.scrollViewManually(myStartX, myStartY, x, y, direction); } - } else { - myReader.scrollViewToCenter(); } return true; } @@ -243,14 +242,7 @@ public final class FBView extends ZLTextView { Math.abs(diff) < minDiff ? PageIndex.current : (diff < 0 ? PageIndex.next : PageIndex.previous); - if (getAnimationType() != Animation.none) { - startAutoScrolling(pageIndex, horizontal ? Direction.rightToLeft : Direction.up, ScrollingPreferences.Instance().AnimationSpeedOption.getValue()); - } else { - myReader.scrollViewToCenter(); - onScrollingFinished(pageIndex); - myReader.repaintView(); - setScrollingActive(false); - } + startAutoScrolling(pageIndex, horizontal ? Direction.rightToLeft : Direction.up, ScrollingPreferences.Instance().AnimationSpeedOption.getValue()); } return true; } @@ -268,6 +260,7 @@ public final class FBView extends ZLTextView { final ZLTextElementRegion region = findRegion(x, y, 10, ZLTextElementRegion.AnyRegionFilter); if (region != null) { selectRegion(region); + myReader.resetView(); myReader.repaintView(); return true; } @@ -286,6 +279,7 @@ public final class FBView extends ZLTextView { final ZLTextElementRegion region = findRegion(x, y, 10, ZLTextElementRegion.AnyRegionFilter); if (region != null) { selectRegion(region); + myReader.resetView(); myReader.repaintView(); } } @@ -330,6 +324,7 @@ public final class FBView extends ZLTextView { } } + myReader.resetView(); myReader.repaintView(); return true; @@ -562,6 +557,7 @@ public final class FBView extends ZLTextView { } else { gotoPage(page); } + myReader.resetView(); myReader.repaintView(); } } diff --git a/src/org/geometerplus/fbreader/fbreader/TurnPageAction.java b/src/org/geometerplus/fbreader/fbreader/TurnPageAction.java index 784b0bd1a..d6acc152e 100644 --- a/src/org/geometerplus/fbreader/fbreader/TurnPageAction.java +++ b/src/org/geometerplus/fbreader/fbreader/TurnPageAction.java @@ -56,34 +56,22 @@ class TurnPageAction extends FBAction { public void run() { final ScrollingPreferences preferences = ScrollingPreferences.Instance(); - final FBView view = Reader.getTextView(); - if (view.getAnimationType() != FBView.Animation.none) { - view.startAutoScrolling( - myForward ? FBView.PageIndex.next : FBView.PageIndex.previous, - preferences.HorizontalOption.getValue() - ? FBView.Direction.rightToLeft : FBView.Direction.up, - preferences.AnimationSpeedOption.getValue() - ); - } else { - view.scrollPage(myForward, FBView.ScrollingMode.NO_OVERLAPPING, 0); - Reader.repaintView(); - } + Reader.getTextView().startAutoScrolling( + myForward ? FBView.PageIndex.next : FBView.PageIndex.previous, + preferences.HorizontalOption.getValue() + ? FBView.Direction.rightToLeft : FBView.Direction.up, + preferences.AnimationSpeedOption.getValue() + ); } public void runWithCoordinates(int x, int y) { final ScrollingPreferences preferences = ScrollingPreferences.Instance(); - final FBView view = Reader.getTextView(); - if (view.getAnimationType() != FBView.Animation.none) { - view.startAutoScrolling( - myForward ? FBView.PageIndex.next : FBView.PageIndex.previous, - preferences.HorizontalOption.getValue() - ? FBView.Direction.rightToLeft : FBView.Direction.up, - x, y, - preferences.AnimationSpeedOption.getValue() - ); - } else { - view.scrollPage(myForward, FBView.ScrollingMode.NO_OVERLAPPING, 0); - Reader.repaintView(); - } + Reader.getTextView().startAutoScrolling( + myForward ? FBView.PageIndex.next : FBView.PageIndex.previous, + preferences.HorizontalOption.getValue() + ? FBView.Direction.rightToLeft : FBView.Direction.up, + x, y, + preferences.AnimationSpeedOption.getValue() + ); } } diff --git a/src/org/geometerplus/fbreader/fbreader/VolumeKeyTurnPageAction.java b/src/org/geometerplus/fbreader/fbreader/VolumeKeyTurnPageAction.java index ea0876490..2c2c16c39 100755 --- a/src/org/geometerplus/fbreader/fbreader/VolumeKeyTurnPageAction.java +++ b/src/org/geometerplus/fbreader/fbreader/VolumeKeyTurnPageAction.java @@ -54,17 +54,11 @@ class VolumeKeyTurnPageAction extends FBAction { return; } } - final FBView view = Reader.getTextView(); - if (view.getAnimationType() != FBView.Animation.none) { - view.startAutoScrolling( - forward ? FBView.PageIndex.next : FBView.PageIndex.previous, - preferences.HorizontalOption.getValue() - ? FBView.Direction.rightToLeft : FBView.Direction.up, - preferences.AnimationSpeedOption.getValue() - ); - } else { - view.scrollPage(forward, FBView.ScrollingMode.NO_OVERLAPPING, 0); - Reader.repaintView(); - } + Reader.getTextView().startAutoScrolling( + forward ? FBView.PageIndex.next : FBView.PageIndex.previous, + preferences.HorizontalOption.getValue() + ? FBView.Direction.rightToLeft : FBView.Direction.up, + preferences.AnimationSpeedOption.getValue() + ); } } diff --git a/src/org/geometerplus/zlibrary/core/application/ZLApplication.java b/src/org/geometerplus/zlibrary/core/application/ZLApplication.java index 67955d47a..70d8bb0cb 100644 --- a/src/org/geometerplus/zlibrary/core/application/ZLApplication.java +++ b/src/org/geometerplus/zlibrary/core/application/ZLApplication.java @@ -45,6 +45,7 @@ public abstract class ZLApplication { protected final void setView(ZLView view) { if (view != null) { myView = view; + resetView(); repaintView(); onViewChanged(); } @@ -62,6 +63,12 @@ public abstract class ZLApplication { setView(myView); } + public final void resetView() { + if (myWindow != null) { + myWindow.resetView(); + } + } + public final void repaintView() { if (myWindow != null) { myWindow.repaintView(); @@ -74,12 +81,6 @@ public abstract class ZLApplication { } } - public final void scrollViewToCenter() { - if (myWindow != null) { - myWindow.scrollViewToCenter(); - } - } - public final void startViewAutoScrolling(ZLView.PageIndex pageIndex, ZLView.Direction direction, int speed) { if (myWindow != null) { myWindow.startViewAutoScrolling(pageIndex, direction, speed); diff --git a/src/org/geometerplus/zlibrary/core/application/ZLApplicationWindow.java b/src/org/geometerplus/zlibrary/core/application/ZLApplicationWindow.java index fc4485fb0..4422cf529 100644 --- a/src/org/geometerplus/zlibrary/core/application/ZLApplicationWindow.java +++ b/src/org/geometerplus/zlibrary/core/application/ZLApplicationWindow.java @@ -35,9 +35,9 @@ abstract public class ZLApplicationWindow { abstract protected void refreshMenu(); + abstract protected void resetView(); abstract protected void repaintView(); abstract protected void scrollViewManually(int startX, int startY, int endX, int endY, ZLView.Direction direction); - abstract protected void scrollViewToCenter(); abstract protected void startViewAutoScrolling(ZLView.PageIndex pageIndex, ZLView.Direction direction, int speed); abstract protected void startViewAutoScrolling(ZLView.PageIndex pageIndex, ZLView.Direction direction, int x, int y, int speed); diff --git a/src/org/geometerplus/zlibrary/core/view/ZLView.java b/src/org/geometerplus/zlibrary/core/view/ZLView.java index 804872435..131b5accc 100644 --- a/src/org/geometerplus/zlibrary/core/view/ZLView.java +++ b/src/org/geometerplus/zlibrary/core/view/ZLView.java @@ -34,7 +34,29 @@ abstract public class ZLView { abstract public FooterArea getFooterArea(); public static enum PageIndex { - current, previous, next + previous, current, next; + + public PageIndex getNext() { + switch (this) { + case previous: + return current; + case current: + return next; + default: + return null; + } + } + + public PageIndex getPrevious() { + switch (this) { + case next: + return current; + case current: + return previous; + default: + return null; + } + } }; public static enum Direction { leftToRight(true), rightToLeft(true), up(false), down(false); diff --git a/src/org/geometerplus/zlibrary/text/view/ZLTextView.java b/src/org/geometerplus/zlibrary/text/view/ZLTextView.java index 002387abf..9dab3e4ce 100644 --- a/src/org/geometerplus/zlibrary/text/view/ZLTextView.java +++ b/src/org/geometerplus/zlibrary/text/view/ZLTextView.java @@ -74,6 +74,7 @@ public abstract class ZLTextView extends ZLTextViewBase { myCurrentPage.moveStartCursor(ZLTextParagraphCursor.cursor(myModel, 0)); } } + ZLApplication.Instance().resetView(); } public ZLTextModel getModel() { @@ -126,6 +127,7 @@ public abstract class ZLTextView extends ZLTextViewBase { if (myCurrentPage.StartCursor.isNull()) { preparePaintInfo(myCurrentPage); } + ZLApplication.Instance().resetView(); ZLApplication.Instance().repaintView(); } } @@ -150,6 +152,7 @@ public abstract class ZLTextView extends ZLTextViewBase { (backward ? myModel.getLastMark() : myModel.getFirstMark()) : (backward ? myModel.getPreviousMark(mark) : myModel.getNextMark(mark))); } + ZLApplication.Instance().resetView(); ZLApplication.Instance().repaintView(); } return count; @@ -183,6 +186,7 @@ public abstract class ZLTextView extends ZLTextViewBase { if (!findResultsAreEmpty()) { myModel.removeAllMarks(); rebuildPaintInfo(); + ZLApplication.Instance().resetView(); ZLApplication.Instance().repaintView(); } } @@ -1285,6 +1289,7 @@ public abstract class ZLTextView extends ZLTextViewBase { @Override public boolean onFingerMove(int x, int y) { if (mySelectionModel.extendTo(x, y)) { + ZLApplication.Instance().resetView(); ZLApplication.Instance().repaintView(); return true; } @@ -1299,12 +1304,15 @@ public abstract class ZLTextView extends ZLTextViewBase { protected abstract boolean isSelectionEnabled(); + /* protected void activateSelection(int x, int y) { if (isSelectionEnabled()) { mySelectionModel.activate(x, y); + ZLApplication.Instance().resetView(); ZLApplication.Instance().repaintView(); } } + */ private ZLTextElementRegion mySelectedRegion; private boolean myHighlightSelectedRegion = true; diff --git a/src/org/geometerplus/zlibrary/ui/android/application/ZLAndroidApplicationWindow.java b/src/org/geometerplus/zlibrary/ui/android/application/ZLAndroidApplicationWindow.java index 1e7d3de38..b14174c76 100644 --- a/src/org/geometerplus/zlibrary/ui/android/application/ZLAndroidApplicationWindow.java +++ b/src/org/geometerplus/zlibrary/ui/android/application/ZLAndroidApplicationWindow.java @@ -67,6 +67,13 @@ public final class ZLAndroidApplicationWindow extends ZLApplicationWindow { } } + protected void resetView() { + final ZLAndroidWidget widget = + ((ZLAndroidLibrary)ZLAndroidLibrary.Instance()).getWidget(); + // I'm not sure about threads, so postInvalidate() is used instead of invalidate() + widget.resetBitmaps(); + } + protected void repaintView() { final ZLAndroidWidget widget = ((ZLAndroidLibrary)ZLAndroidLibrary.Instance()).getWidget(); @@ -81,13 +88,6 @@ public final class ZLAndroidApplicationWindow extends ZLApplicationWindow { widget.scrollManually(startX, startY, endX, endY, direction); } - @Override - protected void scrollViewToCenter() { - final ZLAndroidWidget widget = - ((ZLAndroidLibrary)ZLAndroidLibrary.Instance()).getWidget(); - widget.scrollToCenter(); - } - @Override protected void startViewAutoScrolling(ZLView.PageIndex pageIndex, ZLView.Direction direction, int speed) { final ZLAndroidWidget widget = diff --git a/src/org/geometerplus/zlibrary/ui/android/view/AnimationProvider.java b/src/org/geometerplus/zlibrary/ui/android/view/AnimationProvider.java index 388bfd181..f8a117646 100644 --- a/src/org/geometerplus/zlibrary/ui/android/view/AnimationProvider.java +++ b/src/org/geometerplus/zlibrary/ui/android/view/AnimationProvider.java @@ -41,7 +41,7 @@ abstract class AnimationProvider { } private Mode myMode = Mode.NoScrolling; - protected final Paint myPaint; + private final BitmapManager myBitmapManager; protected int myStartX; protected int myStartY; protected int myEndX; @@ -52,8 +52,8 @@ abstract class AnimationProvider { protected int myWidth; protected int myHeight; - protected AnimationProvider(Paint paint) { - myPaint = paint; + protected AnimationProvider(BitmapManager bitmapManager) { + myBitmapManager = bitmapManager; } Mode getMode() { @@ -168,16 +168,24 @@ abstract class AnimationProvider { } final private List myDrawInfos = new LinkedList(); - final void draw(Canvas canvas, Bitmap bgBitmap, Bitmap fgBitmap) { + final void draw(Canvas canvas) { final long start = System.currentTimeMillis(); - drawInternal(canvas, bgBitmap, fgBitmap); + drawInternal(canvas); myDrawInfos.add(new DrawInfo(myEndX, myEndY, start, System.currentTimeMillis())); if (myDrawInfos.size() > 3) { myDrawInfos.remove(0); } } - protected abstract void drawInternal(Canvas canvas, Bitmap bgBitmap, Bitmap fgBitmap); + protected abstract void drawInternal(Canvas canvas); abstract ZLView.PageIndex getPageToScrollTo(); + + protected Bitmap getBitmapFrom() { + return myBitmapManager.getBitmap(ZLView.PageIndex.current); + } + + protected Bitmap getBitmapTo() { + return myBitmapManager.getBitmap(getPageToScrollTo()); + } } diff --git a/src/org/geometerplus/zlibrary/ui/android/view/BitmapManager.java b/src/org/geometerplus/zlibrary/ui/android/view/BitmapManager.java new file mode 100644 index 000000000..1a50b89f2 --- /dev/null +++ b/src/org/geometerplus/zlibrary/ui/android/view/BitmapManager.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2007-2011 Geometer Plus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +package org.geometerplus.zlibrary.ui.android.view; + +import android.graphics.Bitmap; + +import org.geometerplus.zlibrary.core.view.ZLView; + +class BitmapManager { + private final int SIZE = 2; + private final Bitmap[] myBitmaps = new Bitmap[SIZE]; + private final ZLView.PageIndex[] myIndexes = new ZLView.PageIndex[SIZE]; + + private int myWidth; + private int myHeight; + + private final ZLAndroidWidget myWidget; + + BitmapManager(ZLAndroidWidget widget) { + myWidget = widget; + } + + void setSize(int w, int h) { + if (myWidth != w || myHeight != h) { + myWidth = w; + myHeight = h; + for (int i = 0; i < SIZE; ++i) { + myBitmaps[i] = null; + myIndexes[i] = null; + } + System.gc(); + System.gc(); + System.gc(); + } + } + + Bitmap getBitmap(ZLView.PageIndex index) { + for (int i = 0; i < SIZE; ++i) { + if (index == myIndexes[i]) { + return myBitmaps[i]; + } + } + final int iIndex = getInternalIndex(index); + myIndexes[iIndex] = index; + if (myBitmaps[iIndex] == null) { + myBitmaps[iIndex] = Bitmap.createBitmap(myWidth, myHeight, Bitmap.Config.RGB_565); + } + myWidget.drawOnBitmap(myBitmaps[iIndex], index); + return myBitmaps[iIndex]; + } + + private int getInternalIndex(ZLView.PageIndex index) { + for (int i = 0; i < SIZE; ++i) { + if (myIndexes[i] == null) { + return i; + } + } + for (int i = 0; i < SIZE; ++i) { + if (myIndexes[i] != ZLView.PageIndex.current) { + return i; + } + } + throw new RuntimeException("That's impossible"); + } + + void reset() { + for (int i = 0; i < SIZE; ++i) { + myIndexes[i] = null; + } + } + + void shift(boolean forward) { + for (int i = 0; i < SIZE; ++i) { + if (myIndexes[i] == null) { + continue; + } + myIndexes[i] = forward ? myIndexes[i].getPrevious() : myIndexes[i].getNext(); + } + } +} diff --git a/src/org/geometerplus/zlibrary/ui/android/view/CurlAnimationProvider.java b/src/org/geometerplus/zlibrary/ui/android/view/CurlAnimationProvider.java index b5ddb3872..5827f8587 100644 --- a/src/org/geometerplus/zlibrary/ui/android/view/CurlAnimationProvider.java +++ b/src/org/geometerplus/zlibrary/ui/android/view/CurlAnimationProvider.java @@ -25,6 +25,7 @@ import android.util.FloatMath; import org.geometerplus.zlibrary.core.view.ZLView; class CurlAnimationProvider extends AnimationProvider { + private final Paint myPaint = new Paint(); private final Paint myBackPaint = new Paint(); private final Paint myEdgePaint = new Paint(); @@ -33,8 +34,8 @@ class CurlAnimationProvider extends AnimationProvider { private float mySpeedFactor; - CurlAnimationProvider(Paint paint) { - super(paint); + CurlAnimationProvider(BitmapManager bitmapManager) { + super(bitmapManager); myBackPaint.setAntiAlias(true); myBackPaint.setAlpha(0x40); @@ -45,8 +46,9 @@ class CurlAnimationProvider extends AnimationProvider { } @Override - protected void drawInternal(Canvas canvas, Bitmap bgBitmap, Bitmap fgBitmap) { - canvas.drawBitmap(bgBitmap, 0, 0, myPaint); + protected void drawInternal(Canvas canvas) { + canvas.drawBitmap(getBitmapTo(), 0, 0, myPaint); + final Bitmap fgBitmap = getBitmapFrom(); final int cornerX = myStartX > myWidth / 2 ? myWidth : 0; final int cornerY = myStartY > myHeight / 2 ? myHeight : 0; diff --git a/src/org/geometerplus/zlibrary/ui/android/view/NoneAnimationProvider.java b/src/org/geometerplus/zlibrary/ui/android/view/NoneAnimationProvider.java index 647e478a3..08d78918e 100644 --- a/src/org/geometerplus/zlibrary/ui/android/view/NoneAnimationProvider.java +++ b/src/org/geometerplus/zlibrary/ui/android/view/NoneAnimationProvider.java @@ -22,12 +22,21 @@ package org.geometerplus.zlibrary.ui.android.view; import android.graphics.*; class NoneAnimationProvider extends SimpleAnimationProvider { - NoneAnimationProvider(Paint paint) { - super(paint); + private final Paint myPaint = new Paint(); + + NoneAnimationProvider(BitmapManager bitmapManager) { + super(bitmapManager); } @Override - protected void drawInternal(Canvas canvas, Bitmap bgBitmap, Bitmap fgBitmap) { - canvas.drawBitmap(fgBitmap, 0, 0, myPaint); + protected void drawInternal(Canvas canvas) { + canvas.drawBitmap(getBitmapFrom(), 0, 0, myPaint); + } + + @Override + void doStep() { + if (getMode().Auto) { + terminate(); + } } } diff --git a/src/org/geometerplus/zlibrary/ui/android/view/ShiftAnimationProvider.java b/src/org/geometerplus/zlibrary/ui/android/view/ShiftAnimationProvider.java index 64f8826b1..faee075e9 100644 --- a/src/org/geometerplus/zlibrary/ui/android/view/ShiftAnimationProvider.java +++ b/src/org/geometerplus/zlibrary/ui/android/view/ShiftAnimationProvider.java @@ -22,17 +22,19 @@ package org.geometerplus.zlibrary.ui.android.view; import android.graphics.*; class ShiftAnimationProvider extends SimpleAnimationProvider { - ShiftAnimationProvider(Paint paint) { - super(paint); + private final Paint myPaint = new Paint(); + + ShiftAnimationProvider(BitmapManager bitmapManager) { + super(bitmapManager); } @Override - protected void drawInternal(Canvas canvas, Bitmap bgBitmap, Bitmap fgBitmap) { + protected void drawInternal(Canvas canvas) { myPaint.setColor(Color.rgb(127, 127, 127)); if (myDirection.IsHorizontal) { final int dX = myEndX - myStartX; - canvas.drawBitmap(bgBitmap, dX > 0 ? dX - myWidth : dX + myWidth, 0, myPaint); - canvas.drawBitmap(fgBitmap, dX, 0, myPaint); + canvas.drawBitmap(getBitmapTo(), dX > 0 ? dX - myWidth : dX + myWidth, 0, myPaint); + canvas.drawBitmap(getBitmapFrom(), dX, 0, myPaint); if (dX > 0 && dX < myWidth) { canvas.drawLine(dX, 0, dX, myHeight + 1, myPaint); } else if (dX < 0 && dX > -myWidth) { @@ -40,8 +42,8 @@ class ShiftAnimationProvider extends SimpleAnimationProvider { } } else { final int dY = myEndY - myStartY; - canvas.drawBitmap(bgBitmap, 0, dY > 0 ? dY - myHeight : dY + myHeight, myPaint); - canvas.drawBitmap(fgBitmap, 0, dY, myPaint); + canvas.drawBitmap(getBitmapTo(), 0, dY > 0 ? dY - myHeight : dY + myHeight, myPaint); + canvas.drawBitmap(getBitmapFrom(), 0, dY, myPaint); if (dY > 0 && dY < myHeight) { canvas.drawLine(0, dY, myWidth + 1, dY, myPaint); } else if (dY < 0 && dY > -myHeight) { diff --git a/src/org/geometerplus/zlibrary/ui/android/view/SimpleAnimationProvider.java b/src/org/geometerplus/zlibrary/ui/android/view/SimpleAnimationProvider.java index 823f6fdb2..0245f8e06 100644 --- a/src/org/geometerplus/zlibrary/ui/android/view/SimpleAnimationProvider.java +++ b/src/org/geometerplus/zlibrary/ui/android/view/SimpleAnimationProvider.java @@ -19,15 +19,13 @@ package org.geometerplus.zlibrary.ui.android.view; -import android.graphics.Paint; - import org.geometerplus.zlibrary.core.view.ZLView; abstract class SimpleAnimationProvider extends AnimationProvider { private float mySpeedFactor; - SimpleAnimationProvider(Paint paint) { - super(paint); + SimpleAnimationProvider(BitmapManager bitmapManager) { + super(bitmapManager); } @Override diff --git a/src/org/geometerplus/zlibrary/ui/android/view/SlideAnimationProvider.java b/src/org/geometerplus/zlibrary/ui/android/view/SlideAnimationProvider.java index 8d8511f5c..65be9c6f2 100644 --- a/src/org/geometerplus/zlibrary/ui/android/view/SlideAnimationProvider.java +++ b/src/org/geometerplus/zlibrary/ui/android/view/SlideAnimationProvider.java @@ -22,17 +22,19 @@ package org.geometerplus.zlibrary.ui.android.view; import android.graphics.*; class SlideAnimationProvider extends SimpleAnimationProvider { - SlideAnimationProvider(Paint paint) { - super(paint); + private final Paint myPaint = new Paint(); + + SlideAnimationProvider(BitmapManager bitmapManager) { + super(bitmapManager); } @Override - protected void drawInternal(Canvas canvas, Bitmap bgBitmap, Bitmap fgBitmap) { - canvas.drawBitmap(bgBitmap, 0, 0, myPaint); + protected void drawInternal(Canvas canvas) { + canvas.drawBitmap(getBitmapTo(), 0, 0, myPaint); myPaint.setColor(Color.rgb(127, 127, 127)); if (myDirection.IsHorizontal) { final int dX = myEndX - myStartX; - canvas.drawBitmap(fgBitmap, dX, 0, myPaint); + canvas.drawBitmap(getBitmapFrom(), dX, 0, myPaint); if (dX > 0 && dX < myWidth) { canvas.drawLine(dX, 0, dX, myHeight + 1, myPaint); } else if (dX < 0 && dX > -myWidth) { @@ -40,7 +42,7 @@ class SlideAnimationProvider extends SimpleAnimationProvider { } } else { final int dY = myEndY - myStartY; - canvas.drawBitmap(fgBitmap, 0, dY, myPaint); + canvas.drawBitmap(getBitmapFrom(), 0, dY, myPaint); if (dY > 0 && dY < myHeight) { canvas.drawLine(0, dY, myWidth + 1, dY, myPaint); } else if (dY < 0 && dY > -myHeight) { diff --git a/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidWidget.java b/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidWidget.java index 8a59bc836..f00ef7d1c 100644 --- a/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidWidget.java +++ b/src/org/geometerplus/zlibrary/ui/android/view/ZLAndroidWidget.java @@ -32,9 +32,7 @@ import org.geometerplus.zlibrary.ui.android.util.ZLAndroidKeyUtil; public class ZLAndroidWidget extends View implements View.OnLongClickListener { private final Paint myPaint = new Paint(); - private Bitmap myMainBitmap; - private Bitmap mySecondaryBitmap; - private boolean mySecondaryBitmapIsUpToDate; + private final BitmapManager myBitmapManager = new BitmapManager(this); private Bitmap myFooterBitmap; private ZLView.PageIndex myPageToScrollTo = ZLView.PageIndex.current; @@ -72,6 +70,7 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener { view.onScrollingFinished(ZLView.PageIndex.current); setPageToScrollTo(ZLView.PageIndex.current); } + myBitmapManager.setSize(w, h); } @Override @@ -87,21 +86,6 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener { final int w = getWidth(); final int h = getMainAreaHeight(); - if (myMainBitmap != null && - (myMainBitmap.getWidth() != w || myMainBitmap.getHeight() != h)) { - myMainBitmap = null; - mySecondaryBitmap = null; - System.gc(); - System.gc(); - System.gc(); - } - if (myMainBitmap == null) { - myMainBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565); - mySecondaryBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565); - mySecondaryBitmapIsUpToDate = false; - drawOnBitmap(myMainBitmap); - } - if (getAnimationProvider().inProgress()) { onDrawInScrolling(canvas); } else { @@ -118,16 +102,16 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener { myAnimationType = type; switch (type) { case none: - myAnimationProvider = new NoneAnimationProvider(myPaint); + myAnimationProvider = new NoneAnimationProvider(myBitmapManager); break; case curl: - myAnimationProvider = new CurlAnimationProvider(myPaint); + myAnimationProvider = new CurlAnimationProvider(myBitmapManager); break; case slide: - myAnimationProvider = new SlideAnimationProvider(myPaint); + myAnimationProvider = new SlideAnimationProvider(myBitmapManager); break; case shift: - myAnimationProvider = new ShiftAnimationProvider(myPaint); + myAnimationProvider = new ShiftAnimationProvider(myBitmapManager); break; } } @@ -144,7 +128,7 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener { final AnimationProvider.Mode oldMode = animator.getMode(); animator.doStep(); if (animator.inProgress()) { - animator.draw(canvas, mySecondaryBitmap, myMainBitmap); + animator.draw(canvas); if (animator.getMode().Auto) { postInvalidate(); } @@ -153,9 +137,7 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener { switch (oldMode) { case AutoScrollingForward: { - final Bitmap swap = myMainBitmap; - myMainBitmap = mySecondaryBitmap; - mySecondaryBitmap = swap; + myBitmapManager.shift(animator.getPageToScrollTo() == ZLView.PageIndex.next); view.onScrollingFinished(myPageToScrollTo); ZLApplication.Instance().onRepaintFinished(); break; @@ -170,45 +152,28 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener { } private void setPageToScrollTo(ZLView.PageIndex pageIndex) { - if (myPageToScrollTo != pageIndex) { - myPageToScrollTo = pageIndex; - mySecondaryBitmapIsUpToDate = false; - } + myPageToScrollTo = pageIndex; + } + + public void resetBitmaps() { + myBitmapManager.reset(); } public void scrollManually(int startX, int startY, int endX, int endY, ZLView.Direction direction) { - if (myMainBitmap == null) { - return; - } - final AnimationProvider animator = getAnimationProvider(); if (!animator.inProgress()) { - getAnimationProvider().startManualScrolling( + animator.startManualScrolling( startX, startY, direction, getWidth(), getMainAreaHeight() ); } - getAnimationProvider().scrollTo(endX, endY); - setPageToScrollTo(getAnimationProvider().getPageToScrollTo()); - drawOnBitmap(mySecondaryBitmap); - postInvalidate(); - } - - public void scrollToCenter() { - getAnimationProvider().terminate(); - if (myMainBitmap == null) { - return; - } - setPageToScrollTo(ZLView.PageIndex.current); - drawOnBitmap(mySecondaryBitmap); + animator.scrollTo(endX, endY); + setPageToScrollTo(animator.getPageToScrollTo()); postInvalidate(); } public void startAutoScrolling(ZLView.PageIndex pageIndex, ZLView.Direction direction, Integer x, Integer y, int speed) { - if (myMainBitmap == null) { - return; - } final AnimationProvider animator = getAnimationProvider(); final int w = getWidth(); final int h = getMainAreaHeight(); @@ -235,34 +200,22 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener { setPageToScrollTo(pageIndex); break; } - drawOnBitmap(mySecondaryBitmap); postInvalidate(); } - private void drawOnBitmap(Bitmap bitmap) { + void drawOnBitmap(Bitmap bitmap, ZLView.PageIndex index) { final ZLView view = ZLApplication.Instance().getCurrentView(); if (view == null) { return; } - if (bitmap == myMainBitmap) { - mySecondaryBitmapIsUpToDate = false; - } else if (mySecondaryBitmapIsUpToDate) { - return; - } else { - mySecondaryBitmapIsUpToDate = true; - } - final ZLAndroidPaintContext context = new ZLAndroidPaintContext( new Canvas(bitmap), getWidth(), getMainAreaHeight(), view.isScrollbarShown() ? getVerticalScrollbarWidth() : 0 ); - view.paint( - context, - bitmap == myMainBitmap ? ZLView.PageIndex.current : myPageToScrollTo - ); + view.paint(context, index); } private void drawFooter(Canvas canvas) { @@ -293,8 +246,7 @@ public class ZLAndroidWidget extends View implements View.OnLongClickListener { } private void onDrawStatic(Canvas canvas) { - drawOnBitmap(myMainBitmap); - canvas.drawBitmap(myMainBitmap, 0, 0, myPaint); + canvas.drawBitmap(myBitmapManager.getBitmap(ZLView.PageIndex.current), 0, 0, myPaint); drawFooter(canvas); }