Merge pull request #3 from TouchInstinct/black_pixels_fix
Black pixels fix
This commit is contained in:
commit
2571a51c7e
|
|
@ -1,7 +1,7 @@
|
|||
apply plugin: 'com.android.library'
|
||||
android {
|
||||
compileSdkVersion 21
|
||||
buildToolsVersion "23.0.2"
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion "25.0.0"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
|
|
@ -17,7 +17,7 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
provided 'com.android.support:appcompat-v7:24.2.1'
|
||||
provided 'com.android.support:appcompat-v7:25.0.0'
|
||||
compile('com.github.chrisbanes:PhotoView:1.3.0') {
|
||||
exclude group: 'com.android.support', module: 'support-v4'
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -54,9 +54,7 @@ import com.sun.pdfview.font.PDFFont;
|
|||
*/
|
||||
public class PDFParser extends BaseWatchable {
|
||||
|
||||
/**
|
||||
* emit a file of DCT stream data.
|
||||
*/
|
||||
/** emit a file of DCT stream data. */
|
||||
public final static String DEBUG_DCTDECODE_DATA = "debugdctdecode";
|
||||
static final boolean RELEASE = true;
|
||||
static final int PDF_CMDS_RANGE1_MIN = 1;
|
||||
|
|
@ -78,13 +76,11 @@ public class PDFParser extends BaseWatchable {
|
|||
private boolean resend = false;
|
||||
private Tok tok;
|
||||
private boolean catchexceptions; // Indicates state of BX...EX
|
||||
/**
|
||||
* a weak reference to the page we render into. For the page
|
||||
/** a weak reference to the page we render into. For the page
|
||||
* to remain available, some other code must retain a strong reference to it.
|
||||
*/
|
||||
private WeakReference pageRef;
|
||||
/**
|
||||
* the actual command, for use within a singe iteration. Note that
|
||||
/** the actual command, for use within a singe iteration. Note that
|
||||
* this must be released at the end of each iteration to assure the
|
||||
* page can be collected if not in use
|
||||
*/
|
||||
|
|
@ -92,7 +88,7 @@ public class PDFParser extends BaseWatchable {
|
|||
// ---- result variables
|
||||
byte[] stream;
|
||||
HashMap<String, PDFObject> resources;
|
||||
// public static int debuglevel = 4000;
|
||||
// public static int debuglevel = 4000;
|
||||
// TODO [FHe]: changed for debugging
|
||||
public static int debuglevel = -1;
|
||||
|
||||
|
|
@ -125,7 +121,7 @@ public class PDFParser extends BaseWatchable {
|
|||
* on to a PDFParser.
|
||||
*/
|
||||
public PDFParser(PDFPage cmds, byte[] stream,
|
||||
HashMap<String, PDFObject> resources) {
|
||||
HashMap<String, PDFObject> resources) {
|
||||
super();
|
||||
|
||||
this.pageRef = new WeakReference<PDFPage>(cmds);
|
||||
|
|
@ -141,76 +137,43 @@ public class PDFParser extends BaseWatchable {
|
|||
/////////////////////////////////////////////////////////////////
|
||||
// B E G I N R E A D E R S E C T I O N
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* a token from a PDF Stream
|
||||
*/
|
||||
static class Tok {
|
||||
|
||||
/**
|
||||
* begin bracket <
|
||||
*/
|
||||
/** begin bracket < */
|
||||
public static final int BRKB = 11;
|
||||
/**
|
||||
* end bracket >
|
||||
*/
|
||||
/** end bracket > */
|
||||
public static final int BRKE = 10;
|
||||
/**
|
||||
* begin array [
|
||||
*/
|
||||
/** begin array [ */
|
||||
public static final int ARYB = 9;
|
||||
/**
|
||||
* end array ]
|
||||
*/
|
||||
/** end array ] */
|
||||
public static final int ARYE = 8;
|
||||
/**
|
||||
* String (, readString looks for trailing )
|
||||
*/
|
||||
/** String (, readString looks for trailing ) */
|
||||
public static final int STR = 7;
|
||||
/**
|
||||
* begin brace {
|
||||
*/
|
||||
/** begin brace { */
|
||||
public static final int BRCB = 5;
|
||||
/**
|
||||
* end brace }
|
||||
*/
|
||||
/** end brace } */
|
||||
public static final int BRCE = 4;
|
||||
/**
|
||||
* number
|
||||
*/
|
||||
/** number */
|
||||
public static final int NUM = 3;
|
||||
/**
|
||||
* keyword
|
||||
*/
|
||||
/** keyword */
|
||||
public static final int CMD = 2;
|
||||
/**
|
||||
* name (begins with /)
|
||||
*/
|
||||
/** name (begins with /) */
|
||||
public static final int NAME = 1;
|
||||
/**
|
||||
* unknown token
|
||||
*/
|
||||
/** unknown token */
|
||||
public static final int UNK = 0;
|
||||
/**
|
||||
* end of stream
|
||||
*/
|
||||
/** end of stream */
|
||||
public static final int EOF = -1;
|
||||
/**
|
||||
* the string value of a STR, NAME, or CMD token
|
||||
*/
|
||||
/** the string value of a STR, NAME, or CMD token */
|
||||
public String name;
|
||||
/**
|
||||
* the value of a NUM token
|
||||
*/
|
||||
/** the value of a NUM token */
|
||||
public double value;
|
||||
/**
|
||||
* the type of the token
|
||||
*/
|
||||
/** the type of the token */
|
||||
public int type;
|
||||
|
||||
/**
|
||||
* a printable representation of the token
|
||||
*/
|
||||
/** a printable representation of the token */
|
||||
@Override
|
||||
public String toString() {
|
||||
if (type == NUM) {
|
||||
|
|
@ -409,7 +372,7 @@ public class PDFParser extends BaseWatchable {
|
|||
* character, which has already been read, and end with a balanced ')'
|
||||
* character. A '\' character starts an escape sequence of up
|
||||
* to three octal digits.</p>
|
||||
* <p/>
|
||||
*
|
||||
* <p>Parenthesis must be enclosed by a balanced set of parenthesis,
|
||||
* so a string may enclose balanced parenthesis.</p>
|
||||
*
|
||||
|
|
@ -421,7 +384,7 @@ public class PDFParser extends BaseWatchable {
|
|||
int parenLevel = 0;
|
||||
final StringBuffer sb = new StringBuffer();
|
||||
|
||||
for (int to = stream_.length; loc < to; ) {
|
||||
for (int to = stream_.length; loc < to;) {
|
||||
int c = stream_[loc++];
|
||||
if (c == ')') {
|
||||
if (parenLevel-- == 0) {
|
||||
|
|
@ -462,7 +425,7 @@ public class PDFParser extends BaseWatchable {
|
|||
* character, which has already been read, and end with a '>'
|
||||
* character. Each byte in the array is made up of two hex characters,
|
||||
* the first being the high-order bit.
|
||||
* <p/>
|
||||
*
|
||||
* We translate the byte arrays into char arrays by combining two bytes
|
||||
* into a character, and then translate the character array into a string.
|
||||
* [JK FIXME this is probably a really bad idea!]
|
||||
|
|
@ -477,7 +440,7 @@ public class PDFParser extends BaseWatchable {
|
|||
char w = (char) 0;
|
||||
|
||||
// read individual bytes and format into a character array
|
||||
for (int to = stream_.length; (loc < to) && (stream_[loc] != '>'); ) {
|
||||
for (int to = stream_.length; (loc < to) && (stream_[loc] != '>');) {
|
||||
final char c = (char) stream_[loc];
|
||||
byte b = (byte) 0;
|
||||
|
||||
|
|
@ -515,7 +478,6 @@ public class PDFParser extends BaseWatchable {
|
|||
/////////////////////////////////////////////////////////////////
|
||||
// B E G I N P A R S E R S E C T I O N
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Called to prepare for some iterations
|
||||
*/
|
||||
|
|
@ -543,16 +505,16 @@ public class PDFParser extends BaseWatchable {
|
|||
/**
|
||||
* parse the stream. commands are added to the PDFPage initialized
|
||||
* in the constructor as they are encountered.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Page numbers in comments refer to the Adobe PDF specification.<br>
|
||||
* commands are listed in PDF spec 32000-1:2008 in Table A.1
|
||||
*
|
||||
* @return <ul><li>Watchable.RUNNING when there are commands to be processed
|
||||
* <li>Watchable.COMPLETED when the page is done and all
|
||||
* the commands have been processed
|
||||
* <li>Watchable.STOPPED if the page we are rendering into is
|
||||
* no longer available
|
||||
* </ul>
|
||||
* <li>Watchable.COMPLETED when the page is done and all
|
||||
* the commands have been processed
|
||||
* <li>Watchable.STOPPED if the page we are rendering into is
|
||||
* no longer available
|
||||
* </ul>
|
||||
*/
|
||||
public int iterate() throws Exception {
|
||||
// make sure the page is still available, and create the reference
|
||||
|
|
@ -700,7 +662,7 @@ public class PDFParser extends BaseWatchable {
|
|||
path = new Path();
|
||||
break;
|
||||
case 'f':
|
||||
// the fall-through is intended!
|
||||
// the fall-through is intended!
|
||||
case 'F':
|
||||
// fill the path (close/not close identical)
|
||||
cmds.addPath(path, PDFShapeCmd.FILL | clip);
|
||||
|
|
@ -990,11 +952,11 @@ public class PDFParser extends BaseWatchable {
|
|||
break;
|
||||
case 'Q' + ('q' << 8):
|
||||
processQCmd();
|
||||
// 'q'-cmd
|
||||
// push the parser state
|
||||
parserStates.push((ParserState) state.clone());
|
||||
// push graphics state
|
||||
cmds.addPush();
|
||||
// 'q'-cmd
|
||||
// push the parser state
|
||||
parserStates.push((ParserState) state.clone());
|
||||
// push graphics state
|
||||
cmds.addPush();
|
||||
break;
|
||||
default:
|
||||
if (catchexceptions) {
|
||||
|
|
@ -1063,7 +1025,6 @@ public class PDFParser extends BaseWatchable {
|
|||
path = null;
|
||||
cmds = null;
|
||||
}
|
||||
|
||||
boolean errorwritten = false;
|
||||
|
||||
public void dumpStreamToError() {
|
||||
|
|
@ -1107,12 +1068,10 @@ public class PDFParser extends BaseWatchable {
|
|||
/////////////////////////////////////////////////////////////////
|
||||
// H E L P E R S
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* get a property from a named dictionary in the resources of this
|
||||
* content stream.
|
||||
*
|
||||
* @param name the name of the property in the dictionary
|
||||
* @param name the name of the property in the dictionary
|
||||
* @param inDict the name of the dictionary in the resources
|
||||
* @return the value of the property in the dictionary
|
||||
*/
|
||||
|
|
@ -1133,7 +1092,6 @@ public class PDFParser extends BaseWatchable {
|
|||
* Insert a PDF object into the command stream. The object must
|
||||
* either be an Image or a Form, which is a set of PDF commands
|
||||
* in a stream.
|
||||
*
|
||||
* @param obj the object to insert, an Image or a Form.
|
||||
*/
|
||||
private void doXObject(PDFObject obj) throws IOException {
|
||||
|
|
@ -1153,9 +1111,8 @@ public class PDFParser extends BaseWatchable {
|
|||
/**
|
||||
* Parse image data into a Java BufferedImage and add the image
|
||||
* command to the page.
|
||||
*
|
||||
* @param obj contains the image data, and a dictionary describing
|
||||
* the width, height and color space of the image.
|
||||
* the width, height and color space of the image.
|
||||
*/
|
||||
private void doImage(PDFObject obj) throws IOException {
|
||||
cmds.addImage(PDFImage.createImage(obj, resources));
|
||||
|
|
@ -1165,9 +1122,8 @@ public class PDFParser extends BaseWatchable {
|
|||
* Inject a stream of PDF commands onto the page. Optimized to cache
|
||||
* a parsed stream of commands, so that each Form object only needs
|
||||
* to be parsed once.
|
||||
*
|
||||
* @param obj a stream containing the PDF commands, a transformation
|
||||
* matrix, bounding box, and resources.
|
||||
* matrix, bounding box, and resources.
|
||||
*/
|
||||
private void doForm(PDFObject obj) throws IOException {
|
||||
// check to see if we've already parsed this sucker
|
||||
|
|
@ -1230,7 +1186,6 @@ public class PDFParser extends BaseWatchable {
|
|||
//
|
||||
// return patternSpace.getPaint(pattern, components, resources);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Parse the next object out of the PDF stream. This could be a
|
||||
* Double, a String, a HashMap (dictionary), Object[] array, or
|
||||
|
|
@ -1243,13 +1198,13 @@ public class PDFParser extends BaseWatchable {
|
|||
case Tok.NUM:
|
||||
return new Double(tok.value);
|
||||
case Tok.STR:
|
||||
// the fall-through is intended!
|
||||
// the fall-through is intended!
|
||||
case Tok.NAME:
|
||||
return tok.name;
|
||||
case Tok.BRKB: {
|
||||
final HashMap<String, PDFObject> hm = new HashMap<String, PDFObject>();
|
||||
String name = null;
|
||||
for (Object obj = null; (obj = parseObject()) != null; ) {
|
||||
for (Object obj = null; (obj = parseObject()) != null;) {
|
||||
if (name == null) {
|
||||
name = (String) obj;
|
||||
} else {
|
||||
|
|
@ -1265,7 +1220,7 @@ public class PDFParser extends BaseWatchable {
|
|||
case Tok.ARYB: {
|
||||
// build an array
|
||||
final ArrayList<Object> ary = new ArrayList<Object>();
|
||||
for (Object obj = null; (obj = parseObject()) != null; ) {
|
||||
for (Object obj = null; (obj = parseObject()) != null;) {
|
||||
ary.add(obj);
|
||||
}
|
||||
if (tok.type != Tok.ARYE) {
|
||||
|
|
@ -1396,7 +1351,6 @@ public class PDFParser extends BaseWatchable {
|
|||
|
||||
/**
|
||||
* add graphics state commands contained within a dictionary.
|
||||
*
|
||||
* @param name the resource name of the graphics state dictionary
|
||||
*/
|
||||
private void setGSState(String name) throws IOException {
|
||||
|
|
@ -1454,15 +1408,11 @@ public class PDFParser extends BaseWatchable {
|
|||
|
||||
/**
|
||||
* pop a single float value off the stack.
|
||||
*
|
||||
* @return the float value of the top of the stack
|
||||
* @throws PDFParseException if the value on the top of the stack
|
||||
* isn't a number
|
||||
* isn't a number
|
||||
*/
|
||||
private float popFloat() throws PDFParseException {
|
||||
if (stack.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
Object obj = stack.pop();
|
||||
if (obj instanceof Double) {
|
||||
return ((Double) obj).floatValue();
|
||||
|
|
@ -1475,11 +1425,10 @@ public class PDFParser extends BaseWatchable {
|
|||
* pop an array of float values off the stack. This is equivalent
|
||||
* to filling an array from end to front by popping values off the
|
||||
* stack.
|
||||
*
|
||||
* @param count the number of numbers to pop off the stack
|
||||
* @return an array of length <tt>count</tt>
|
||||
* @throws PDFParseException if any of the values popped off the
|
||||
* stack are not numbers.
|
||||
* stack are not numbers.
|
||||
*/
|
||||
private float[] popFloat(int count) throws PDFParseException {
|
||||
float[] ary = new float[count];
|
||||
|
|
@ -1491,7 +1440,6 @@ public class PDFParser extends BaseWatchable {
|
|||
|
||||
/**
|
||||
* pop a single integer value off the stack.
|
||||
*
|
||||
* @return the integer value of the top of the stack
|
||||
* @throws PDFParseException if the top of the stack isn't a number.
|
||||
*/
|
||||
|
|
@ -1508,11 +1456,10 @@ public class PDFParser extends BaseWatchable {
|
|||
* pop an array of integer values off the stack. This is equivalent
|
||||
* to filling an array from end to front by popping values off the
|
||||
* stack.
|
||||
*
|
||||
* @param count the number of numbers to pop off the stack
|
||||
* @return an array of length <tt>count</tt>
|
||||
* @throws PDFParseException if any of the values popped off the
|
||||
* stack are not numbers.
|
||||
* stack are not numbers.
|
||||
*/
|
||||
private float[] popFloatArray() throws PDFParseException {
|
||||
Object obj = stack.pop();
|
||||
|
|
@ -1533,10 +1480,9 @@ public class PDFParser extends BaseWatchable {
|
|||
|
||||
/**
|
||||
* pop a String off the stack.
|
||||
*
|
||||
* @return the String from the top of the stack
|
||||
* @throws PDFParseException if the top of the stack is not a NAME
|
||||
* or STR.
|
||||
* or STR.
|
||||
*/
|
||||
private String popString() throws PDFParseException {
|
||||
Object obj = stack.pop();
|
||||
|
|
@ -1549,10 +1495,9 @@ public class PDFParser extends BaseWatchable {
|
|||
|
||||
/**
|
||||
* pop a PDFObject off the stack.
|
||||
*
|
||||
* @return the PDFObject from the top of the stack
|
||||
* @throws PDFParseException if the top of the stack does not contain
|
||||
* a PDFObject.
|
||||
* a PDFObject.
|
||||
*/
|
||||
private PDFObject popObject() throws PDFParseException {
|
||||
Object obj = stack.pop();
|
||||
|
|
@ -1564,10 +1509,9 @@ public class PDFParser extends BaseWatchable {
|
|||
|
||||
/**
|
||||
* pop an array off the stack
|
||||
*
|
||||
* @return the array of objects that is the top element of the stack
|
||||
* @throws PDFParseException if the top element of the stack does not
|
||||
* contain an array.
|
||||
* contain an array.
|
||||
*/
|
||||
private Object[] popArray() throws PDFParseException {
|
||||
Object obj = stack.pop();
|
||||
|
|
@ -1584,17 +1528,11 @@ public class PDFParser extends BaseWatchable {
|
|||
*/
|
||||
class ParserState implements Cloneable {
|
||||
|
||||
/**
|
||||
* the fill color space
|
||||
*/
|
||||
/** the fill color space */
|
||||
PDFColorSpace fillCS;
|
||||
/**
|
||||
* the stroke color space
|
||||
*/
|
||||
/** the stroke color space */
|
||||
PDFColorSpace strokeCS;
|
||||
/**
|
||||
* the text paramters
|
||||
*/
|
||||
/** the text paramters */
|
||||
PDFTextFormat textFormat;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* $Id: CalRGBColor.java,v 1.2 2007/12/20 18:33:34 rbair Exp $
|
||||
*
|
||||
* Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
|
||||
* Santa Clara, California 95054, U.S.A. All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package com.sun.pdfview.colorspace;
|
||||
|
||||
import android.graphics.Color;
|
||||
|
||||
public class ICCIColorSpace extends PDFColorSpace {
|
||||
|
||||
public ICCIColorSpace() {
|
||||
}
|
||||
|
||||
/**
|
||||
* get the number of components (3)
|
||||
*/
|
||||
@Override public int getNumComponents() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override public int toColor(float[] fcomp) {
|
||||
return Color.rgb((int)(fcomp[0]*255),(int)(fcomp[1]*255),(int)(fcomp[2]*255));
|
||||
}
|
||||
|
||||
@Override public int toColor(int[] icomp) {
|
||||
return Color.rgb(icomp[0],icomp[1],icomp[2]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the type of this color space (TYPE_RGB)
|
||||
*/
|
||||
@Override public int getType() {
|
||||
return COLORSPACE_GRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "RGB";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -28,186 +28,187 @@ import com.sun.pdfview.PDFPaint;
|
|||
import com.sun.pdfview.PDFParseException;
|
||||
import com.sun.pdfview.function.PDFFunction;
|
||||
|
||||
|
||||
/**
|
||||
* A color space that can convert a set of color components into
|
||||
* PDFPaint.
|
||||
*
|
||||
* @author Mike Wessler
|
||||
*/
|
||||
public abstract class PDFColorSpace {
|
||||
|
||||
/** the name of the device-dependent gray color space */
|
||||
public static final int COLORSPACE_GRAY = 0;
|
||||
|
||||
/** the name of the device-dependent gray color space */
|
||||
public static final int COLORSPACE_GRAY = 0;
|
||||
/** the name of the device-dependent RGB color space */
|
||||
public static final int COLORSPACE_RGB = 1;
|
||||
|
||||
/** the name of the device-dependent RGB color space */
|
||||
public static final int COLORSPACE_RGB = 1;
|
||||
/** the name of the device-dependent CMYK color space */
|
||||
public static final int COLORSPACE_CMYK = 2;
|
||||
|
||||
/** the name of the device-dependent CMYK color space */
|
||||
public static final int COLORSPACE_CMYK = 2;
|
||||
/** the name of the pattern color space */
|
||||
public static final int COLORSPACE_PATTERN = 3;
|
||||
|
||||
/** the name of the pattern color space */
|
||||
public static final int COLORSPACE_PATTERN = 3;
|
||||
public static final int COLORSPACE_INDEXED = 4;
|
||||
|
||||
public static final int COLORSPACE_INDEXED = 4;
|
||||
public static final int COLORSPACE_ALTERNATE = 5;
|
||||
|
||||
public static final int COLORSPACE_ALTERNATE = 5;
|
||||
/** the device-dependent color spaces */
|
||||
// private static PDFColorSpace graySpace =
|
||||
// new PDFColorSpace(ColorSpace.getInstance(ColorSpace.CS_GRAY));
|
||||
private static PDFColorSpace rgbSpace = new RGBColorSpace();
|
||||
private static PDFColorSpace cmykSpace = new CMYKColorSpace();
|
||||
|
||||
/** the device-dependent color spaces */
|
||||
// private static PDFColorSpace graySpace =
|
||||
// new PDFColorSpace(ColorSpace.getInstance(ColorSpace.CS_GRAY));
|
||||
private static PDFColorSpace rgbSpace = new RGBColorSpace();
|
||||
private static PDFColorSpace cmykSpace = new CMYKColorSpace();
|
||||
private static PDFColorSpace icciSpace = new ICCIColorSpace();
|
||||
/** the pattern space */
|
||||
private static PDFColorSpace patternSpace = new RGBColorSpace(); // TODO [FHe]
|
||||
/** the pattern space */
|
||||
private static PDFColorSpace patternSpace = new RGBColorSpace(); // TODO [FHe]
|
||||
|
||||
/** graySpace and the gamma correction for it. */
|
||||
private static PDFColorSpace graySpace = new GrayColorSpace();
|
||||
/** graySpace and the gamma correction for it. */
|
||||
private static PDFColorSpace graySpace = new GrayColorSpace();
|
||||
|
||||
/**
|
||||
* create a PDFColorSpace based on a Java ColorSpace
|
||||
*
|
||||
* @param cs the Java ColorSpace
|
||||
*/
|
||||
protected PDFColorSpace() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a color space by name
|
||||
*
|
||||
* @param name the name of one of the device-dependent color spaces
|
||||
*/
|
||||
public static PDFColorSpace getColorSpace(int name) {
|
||||
switch (name) {
|
||||
case COLORSPACE_GRAY:
|
||||
return graySpace;
|
||||
|
||||
case COLORSPACE_RGB:
|
||||
return rgbSpace;
|
||||
|
||||
case COLORSPACE_CMYK:
|
||||
return cmykSpace;
|
||||
|
||||
case COLORSPACE_PATTERN:
|
||||
return patternSpace;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown Color Space name: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a color space specified in a PDFObject
|
||||
*
|
||||
* @param csobj the PDFObject with the colorspace information
|
||||
*/
|
||||
public static PDFColorSpace getColorSpace(PDFObject csobj, Map resources) throws IOException {
|
||||
String name;
|
||||
|
||||
PDFObject colorSpaces = null;
|
||||
|
||||
if (resources != null) {
|
||||
colorSpaces = (PDFObject) resources.get("ColorSpace");
|
||||
/**
|
||||
* create a PDFColorSpace based on a Java ColorSpace
|
||||
* @param cs the Java ColorSpace
|
||||
*/
|
||||
protected PDFColorSpace() {
|
||||
}
|
||||
|
||||
if (csobj.getType() == PDFObject.NAME) {
|
||||
name = csobj.getStringValue();
|
||||
/**
|
||||
* Get a color space by name
|
||||
*
|
||||
* @param name the name of one of the device-dependent color spaces
|
||||
*/
|
||||
public static PDFColorSpace getColorSpace(int name) {
|
||||
switch (name) {
|
||||
case COLORSPACE_GRAY:
|
||||
return graySpace;
|
||||
|
||||
if (name.equals("DeviceGray") || name.equals("G")) {
|
||||
return getColorSpace(COLORSPACE_GRAY);
|
||||
} else if (name.equals("DeviceRGB") || name.equals("RGB")) {
|
||||
return getColorSpace(COLORSPACE_RGB);
|
||||
} else if (name.equals("DeviceCMYK") || name.equals("CMYK")) {
|
||||
return getColorSpace(COLORSPACE_CMYK);
|
||||
} else if (name.equals("Pattern")) {
|
||||
return getColorSpace(COLORSPACE_PATTERN);
|
||||
} else if (colorSpaces != null) {
|
||||
csobj = (PDFObject) colorSpaces.getDictRef(name);
|
||||
}
|
||||
case COLORSPACE_RGB:
|
||||
return rgbSpace;
|
||||
|
||||
case COLORSPACE_CMYK:
|
||||
return cmykSpace;
|
||||
|
||||
case COLORSPACE_PATTERN:
|
||||
return patternSpace;
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown Color Space name: " +
|
||||
name);
|
||||
}
|
||||
}
|
||||
|
||||
if (csobj == null) {
|
||||
return null;
|
||||
} else if (csobj.getCache() != null) {
|
||||
return (PDFColorSpace) csobj.getCache();
|
||||
/**
|
||||
* Get a color space specified in a PDFObject
|
||||
*
|
||||
* @param csobj the PDFObject with the colorspace information
|
||||
*/
|
||||
public static PDFColorSpace getColorSpace(PDFObject csobj, Map resources)
|
||||
throws IOException {
|
||||
String name;
|
||||
|
||||
PDFObject colorSpaces = null;
|
||||
|
||||
if (resources != null) {
|
||||
colorSpaces = (PDFObject) resources.get("ColorSpace");
|
||||
}
|
||||
|
||||
if (csobj.getType() == PDFObject.NAME) {
|
||||
name = csobj.getStringValue();
|
||||
|
||||
if (name.equals("DeviceGray") || name.equals("G")) {
|
||||
return getColorSpace(COLORSPACE_GRAY);
|
||||
} else if (name.equals("DeviceRGB") || name.equals("RGB")) {
|
||||
return getColorSpace(COLORSPACE_RGB);
|
||||
} else if (name.equals("DeviceCMYK") || name.equals("CMYK")) {
|
||||
return getColorSpace(COLORSPACE_CMYK);
|
||||
} else if (name.equals("Pattern")) {
|
||||
return getColorSpace(COLORSPACE_PATTERN);
|
||||
} else if (colorSpaces != null) {
|
||||
csobj = (PDFObject) colorSpaces.getDictRef(name);
|
||||
}
|
||||
}
|
||||
|
||||
if (csobj == null) {
|
||||
return null;
|
||||
} else if (csobj.getCache() != null) {
|
||||
return (PDFColorSpace) csobj.getCache();
|
||||
}
|
||||
|
||||
PDFColorSpace value = null;
|
||||
|
||||
// csobj is [/name <<dict>>]
|
||||
PDFObject[] ary = csobj.getArray();
|
||||
name = ary[0].getStringValue();
|
||||
|
||||
if (name.equals("CalGray")) {
|
||||
value = graySpace; // TODO [FHe]
|
||||
} else if (name.equals("CalRGB")) {
|
||||
value = rgbSpace; // TODO [FHe]
|
||||
} else if (name.equals("Lab")) {
|
||||
value = rgbSpace; // TODO [FHe]
|
||||
} else if (name.equals("ICCBased")) {
|
||||
value = rgbSpace; // TODO [FHe]
|
||||
} else if (name.equals("Separation") || name.equals("DeviceN")) {
|
||||
PDFColorSpace alternate = getColorSpace(ary[2], resources);
|
||||
PDFFunction function = PDFFunction.getFunction(ary[3]);
|
||||
value = new AlternateColorSpace(alternate, function);
|
||||
} else if (name.equals("Indexed") || name.equals("I")) {
|
||||
/**
|
||||
* 4.5.5 [/Indexed baseColor hival lookup]
|
||||
*/
|
||||
PDFColorSpace refspace = getColorSpace(ary[1], resources);
|
||||
|
||||
// number of indices= ary[2], data is in ary[3];
|
||||
int count = ary[2].getIntValue();
|
||||
value = new IndexedColor(refspace, count, ary[3]);
|
||||
} else if (name.equals("Pattern")) {
|
||||
return rgbSpace; // TODO [FHe]
|
||||
} else {
|
||||
throw new PDFParseException("Unknown color space: " + name +
|
||||
" with " + ary[1]);
|
||||
}
|
||||
|
||||
csobj.setCache(value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
PDFColorSpace value = null;
|
||||
/**
|
||||
* get the number of components expected in the getPaint command
|
||||
*/
|
||||
public abstract int getNumComponents();
|
||||
|
||||
// csobj is [/name <<dict>>]
|
||||
PDFObject[] ary = csobj.getArray();
|
||||
name = ary[0].getStringValue();
|
||||
|
||||
if (name.equals("CalGray")) {
|
||||
value = graySpace; // TODO [FHe]
|
||||
} else if (name.equals("CalRGB")) {
|
||||
value = rgbSpace; // TODO [FHe]
|
||||
} else if (name.equals("Lab")) {
|
||||
value = rgbSpace; // TODO [FHe]
|
||||
} else if (name.equals("ICCBased")) {
|
||||
value = rgbSpace;//icciSpace; // TODO [FHe]
|
||||
} else if (name.equals("Separation") || name.equals("DeviceN")) {
|
||||
PDFColorSpace alternate = getColorSpace(ary[2], resources);
|
||||
PDFFunction function = PDFFunction.getFunction(ary[3]);
|
||||
value = new AlternateColorSpace(alternate, function);
|
||||
} else if (name.equals("Indexed") || name.equals("I")) {
|
||||
/**
|
||||
* 4.5.5 [/Indexed baseColor hival lookup]
|
||||
*/
|
||||
PDFColorSpace refspace = getColorSpace(ary[1], resources);
|
||||
|
||||
// number of indices= ary[2], data is in ary[3];
|
||||
int count = ary[2].getIntValue();
|
||||
value = new IndexedColor(refspace, count, ary[3]);
|
||||
} else if (name.equals("Pattern")) {
|
||||
return rgbSpace; // TODO [FHe]
|
||||
} else {
|
||||
throw new PDFParseException("Unknown color space: " + name +
|
||||
" with " + ary[1]);
|
||||
/**
|
||||
* get the PDFPaint representing the color described by the
|
||||
* given color components
|
||||
* @param components the color components corresponding to the given
|
||||
* colorspace
|
||||
* @return a PDFPaint object representing the closest Color to the
|
||||
* given components.
|
||||
*/
|
||||
public PDFPaint getPaint(float[] components) {
|
||||
return PDFPaint.getColorPaint(toColor(components));
|
||||
}
|
||||
public PDFPaint getFillPaint(float[] components) {
|
||||
return PDFPaint.getPaint(toColor(components));
|
||||
}
|
||||
|
||||
csobj.setCache(value);
|
||||
/**
|
||||
* get the type of this color space
|
||||
*/
|
||||
public abstract int getType();
|
||||
/**
|
||||
* get the name of this color space
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
return value;
|
||||
}
|
||||
public abstract int toColor(float[] fcomp);
|
||||
|
||||
public abstract int toColor(int[] icomp);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ColorSpace["+getName()+"]";
|
||||
}
|
||||
|
||||
/**
|
||||
* get the number of components expected in the getPaint command
|
||||
*/
|
||||
public abstract int getNumComponents();
|
||||
|
||||
/**
|
||||
* get the PDFPaint representing the color described by the
|
||||
* given color components
|
||||
*
|
||||
* @param components the color components corresponding to the given
|
||||
* colorspace
|
||||
* @return a PDFPaint object representing the closest Color to the
|
||||
* given components.
|
||||
*/
|
||||
public PDFPaint getPaint(float[] components) {
|
||||
return PDFPaint.getColorPaint(toColor(components));
|
||||
}
|
||||
|
||||
public PDFPaint getFillPaint(float[] components) {
|
||||
return PDFPaint.getPaint(toColor(components));
|
||||
}
|
||||
|
||||
/**
|
||||
* get the type of this color space
|
||||
*/
|
||||
public abstract int getType();
|
||||
|
||||
/**
|
||||
* get the name of this color space
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
public abstract int toColor(float[] fcomp);
|
||||
|
||||
public abstract int toColor(int[] icomp);
|
||||
|
||||
@Override public String toString() {
|
||||
return "ColorSpace[" + getName() + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,13 +21,19 @@
|
|||
|
||||
package com.sun.pdfview.decode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
import net.sf.andpdf.nio.ByteBuffer;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.Config;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Bitmap.Config;
|
||||
import android.util.Log;
|
||||
|
||||
import com.sun.pdfview.PDFObject;
|
||||
import com.sun.pdfview.PDFParseException;
|
||||
import net.sf.andpdf.nio.ByteBuffer;
|
||||
import com.sun.pdfview.colorspace.PDFColorSpace;
|
||||
|
||||
/**
|
||||
* decode a DCT encoded array into a byte array. This class uses Java's
|
||||
|
|
@ -37,49 +43,52 @@ import net.sf.andpdf.nio.ByteBuffer;
|
|||
*/
|
||||
public class DCTDecode {
|
||||
|
||||
/**
|
||||
* decode an array of bytes in DCT format.
|
||||
* <p>
|
||||
* DCT is the format used by JPEG images, so this class simply
|
||||
* loads the DCT-format bytes as an image, then reads the bytes out
|
||||
* of the image to create the array. Unfortunately, their most
|
||||
* likely use is to get turned BACK into an image, so this isn't
|
||||
* terribly efficient... but is is general... don't hit, please.
|
||||
* <p>
|
||||
* The DCT-encoded stream may have 1, 3 or 4 samples per pixel, depending
|
||||
* on the colorspace of the image. In decoding, we look for the colorspace
|
||||
* in the stream object's dictionary to decide how to decode this image.
|
||||
* If no colorspace is present, we guess 3 samples per pixel.
|
||||
*
|
||||
* @param dict the stream dictionary
|
||||
* @param buf the DCT-encoded buffer
|
||||
* @param params the parameters to the decoder (ignored)
|
||||
* @return the decoded buffer
|
||||
*/
|
||||
protected static ByteBuffer decode(PDFObject dict, ByteBuffer buf, PDFObject params) throws PDFParseException {
|
||||
// System.out.println("DCTDecode image info: "+params);
|
||||
buf.rewind();
|
||||
/**
|
||||
* decode an array of bytes in DCT format.
|
||||
* <p>
|
||||
* DCT is the format used by JPEG images, so this class simply
|
||||
* loads the DCT-format bytes as an image, then reads the bytes out
|
||||
* of the image to create the array. Unfortunately, their most
|
||||
* likely use is to get turned BACK into an image, so this isn't
|
||||
* terribly efficient... but is is general... don't hit, please.
|
||||
* <p>
|
||||
* The DCT-encoded stream may have 1, 3 or 4 samples per pixel, depending
|
||||
* on the colorspace of the image. In decoding, we look for the colorspace
|
||||
* in the stream object's dictionary to decide how to decode this image.
|
||||
* If no colorspace is present, we guess 3 samples per pixel.
|
||||
*
|
||||
* @param dict the stream dictionary
|
||||
* @param buf the DCT-encoded buffer
|
||||
* @param params the parameters to the decoder (ignored)
|
||||
* @return the decoded buffer
|
||||
*/
|
||||
protected static ByteBuffer decode(PDFObject dict, ByteBuffer buf,
|
||||
PDFObject params) throws PDFParseException
|
||||
{
|
||||
// System.out.println("DCTDecode image info: "+params);
|
||||
buf.rewind();
|
||||
|
||||
// copy the data into a byte array required by createimage
|
||||
byte[] ary = new byte[buf.remaining()];
|
||||
buf.get(ary);
|
||||
|
||||
// copy the data into a byte array required by createimage
|
||||
byte[] ary = new byte[buf.remaining()];
|
||||
buf.get(ary);
|
||||
Bitmap img = BitmapFactory.decodeByteArray(ary, 0, ary.length);
|
||||
Bitmap img = BitmapFactory.decodeByteArray(ary, 0, ary.length);
|
||||
|
||||
if (img == null) throw new PDFParseException("could not decode image of compressed size " + ary.length);
|
||||
Config conf = img.getConfig();
|
||||
Log.e("ANDPDF.dctdecode", "decoded image type" + conf);
|
||||
int size = 4 * img.getWidth() * img.getHeight();
|
||||
if (conf == Config.RGB_565) {
|
||||
size = 2 * img.getWidth() * img.getHeight();
|
||||
if (img == null)
|
||||
throw new PDFParseException("could not decode image of compressed size "+ary.length);
|
||||
Config conf = img.getConfig();
|
||||
Log.e("ANDPDF.dctdecode", "decoded image type"+conf);
|
||||
int size = 4*img.getWidth()*img.getHeight();
|
||||
if (conf == Config.RGB_565)
|
||||
size = 2*img.getWidth()*img.getHeight();
|
||||
// TODO [FHe]: else ... what do we get for gray? Config.ALPHA_8?
|
||||
|
||||
java.nio.ByteBuffer byteBuf = java.nio.ByteBuffer.allocate(size);
|
||||
img.copyPixelsToBuffer(byteBuf);
|
||||
|
||||
ByteBuffer result = ByteBuffer.fromNIO(byteBuf);
|
||||
result.rewind();
|
||||
return result;
|
||||
}
|
||||
// TODO [FHe]: else ... what do we get for gray? Config.ALPHA_8?
|
||||
|
||||
java.nio.ByteBuffer byteBuf = java.nio.ByteBuffer.allocate(size);
|
||||
img.copyPixelsToBuffer(byteBuf);
|
||||
ByteBuffer result = ByteBuffer.fromNIO(byteBuf);
|
||||
result.rewind();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,17 @@
|
|||
package net.sf.andpdf.pdfviewer;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
|
|
@ -25,7 +20,6 @@ import android.view.inputmethod.InputMethodManager;
|
|||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
|
@ -43,7 +37,6 @@ import net.sf.andpdf.nio.ByteBuffer;
|
|||
import net.sf.andpdf.refs.HardReference;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import uk.co.senab.photoview.PhotoViewAttacher;
|
||||
|
||||
|
|
@ -64,8 +57,6 @@ public class PdfViewerFragment extends Fragment {
|
|||
public static final boolean DEFAULTANTIALIAS = true;
|
||||
public static final boolean DEFAULTUSEFONTSUBSTITUTION = false;
|
||||
|
||||
public static final String DIALOG_FRAGMENT_TAG_MARK = "DIALOG_FRAGMENT";
|
||||
|
||||
private GraphView mGraphView;
|
||||
private PDFFile mPdfFile;
|
||||
public static byte[] byteArray;
|
||||
|
|
@ -221,13 +212,6 @@ public class PdfViewerFragment extends Fragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void gotoPage() {
|
||||
if (mPdfFile != null) {
|
||||
final Bundle bundle = new Bundle();
|
||||
showDialogFragment(new GoToPageDialogFragment(), bundle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides device keyboard that is showing over {@link Activity}.
|
||||
* Do NOT use it if keyboard is over {@link android.app.Dialog} - it won't work as they have different {@link Activity#getWindow()}.
|
||||
|
|
@ -241,78 +225,11 @@ public class PdfViewerFragment extends Fragment {
|
|||
getActivity().getWindow().getDecorView().requestFocus();
|
||||
}
|
||||
|
||||
public class GoToPageDialogFragment extends DialogFragment {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(final Bundle savedInstanceState) {
|
||||
LayoutInflater factory = LayoutInflater.from(getActivity());
|
||||
final View pagenumView = factory.inflate(R.layout.dialog_pagenumber, null);
|
||||
final EditText edPagenum = (EditText) pagenumView.findViewById(R.id.pagenum_edit);
|
||||
edPagenum.setText(String.format(Locale.getDefault(), "%d", mPage));
|
||||
edPagenum.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||
|
||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||
if (event == null || (event.getAction() == 1)) {
|
||||
// Hide the keyboard
|
||||
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(edPagenum.getWindowToken(), 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
//.setIcon(R.drawable.icon)
|
||||
.setTitle("Jump to page")
|
||||
.setView(pagenumView)
|
||||
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
String strPagenum = edPagenum.getText().toString();
|
||||
int pageNum = mPage;
|
||||
try {
|
||||
pageNum = Integer.parseInt(strPagenum);
|
||||
} catch (NumberFormatException ignore) {
|
||||
}
|
||||
if ((pageNum != mPage) && (pageNum >= 1) && (pageNum <= mPdfFile.getNumPages())) {
|
||||
mPage = pageNum;
|
||||
mGraphView.bZoomOut.setEnabled(true);
|
||||
mGraphView.bZoomIn.setEnabled(true);
|
||||
progress = ProgressDialog.show(getActivity(), "Loading", "Loading PDF Page " + mPage, true, true);
|
||||
startRenderThread(mPage);
|
||||
}
|
||||
}
|
||||
})
|
||||
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichButton) {
|
||||
}
|
||||
})
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
public void showDialogFragment(@NonNull final DialogFragment dialogFragment, @Nullable final Bundle bundle) {
|
||||
if (getFragmentManager().getFragments() != null) {
|
||||
for (final Fragment fragment : getFragmentManager().getFragments()) {
|
||||
// to fix bug with opening fragment several times on fast clicking
|
||||
if (fragment != null && fragment.getClass() == dialogFragment.getClass()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bundle != null) {
|
||||
dialogFragment.setArguments(bundle);
|
||||
}
|
||||
dialogFragment.show(getFragmentManager(), dialogFragment.getClass().getName() + ";" + DIALOG_FRAGMENT_TAG_MARK);
|
||||
}
|
||||
|
||||
private class GraphView extends FrameLayout {
|
||||
public Bitmap mBi;
|
||||
public ImageView pdfZoomedImageView;
|
||||
public PhotoViewAttacher photoViewAttacher;
|
||||
|
||||
ImageButton bZoomOut;
|
||||
ImageButton bZoomIn;
|
||||
|
||||
public GraphView(Context context) {
|
||||
super(context);
|
||||
|
||||
|
|
@ -366,70 +283,64 @@ public class PdfViewerFragment extends Fragment {
|
|||
// TODO: refactor
|
||||
private void showPage(final int page) {
|
||||
// on some Android getWidth() and getHeight() returns 0, so we need to wait until UI is ready
|
||||
mGraphView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// free memory from previous page
|
||||
mGraphView.setPageBitmap(null);
|
||||
mGraphView.updateImage();
|
||||
try {
|
||||
// free memory from previous page
|
||||
mGraphView.setPageBitmap(null);
|
||||
mGraphView.updateImage();
|
||||
|
||||
// Only load the page if it's a different page (i.e. not just changing the zoom level)
|
||||
if (mPdfPage == null || mPdfPage.getPageNumber() != page) {
|
||||
mPdfPage = mPdfFile.getPage(page, true);
|
||||
}
|
||||
// Only load the page if it's a different page (i.e. not just changing the zoom level)
|
||||
if (mPdfPage == null || mPdfPage.getPageNumber() != page) {
|
||||
mPdfPage = mPdfFile.getPage(page, true);
|
||||
}
|
||||
|
||||
final int scale = 3;
|
||||
final int scale = 3;
|
||||
|
||||
double width = mPdfPage.getWidth() * scale;
|
||||
double height = mPdfPage.getHeight() * scale;
|
||||
double width = mPdfPage.getWidth() * scale;
|
||||
double height = mPdfPage.getHeight() * scale;
|
||||
|
||||
int maxWidthToPopulate = mGraphView.getWidth();
|
||||
int maxHeightToPopulate = mGraphView.getHeight();
|
||||
int maxWidthToPopulate = mGraphView.getWidth();
|
||||
int maxHeightToPopulate = mGraphView.getHeight();
|
||||
|
||||
int calculatedWidth;
|
||||
int calculatedHeight;
|
||||
final double widthRatio = width / maxWidthToPopulate;
|
||||
final double heightRatio = height / maxHeightToPopulate;
|
||||
if (width < maxWidthToPopulate && height < maxHeightToPopulate) {
|
||||
if (widthRatio > heightRatio) {
|
||||
calculatedWidth = (int) (width / widthRatio);
|
||||
calculatedHeight = (int) (height / widthRatio);
|
||||
} else {
|
||||
calculatedWidth = (int) (width / heightRatio);
|
||||
calculatedHeight = (int) (height / heightRatio);
|
||||
}
|
||||
int calculatedWidth;
|
||||
int calculatedHeight;
|
||||
final double widthRatio = width / maxWidthToPopulate;
|
||||
final double heightRatio = height / maxHeightToPopulate;
|
||||
if (width < maxWidthToPopulate && height < maxHeightToPopulate) {
|
||||
if (widthRatio > heightRatio) {
|
||||
calculatedWidth = (int) (width / widthRatio);
|
||||
calculatedHeight = (int) (height / widthRatio);
|
||||
} else {
|
||||
calculatedWidth = (int) (width / heightRatio);
|
||||
calculatedHeight = (int) (height / heightRatio);
|
||||
}
|
||||
} else {
|
||||
if (widthRatio > 1 && heightRatio > 1) {
|
||||
if (widthRatio > heightRatio) {
|
||||
calculatedHeight = (int) (height / widthRatio);
|
||||
calculatedWidth = (int) (width / widthRatio);
|
||||
} else {
|
||||
if (widthRatio > 1 && heightRatio > 1) {
|
||||
if (widthRatio > heightRatio) {
|
||||
calculatedHeight = (int) (height / widthRatio);
|
||||
calculatedWidth = (int) (width / widthRatio);
|
||||
} else {
|
||||
calculatedHeight = (int) (height / heightRatio);
|
||||
calculatedWidth = (int) (width / heightRatio);
|
||||
}
|
||||
} else {
|
||||
if (widthRatio > heightRatio) {
|
||||
calculatedHeight = (int) (height / widthRatio);
|
||||
calculatedWidth = (int) (width / widthRatio);
|
||||
} else {
|
||||
calculatedHeight = (int) (height / heightRatio);
|
||||
calculatedWidth = (int) (width / heightRatio);
|
||||
}
|
||||
}
|
||||
calculatedHeight = (int) (height / heightRatio);
|
||||
calculatedWidth = (int) (width / heightRatio);
|
||||
}
|
||||
} else {
|
||||
if (widthRatio > heightRatio) {
|
||||
calculatedHeight = (int) (height / widthRatio);
|
||||
calculatedWidth = (int) (width / widthRatio);
|
||||
} else {
|
||||
calculatedHeight = (int) (height / heightRatio);
|
||||
calculatedWidth = (int) (width / heightRatio);
|
||||
}
|
||||
|
||||
final Bitmap bitmap = mPdfPage.getImage(calculatedWidth, calculatedHeight, null, true, true);
|
||||
mGraphView.setPageBitmap(bitmap);
|
||||
mGraphView.updateImage();
|
||||
} catch (Throwable e) {
|
||||
Log.e(TAG, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final Bitmap bitmap = mPdfPage.getImage(calculatedWidth, calculatedHeight, null, true, true);
|
||||
mGraphView.setPageBitmap(bitmap);
|
||||
mGraphView.updateImage();
|
||||
} catch (Throwable e) {
|
||||
Log.e(TAG, e.getMessage(), e);
|
||||
}
|
||||
|
||||
hideProgressBar();
|
||||
|
||||
}
|
||||
|
||||
private void hideProgressBar() {
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jason Polites
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.andpdf.utils;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.util.FloatMath;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
public class MathUtils {
|
||||
|
||||
public static float distance(MotionEvent event) {
|
||||
float x = event.getX(0) - event.getX(1);
|
||||
float y = event.getY(0) - event.getY(1);
|
||||
return FloatMath.sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
public static float distance(PointF p1, PointF p2) {
|
||||
float x = p1.x - p2.x;
|
||||
float y = p1.y - p2.y;
|
||||
return FloatMath.sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
public static float distance(float x1, float y1, float x2, float y2) {
|
||||
float x = x1 - x2;
|
||||
float y = y1 - y2;
|
||||
return FloatMath.sqrt(x * x + y * y);
|
||||
}
|
||||
|
||||
public static void midpoint(MotionEvent event, PointF point) {
|
||||
float x1 = event.getX(0);
|
||||
float y1 = event.getY(0);
|
||||
float x2 = event.getX(1);
|
||||
float y2 = event.getY(1);
|
||||
midpoint(x1, y1, x2, y2, point);
|
||||
}
|
||||
|
||||
public static void midpoint(float x1, float y1, float x2, float y2, PointF point) {
|
||||
point.x = (x1 + x2) / 2.0f;
|
||||
point.y = (y1 + y2) / 2.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotates p1 around p2 by angle degrees.
|
||||
*
|
||||
* @param p1
|
||||
* @param p2
|
||||
* @param angle
|
||||
*/
|
||||
public void rotate(PointF p1, PointF p2, float angle) {
|
||||
float px = p1.x;
|
||||
float py = p1.y;
|
||||
float ox = p2.x;
|
||||
float oy = p2.y;
|
||||
p1.x = (FloatMath.cos(angle) * (px - ox) - FloatMath.sin(angle) * (py - oy) + ox);
|
||||
p1.y = (FloatMath.sin(angle) * (px - ox) + FloatMath.cos(angle) * (py - oy) + oy);
|
||||
}
|
||||
|
||||
public static float angle(PointF p1, PointF p2) {
|
||||
return angle(p1.x, p1.y, p2.x, p2.y);
|
||||
}
|
||||
|
||||
public static float angle(float x1, float y1, float x2, float y2) {
|
||||
return (float) Math.atan2(y2 - y1, x2 - x1);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2012 Jason Polites
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.sf.andpdf.utils;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.util.FloatMath;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
public class VectorF {
|
||||
|
||||
public float angle;
|
||||
public float length;
|
||||
|
||||
public final PointF start = new PointF();
|
||||
public final PointF end = new PointF();
|
||||
|
||||
public void calculateEndPoint() {
|
||||
end.x = FloatMath.cos(angle) * length + start.x;
|
||||
end.y = FloatMath.sin(angle) * length + start.y;
|
||||
}
|
||||
|
||||
public void setStart(PointF p) {
|
||||
this.start.x = p.x;
|
||||
this.start.y = p.y;
|
||||
}
|
||||
|
||||
public void setEnd(PointF p) {
|
||||
this.end.x = p.x;
|
||||
this.end.y = p.y;
|
||||
}
|
||||
|
||||
public void set(MotionEvent event) {
|
||||
this.start.x = event.getX(0);
|
||||
this.start.y = event.getY(0);
|
||||
this.end.x = event.getX(1);
|
||||
this.end.y = event.getY(1);
|
||||
}
|
||||
|
||||
public float calculateLength() {
|
||||
length = MathUtils.distance(start, end);
|
||||
return length;
|
||||
}
|
||||
|
||||
public float calculateAngle() {
|
||||
angle = MathUtils.angle(start, end);
|
||||
return angle;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue