123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- package com.poqop.document;
- import android.graphics.*;
- import java.lang.ref.SoftReference;
- /**
- *ÏÔʾÄÚÈÝ¡£
- * @author Administrator
- *
- */
- class PageTreeNode {
- private static final int SLICE_SIZE = 65535;
- private Bitmap bitmap;
- private SoftReference<Bitmap> bitmapWeakReference;
- private boolean decodingNow;
- private final RectF pageSliceBounds;
- private final Page page;
- private PageTreeNode[] children;
- private final int treeNodeDepthLevel;
- private Matrix matrix = new Matrix();
- private final Paint bitmapPaint = new Paint();
- private DocumentView documentView;
- private boolean invalidateFlag;
- private Rect targetRect;
- private RectF targetRectF;
- PageTreeNode(DocumentView documentView, RectF localPageSliceBounds, Page page, int treeNodeDepthLevel, PageTreeNode parent) {
- this.documentView = documentView;
- this.pageSliceBounds = evaluatePageSliceBounds(localPageSliceBounds, parent);
- this.page = page;
- this.treeNodeDepthLevel = treeNodeDepthLevel;
- }
-
- /*
- * ¸üÐÂÏÔʾ
- */
- public void updateVisibility() {
- invalidateChildren();
- if (children != null) {
- for (PageTreeNode child : children) {
- child.updateVisibility();
- }
- }
- if (isVisible()) {
- if (!thresholdHit()) {
- if (getBitmap() != null && !invalidateFlag) {
- restoreBitmapReference();
- } else {
- decodePageTreeNode();
- }
- }
- }
- if (!isVisibleAndNotHiddenByChildren()) {
- stopDecodingThisNode();
- setBitmap(null);
- }
- }
- public void invalidate() {
- invalidateChildren();
- invalidateRecursive();
- updateVisibility();
- }
- private void invalidateRecursive() {
- invalidateFlag = true;
- if (children != null) {
- for (PageTreeNode child : children) {
- child.invalidateRecursive();
- }
- }
- stopDecodingThisNode();
- }
- void invalidateNodeBounds() {
- targetRect = null;
- targetRectF = null;
- if (children != null) {
- for (PageTreeNode child : children) {
- child.invalidateNodeBounds();
- }
- }
- }
- void draw(Canvas canvas) {
- if (getBitmap() != null) {
- canvas.drawBitmap(getBitmap(), new Rect(0, 0, getBitmap().getWidth(), getBitmap().getHeight()), getTargetRect(), bitmapPaint);
- }
- if (children == null) {
- return;
- }
- for (PageTreeNode child : children) {
- child.draw(canvas);
- }
- }
- private boolean isVisible() {
- return RectF.intersects(documentView.getViewRect(), getTargetRectF());
- }
- private RectF getTargetRectF() {
- if (targetRectF == null) {
- targetRectF = new RectF(getTargetRect());
- }
- return targetRectF;
- }
-
- private void invalidateChildren() {
- if (thresholdHit() && children == null && isVisible()) {
- final int newThreshold = treeNodeDepthLevel * 2;
- children = new PageTreeNode[]
- {
- new PageTreeNode(documentView, new RectF(0, 0, 0.5f, 0.5f), page, newThreshold, this),
- new PageTreeNode(documentView, new RectF(0.5f, 0, 1.0f, 0.5f), page, newThreshold, this),
- new PageTreeNode(documentView, new RectF(0, 0.5f, 0.5f, 1.0f), page, newThreshold, this),
- new PageTreeNode(documentView, new RectF(0.5f, 0.5f, 1.0f, 1.0f), page, newThreshold, this)
- };
- }
- if (!thresholdHit() && getBitmap() != null || !isVisible()) {
- recycleChildren();
- }
- }
- private boolean thresholdHit() {
- float zoom = documentView.zoomModel.getZoom();
- int mainWidth = documentView.getWidth();
- float height = page.getPageHeight(mainWidth, zoom);
- return (mainWidth * zoom * height) / (treeNodeDepthLevel * treeNodeDepthLevel) > SLICE_SIZE;
- }
- public Bitmap getBitmap() {
- return bitmapWeakReference != null ? bitmapWeakReference.get() : null;
- }
- private void restoreBitmapReference() {
- setBitmap(getBitmap());
- }
- private void decodePageTreeNode() {
- if (isDecodingNow()) {
- return;
- }
- setDecodingNow(true);
- documentView.decodeService.decodePage(this, page.index, new DecodeService.DecodeCallback() {
- public void decodeComplete(final Bitmap bitmap) {
- documentView.post(new Runnable() {
- public void run() {
- setBitmap(bitmap);
- invalidateFlag = false;
- setDecodingNow(false);
- page.setAspectRatio(documentView.decodeService.getPageWidth(page.index), documentView.decodeService.getPageHeight(page.index));
- invalidateChildren();
- }
- });
- }
- }, documentView.zoomModel.getZoom(), pageSliceBounds);
- }
- private RectF evaluatePageSliceBounds(RectF localPageSliceBounds, PageTreeNode parent) {
- if (parent == null) {
- return localPageSliceBounds;
- }
- final Matrix matrix = new Matrix();
- matrix.postScale(parent.pageSliceBounds.width(), parent.pageSliceBounds.height());
- matrix.postTranslate(parent.pageSliceBounds.left, parent.pageSliceBounds.top);
- final RectF sliceBounds = new RectF();
- matrix.mapRect(sliceBounds, localPageSliceBounds);
- return sliceBounds;
- }
- private void setBitmap(Bitmap bitmap) {
- if (bitmap != null && bitmap.getWidth() == -1 && bitmap.getHeight() == -1) {
- return;
- }
- if (this.bitmap != bitmap) {
- if (bitmap != null) {
- if (this.bitmap != null) {
- this.bitmap.recycle();
- }
- bitmapWeakReference = new SoftReference<Bitmap>(bitmap);
- documentView.postInvalidate();
- }
- this.bitmap = bitmap;
- }
- }
- private boolean isDecodingNow() {
- return decodingNow;
- }
- private void setDecodingNow(boolean decodingNow) {
- if (this.decodingNow != decodingNow) {
- this.decodingNow = decodingNow;
- if (decodingNow) {
- documentView.progressModel.increase();
- } else {
- documentView.progressModel.decrease();
- }
- }
- }
- private Rect getTargetRect() {
- if (targetRect == null) {
- matrix.reset();
- matrix.postScale(page.bounds.width(), page.bounds.height());
- matrix.postTranslate(page.bounds.left, page.bounds.top);
- RectF targetRectF = new RectF();
- matrix.mapRect(targetRectF, pageSliceBounds);
- targetRect = new Rect((int) targetRectF.left, (int) targetRectF.top, (int) targetRectF.right, (int) targetRectF.bottom);
- }
- return targetRect;
- }
- private void stopDecodingThisNode() {
- if (!isDecodingNow()) {
- return;
- }
- documentView.decodeService.stopDecoding(this);
- setDecodingNow(false);
- }
- private boolean isHiddenByChildren() {
- if (children == null) {
- return false;
- }
- for (PageTreeNode child : children) {
- if (child.getBitmap() == null) {
- return false;
- }
- }
- return true;
- }
- private void recycleChildren() {
- if (children == null) {
- return;
- }
- for (PageTreeNode child : children) {
- child.recycle();
- }
- if (!childrenContainBitmaps()) {
- children = null;
- }
- }
- private boolean containsBitmaps() {
- return getBitmap() != null || childrenContainBitmaps();
- }
- private boolean childrenContainBitmaps() {
- if (children == null) {
- return false;
- }
- for (PageTreeNode child : children) {
- if (child.containsBitmaps()) {
- return true;
- }
- }
- return false;
- }
- private void recycle() {
- stopDecodingThisNode();
- setBitmap(null);
- if (children != null) {
- for (PageTreeNode child : children) {
- child.recycle();
- }
- }
- }
- private boolean isVisibleAndNotHiddenByChildren() {
- return isVisible() && !isHiddenByChildren();
- }
- }
|