package org.ebookdroid.droids.djvu.codec; import org.ebookdroid.common.bitmaps.ByteBufferBitmap; import org.ebookdroid.common.bitmaps.ByteBufferManager; import org.ebookdroid.common.settings.AppSettings; import org.ebookdroid.core.ViewState; import org.ebookdroid.core.codec.AbstractCodecPage; import org.ebookdroid.core.codec.PageLink; import org.ebookdroid.core.codec.PageTextBox; import android.graphics.Color; import android.graphics.RectF; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.emdev.utils.LengthUtils; public class DjvuPage extends AbstractCodecPage { private final long contextHandle; private final long docHandle; private final int pageNo; private long pageHandle; private final static boolean USE_DIRECT = true; DjvuPage(final long contextHandle, final long docHandle, final long pageHandle, final int pageNo) { this.contextHandle = contextHandle; this.docHandle = docHandle; this.pageHandle = pageHandle; this.pageNo = pageNo; } @Override public int getWidth() { return getWidth(pageHandle); } @Override public int getHeight() { return getHeight(pageHandle); } @Override public ByteBufferBitmap renderBitmap(final ViewState viewState, final int width, final int height, final RectF pageSliceBounds) { final int renderMode = AppSettings.current().djvuRenderingMode; ByteBufferBitmap buf = ByteBufferManager.getBitmap(width, height); if (width > 0 && height > 0) { final ByteBuffer byteBuffer = buf.getPixels(); if (renderPageDirect(pageHandle, contextHandle, width, height, pageSliceBounds.left, pageSliceBounds.top, pageSliceBounds.width(), pageSliceBounds.height(), byteBuffer, renderMode)) { return buf; } } buf.eraseColor(Color.GRAY); return buf; } @Override protected void finalize() throws Throwable { recycle(); super.finalize(); } @Override public synchronized void recycle() { if (pageHandle == 0) { return; } free(pageHandle); pageHandle = 0; } @Override public synchronized boolean isRecycled() { return pageHandle == 0; } @Override public List<PageLink> getPageLinks() { final List<PageLink> links = getPageLinks(docHandle, pageNo); if (links != null) { final float width = getWidth(); final float height = getHeight(); for (final PageLink link : links) { normalize(link.sourceRect, width, height); if (link.url != null && link.url.startsWith("#")) { try { link.targetPage = Integer.parseInt(link.url.substring(1)) - 1; link.url = null; } catch (final NumberFormatException ex) { ex.printStackTrace(); } } } return links; } return Collections.emptyList(); } @Override public List<PageTextBox> getPageText() { final List<PageTextBox> list = getPageText(docHandle, pageNo, contextHandle, null); if (LengthUtils.isNotEmpty(list)) { final float width = getWidth(); final float height = getHeight(); for (final PageTextBox ptb : list) { normalizeTextBox(ptb, width, height); // System.out.println("" + ptb); } } return list; } @Override public List<? extends RectF> searchText(final String pattern) { final List<PageTextBox> list = getPageText(docHandle, pageNo, contextHandle, pattern); if (LengthUtils.isNotEmpty(list)) { final float width = getWidth(); final float height = getHeight(); for (final PageTextBox ptb : list) { normalizeTextBox(ptb, width, height); } } return list; } static void normalize(final RectF r, final float width, final float height) { r.left = r.left / width; r.right = r.right / width; r.top = r.top / height; r.bottom = r.bottom / height; } static void normalizeTextBox(final PageTextBox r, final float width, final float height) { final float left = r.left / width; final float right = r.right / width; final float top = 1 - r.top / height; final float bottom = 1 - r.bottom / height; r.left = Math.min(left, right); r.right = Math.max(left, right); r.top = Math.min(top, bottom); r.bottom = Math.max(top, bottom); } private static native int getWidth(long pageHandle); private static native int getHeight(long pageHandle); private static native boolean isDecodingDone(long pageHandle); private static native boolean renderPageDirect(long pageHandle, long contextHandle, int targetWidth, int targetHeight, float pageSliceX, float pageSliceY, float pageSliceWidth, float pageSliceHeight, ByteBuffer byteBuffer, int renderMode); private static native void free(long pageHandle); private native static ArrayList<PageLink> getPageLinks(long docHandle, int pageNo); native static List<PageTextBox> getPageText(long docHandle, int pageNo, long contextHandle, String pattern); }