package com.lfk.justwetools.View.ReadView; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; import android.text.format.Time; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.io.UnsupportedEncodingException; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.text.DecimalFormat; import java.util.Vector; public class PageFactory { private int mHeight, mWidth; private int mVisibleHeight, mVisibleWidth; private int mPageLineCount; // 行间距 private int mLineSpace = 2; // 字节长 private int m_mpBufferLen; private MappedByteBuffer m_mpBuff; // 页首页尾的行数 private int m_mbBufEndPos = 0; private int m_mbBufBeginPos = 0; private Paint mNumPaint; private Paint mPaint; private int marginHeight = 30; private int marginWeight = 30; // 字号 private int mFontSize = 60; private int mNumFontSize = 45; private Bitmap m_book_bg; private Vector<String> m_lines = new Vector<String>(); public PageFactory(Context context,int w, int h, int font_size){ mWidth = w; mHeight = h; mFontSize = font_size; mVisibleHeight = mHeight - marginHeight *2 - mFontSize; mVisibleWidth = mWidth - marginWeight *2; Typeface typeface = Typeface.createFromAsset(context.getAssets(),"fonts/FZBYSK.TTF"); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setTextSize(mFontSize); mPaint.setTypeface(typeface); mPaint.setColor(Color.BLACK); // 每页行数 mPageLineCount = mVisibleHeight/(mFontSize+2); mNumPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mNumPaint.setTextSize(mNumFontSize); mNumPaint.setTypeface(typeface); mNumPaint.setColor(Color.GRAY); } public void openBook(String path, int[] position){ try { File file = new File(path); long length = file.length(); m_mpBufferLen = (int)length; m_mpBuff = new RandomAccessFile(file, "r"). getChannel().map(FileChannel.MapMode.READ_ONLY, 0, length); m_mbBufEndPos = position[1]; m_mbBufBeginPos = position[0]; } catch (IOException e) { e.printStackTrace(); } } public void onDraw(Canvas canvas){ if(m_lines.size() == 0){ // first init m_mbBufEndPos = m_mbBufBeginPos; m_lines = pageDown(); } if(m_lines.size() > 0){ int y = marginHeight; if(m_book_bg != null){ Rect rectF = new Rect(0, 0, mWidth, mHeight); canvas.drawBitmap(m_book_bg, null, rectF, null); }else{ canvas.drawColor(Color.WHITE); } for(String line : m_lines){ // y是每行的位置 y += mFontSize + mLineSpace; canvas.drawText(line, marginWeight, y, mPaint); } float percent = (float)m_mbBufBeginPos * 100/m_mpBufferLen; DecimalFormat sirPercent = new DecimalFormat("#0.00"); canvas.drawText(sirPercent.format(percent) + "%", marginWeight + 2, mHeight - marginHeight, mNumPaint); Time time = new Time(); time.setToNow(); String mTime = time.hour + "时" + time.minute + "分 "; int strLen = (int)mNumPaint.measureText(mTime); canvas.drawText(mTime , mWidth - marginWeight - strLen, mHeight - marginHeight, mNumPaint); } } private void pageUp() { // TODO Auto-generated method stub String strParagraph = ""; Vector<String> lines = new Vector<String>(); while((lines.size() < mPageLineCount) && (m_mbBufBeginPos > 0)){ Vector<String> paraLines = new Vector<String>(); byte[] parabuffer = readParagraphBack(m_mbBufBeginPos); m_mbBufBeginPos -= parabuffer.length; try { strParagraph = new String(parabuffer, "GBK"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } strParagraph = strParagraph.replaceAll("\r\n", " "); strParagraph = strParagraph.replaceAll("\n", " "); while(strParagraph.length() > 0){ int paintSize = mPaint.breakText(strParagraph, true, mVisibleWidth, null); paraLines.add(strParagraph.substring(0, paintSize)); strParagraph = strParagraph.substring(paintSize); } lines.addAll(0, paraLines); while (lines.size() > mPageLineCount) { try { m_mbBufBeginPos += lines.get(0).getBytes("GBK").length; lines.remove(0); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } m_mbBufEndPos = m_mbBufBeginPos; } } private Vector<String> pageDown() { // TODO Auto-generated method stub String strParagraph = ""; Vector<String> lines = new Vector<String>(); while((lines.size() < mPageLineCount) && (m_mbBufEndPos < m_mpBufferLen)){ byte[] parabuffer = readParagraphForward(m_mbBufEndPos); m_mbBufEndPos += parabuffer.length; try { strParagraph = new String(parabuffer, "GBK"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } strParagraph = strParagraph.replaceAll("\r\n", " "); strParagraph = strParagraph.replaceAll("\n", " "); while(strParagraph.length() > 0){ int paintSize = mPaint.breakText(strParagraph, true, mVisibleWidth, null); lines.add(strParagraph.substring(0, paintSize)); strParagraph = strParagraph.substring(paintSize); if(lines.size() >= mPageLineCount){ break; } } if(strParagraph.length()!=0){ try { m_mbBufEndPos -= (strParagraph).getBytes("GBK").length; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } return lines; } private byte[] readParagraphForward(int m_mbBufPos) { // TODO Auto-generated method stub byte b0, b1 ; int i = m_mbBufPos; while(i < m_mpBufferLen){ b0 = m_mpBuff.get(i++); if(b0 == 0x0a){ break; } } int nParaSize = i - m_mbBufPos; byte[] buf = new byte[nParaSize]; for (i = 0; i < nParaSize; i++) { buf[i] = m_mpBuff.get(m_mbBufPos + i); } return buf; } private byte[] readParagraphBack(int m_mbBufBeginPos) { byte b0, b1 ; int i = m_mbBufBeginPos -1 ; while(i > 0){ b0 = m_mpBuff.get(i); if(b0 == 0x0a && i != m_mbBufBeginPos -1 ){ i++; break; } i--; } int nParaSize = m_mbBufBeginPos -i ; byte[] buf = new byte[nParaSize]; for (int j = 0; j < nParaSize; j++) { buf[j] = m_mpBuff.get(i + j); } return buf; } public void nextPage() { // TODO Auto-generated method stub if(m_mbBufEndPos >= m_mpBufferLen){ return; }else{ m_lines.clear(); m_mbBufBeginPos = m_mbBufEndPos; m_lines = pageDown(); } } public void prePage() { // TODO Auto-generated method stub if(m_mbBufBeginPos <= 0){ return; } m_lines.clear(); pageUp(); m_lines = pageDown(); } public int[] getPosition(){ int[] a = new int[]{m_mbBufBeginPos, m_mbBufEndPos}; return a; } public void setTextFont(int fontsize) { // TODO Auto-generated method stub mFontSize = fontsize; mPaint.setTextSize(mFontSize); mPageLineCount = mVisibleHeight/(mFontSize+mLineSpace); m_mbBufEndPos = m_mbBufBeginPos; nextPage(); } public int getTextFont() { // TODO Auto-generated method stub return mFontSize; } public void setPercent(int persent) { // TODO Auto-generated method stub float a = (float)(m_mpBufferLen*persent)/100; m_mbBufEndPos = (int)a; if(m_mbBufEndPos == 0){ nextPage(); }else{ nextPage(); prePage(); nextPage(); } } public void setBgBitmap(Bitmap BG) { m_book_bg = BG; } }