
org.jpedal.display.GUIDisplay Maven / Gradle / Ivy
/*
* ===========================================
* Java Pdf Extraction Decoding Access Library
* ===========================================
*
* Project Info: http://www.idrsolutions.com
* Help section for developers at http://www.idrsolutions.com/support/
*
* (C) Copyright 1997-2016 IDRsolutions and Contributors.
*
* This file is part of JPedal/JPDF2HTML5
*
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ---------------
* GUIDisplay.java
* ---------------
*/
package org.jpedal.display;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import org.jpedal.exception.PdfException;
import org.jpedal.external.Options;
import org.jpedal.external.RenderChangeListener;
import org.jpedal.objects.PdfPageData;
import org.jpedal.objects.acroforms.AcroRenderer;
import org.jpedal.parser.DecoderOptions;
import org.jpedal.render.DynamicVectorRenderer;
import org.jpedal.text.TextLines;
import org.jpedal.utils.ScalingFactory;
/**
* hold code generic to Swing or FX
*/
public class GUIDisplay implements Display{
protected int lastFormPage=-1,lastStart=-1,lastEnd=-1;
protected int pageUsedForTransform;
/**tracks indent so changing to continuous does not disturb display*/
protected int lastIndent=-1;
protected double indent;
/**Normally null - user object to listen to paint events*/
public RenderChangeListener customRenderChangeListener;
//rectangle onscreen
public int rx,ry,rw,rh;
protected DisplayOffsets displayOffsets;
public DecoderOptions options;
/**
* Flag if we should allow cursor to change
*/
public static boolean allowChangeCursor = true;
public final MultiDisplayOptions multiDisplayOptions=new MultiDisplayOptions();
//Animation enabled (currently just turnover in facing)
public static boolean default_turnoverOn = true;//can be altered by user
//Display the first page separately in Facing mode
public static boolean default_separateCover = true;//can be altered by user
public DynamicVectorRenderer currentDisplay;
public boolean isInitialised;
/**flag to switch back to unaccelerate screen if no enough memory for scaling*/
public boolean overRideAcceleration;
/**render screen using hardware acceleration*/
public boolean useAcceleration=true;
public boolean ignoreScalingForAcceleration;
public boolean accelerationAlwaysRedraw;
public PageOffsets currentOffset;
/** Holds the x,y,w,h of the current highlighted image, null if none */
private int[] highlightedImage;
protected GUIThumbnailPanel thumbnails;
/** Keep a record of cumulative offsets for SINGLE_PAGE mode*/
public int[] pageOffsetH, pageOffsetW;
public boolean[] isRotated;
public int topW,topH;
public double cropX,cropY,cropW,cropH;
/**used to draw demo cross*/
public int crx,cry,crw,crh;
/**local copies*/
public int displayRotation,displayView=SINGLE_PAGE;
public int lastDisplayRotation;
public int insetW,insetH;
public float scaling;
public float lastScaling;
public int pageNumber;
/**any scaling factor being used to convert co-ords into correct values
* and to alter image size
*/
public float oldScaling=-1,oldRotation=-1;
public PdfPageData pageData;
@Deprecated
/*
* Please use PdfDecoder.setBorderPresent(boolean) instead
* True : Show border around page.
* Flase : Remove border around page.
*/
public static int CURRENT_BORDER_STYLE = 1;
// Affine transformation as a double array
protected double[] displayScalingDbl;
// public static void setBorderStyle(int style){
// CURRENT_BORDER_STYLE = style;
// }
//
// public static int getBorderStyle(){
// return CURRENT_BORDER_STYLE;
// }
/**
* used internally by multiple pages
* scaling -1 to ignore, -2 to force reset
*/
@Override
public int getYCordForPage(final int page, final float scaling) {
if (scaling == -2 || (scaling != -1f && scaling != oldScaling)) {
oldScaling = scaling;
setPageOffsets(page);
}
return getYCordForPage(page);
}
@Override
public boolean getBoolean(final BoolValue option) {
switch (option) {
case SEPARATE_COVER:
return multiDisplayOptions.isSeparateCover();
case TURNOVER_ON:
return multiDisplayOptions.isTurnoverOn();
default:
throw new RuntimeException("GetBoolean called with unknown value "+option);
}
}
@Override
public void setBoolean(final BoolValue option, final boolean value) {
switch (option) {
case SEPARATE_COVER:
multiDisplayOptions.setSeparateCover(value);
return;
case TURNOVER_ON:
multiDisplayOptions.setTurnoverOn(value);
return;
default:
throw new RuntimeException("setBoolean called with unkown value "+value);
}
}
/**
* general method to pass in Objects - only takes RenderChangeListener at present
* @param type
* @param newHandler
*/
@Override
public void setObjectValue(final int type, final Object newHandler) {
//set value
switch(type){
case Options.RenderChangeListener:
customRenderChangeListener = (RenderChangeListener) newHandler;
break;
default:
throw new RuntimeException("setObjectValue does not take value "+type);
}
}
@Override
public void setCursorBoxOnScreen(final Rectangle cursorBoxOnScreen, final boolean isSamePage) {
}
/**
*
* @param displayView is of type int
* @return returns an int[] with 2 values ([0]width and [1]height)
* which we then use to create a Dimension object in current Swing code
*/
@Override
public int[] getPageSize(final int displayView) {
final int[] pageSize = new int[2]; //element 0 = width, element 1 = height
//height for facing pages
int biggestFacingHeight=0;
int facingWidth=0;
if((displayView==FACING)&&(multiDisplayOptions.getPageW()!=null)){
//get 2 facing page numbers
int p1;
final int p2;
if (multiDisplayOptions.isSeparateCover()) {
p1=pageNumber;
if((p1 & 1)==1) {
p1--;
}
p2=p1+1;
} else {
p1=pageNumber;
if((p1 & 1)==0) {
p1--;
}
p2=p1+1;
}
if (p1 == 0) {
biggestFacingHeight = multiDisplayOptions.getPageH(p2);
facingWidth = multiDisplayOptions.getPageW(p2)*2;
} else {
biggestFacingHeight=multiDisplayOptions.getPageH(p1);
if(p2=360) {
displayRotation -= 360;
}
//swap if this page rotated and flag
if((displayRotation==90|| displayRotation==270)){
final int tmp=pageW[i];
pageW[i]=pageH[i];
pageH[i]=tmp;
isRotated[i]=true; //flag page as rotated
}
if((i&1)==1){
if(pageW[i]>RmaxWidth) {
RmaxWidth = pageW[i];
}
if(pageH[i]>RmaxHeight) {
RmaxHeight = pageH[i];
}
}else{
if(multiDisplayOptions.getPageW(i)>LmaxWidth) {
LmaxWidth = multiDisplayOptions.getPageW(i);
}
if(pageH[i]>LmaxHeight) {
LmaxHeight = pageH[i];
}
}
}
int[] xReached=multiDisplayOptions.getxReached();
int[] yReached=multiDisplayOptions.getyReached();
//loop through all pages and work out positions
for(int i=1;i=2 &&
(((pageData.getRotation(i) == 270 || pageData.getRotation(i) == 90) &&
(pageData.getRotation(i-1) != 270 || pageData.getRotation(i-1) != 90))
|| ((pageData.getRotation(i-1) == 270 || pageData.getRotation(i-1) == 90) &&
(pageData.getRotation(i) != 270 || pageData.getRotation(i) != 90))))) {
pageOffsetW[i] = (pageW[i] - pageW[i-1]) + pageOffsetW[i-1];
pageOffsetH[i] = (pageH[i] - pageH[i-1]) + pageOffsetH[i-1];
}
//Left Pages
if((i & 1)==0){
//Last Page rotated so correct height
if(i3){
final int temp = (pageH[i-2]-pageH[i-1])/2;
if(temp>0) {
heightCorrection += temp;
}
}
yReached[i] = (yReached[i-1]+pageH[i-1] +gap)+heightCorrection;
}else{ //Right Pages
//Last Page rotated so correct height
heightCorrection = (pageH[i-1]-pageH[i])/2;
yReached[i] = (yReached[i-1])+heightCorrection;
}
if((i & 1)==0){//Indent Left pages by diff between maxWidth and pageW (will only indent unrotated)
xReached[i] += (LmaxWidth-pageW[i]);
}else{//Place Right Pages with a gap (This keeps pages centered)
xReached[i] = xReached[i-1]+pageW[i-1] +gap;
}
}else if(displayView==CONTINUOUS){
//Place page below last with gap
yReached[i] = (yReached[i-1]+pageH[i-1]+gap);
if(!(i>=2 &&
(((pageData.getRotation(i) == 270 || pageData.getRotation(i) == 90) &&
(pageData.getRotation(i-1) != 270 || pageData.getRotation(i-1) != 90))
|| ((pageData.getRotation(i-1) == 270 || pageData.getRotation(i-1) == 90) &&
(pageData.getRotation(i) != 270 || pageData.getRotation(i) != 90))))) {
pageOffsetW[i] = (pageW[i] - pageW[i-1]) + pageOffsetW[i-1];
pageOffsetH[i] = (pageH[i] - pageH[i-1]) + pageOffsetH[i-1];
}
}else if((displayView==FACING)){
if((i&1)==1){ //If right page, place on right with gap
xReached[i] = (xReached[i-1]+pageW[i-1]+gap);
if(pageH[i] < pageH[i-1])//Drop page down to keep pages centred
{
yReached[i] += (((pageH[i - 1] - pageH[i]) / 2));
}
}else{ //If left page, indent by diff of max and current page
xReached[i] = 0;
if(i
*/
@Override
public void setPageRotation(int newRotation) {
//assume unrotated for multiple views and rotate on a page basis
if(displayView!=Display.SINGLE_PAGE) {
newRotation = 0;
}
pageUsedForTransform= pageNumber;
if(displayView!=Display.SINGLE_PAGE && displayView!=Display.FACING){
displayScalingDbl = ScalingFactory.getScalingForImage(1, 0, scaling,pageData);//(int)(pageData.getCropBoxWidth(pageNumber)*scaling),(int)(pageData.getCropBoxHeight(pageNumber)*scaling),
}else{
displayScalingDbl = ScalingFactory.getScalingForImage(pageNumber,newRotation, scaling, pageData);//(int)(pageData.getCropBoxWidth(pageNumber)*scaling),(int)(pageData.getCropBoxHeight(pageNumber)*scaling),
}
final int insetW=options.getInsetW();
final int insetH=options.getInsetH();
// Affine transformations
switch (newRotation) {
case 90:
displayScalingDbl[4] += ((insetW/scaling) * displayScalingDbl[1] );
displayScalingDbl[5] += ((insetH/scaling) * displayScalingDbl[2] );
break;
case 270:
displayScalingDbl[4] += ((-insetW/scaling) * displayScalingDbl[1] );
displayScalingDbl[5] += ((-insetH/scaling) * displayScalingDbl[2] );
break;
case 180:
displayScalingDbl[4] += ((-insetW/scaling) * displayScalingDbl[0] );
displayScalingDbl[5] += ((insetH/scaling) * displayScalingDbl[3] );
break;
default:
displayScalingDbl[4] += ((insetW/scaling) * displayScalingDbl[0] );
displayScalingDbl[5] += ((-insetH/scaling) * displayScalingDbl[3] );
break;
}
//force redraw if screen being cached
refreshDisplay();
}
@Override
public void resetViewableArea() {
throw new UnsupportedOperationException("resetViewableArea Not supported yet.");
}
@Override
public void paintPage(final Graphics2D g2, final AcroRenderer formRenderer, final TextLines textLines) {
throw new UnsupportedOperationException("paintPage not supported yet.");
}
/**
* Deprecated on 04/07/2014, please use
* updateCursorBoxOnScreen(int[] newOutlineRectangle, int outlineColor, int pageNumber,int x_size,int y_size) instead.
* @deprecated
*/
@Deprecated
@Override
public void updateCursorBoxOnScreen(final Rectangle newOutlineRectangle, final Color outlineColor, final int pageNumber, final int x_size, final int y_size) {
throw new UnsupportedOperationException("please use updateCursorBoxOnScreen(int[] newOutlineRectangle, int outlineColor, int pageNumber,int x_size,int y_size) instead");
}
@Override
public void updateCursorBoxOnScreen(final int[] newOutlineRectangle, final int outlineColor, final int pageNumber, final int x_size, final int y_size){
throw new UnsupportedOperationException("updateCursorBoxOnScreen Not supported yet.");
}
@Override
public void drawCursor(final Graphics g, final float scaling) {
throw new UnsupportedOperationException("drawCursor Not supported yet.");
}
/**
* Deprecated on 07/07/2014
* Please use setViewableArea(int[] viewport) instead.
* @deprecated
*/
@Deprecated
@Override
public AffineTransform setViewableArea(final Rectangle viewport) throws PdfException {
throw new UnsupportedOperationException("setViewableArea Not supported yet.");
}
/**
* NOT PART OF API
*
* allows the user to create a viewport within the displayed page, the
* aspect ratio is keep for the PDF page
*
* Passing in a null value is the same as calling resetViewableArea()
*
*
* The viewport works from the bottom left of the PDF page
* The general formula is
* (leftMargin,
* bottomMargin,
* pdfWidth-leftMargin-rightMargin,
* pdfHeight-bottomMargin-topMargin)
*
* The viewport will not be incorporated in printing
*
* Throws PdfException if the viewport is not totally enclosed within the
* 100% cropped pdf
*/
@Override
public AffineTransform setViewableArea(final int[] viewport) throws PdfException{
throw new UnsupportedOperationException("setViewableArea Not supported yet.");
}
@Override
public void drawFacing(final Rectangle visibleRect) {
throw new UnsupportedOperationException("drawFacing Not supported yet.");
}
@Override
public void paintPage(final Object box, final AcroRenderer formRenderer, final TextLines textLines) {
throw new UnsupportedOperationException("paintPage Not supported yet.");
}
public void setCurrentDisplay(final DynamicVectorRenderer pageView) {
this.currentDisplay=pageView;
}
public int getDisplayRotation() {
return displayRotation;
}
public int getRx() {
return rx;
}
public int getRy() {
return ry;
}
public int getRw() {
return rw;
}
public int getRh() {
return rh;
}
public int getInsetW() {
return insetW;
}
public int getInsetH() {
return insetH;
}
@Override
public Rectangle getDisplayedRectangle() {
throw new UnsupportedOperationException("getDisplayedRectangle Not supported yet.");
}
public Rectangle getDisplayedRectangle(final boolean isShowing,final Rectangle userAnnot) {
//get raw rectangle
rx =userAnnot.x;
ry =userAnnot.y;
rw =userAnnot.width;
rh =userAnnot.height;
//Best way I found to catch if pdf decoder is being used but never displayed
if(!isShowing && (rw==0 || rh==0)){
rx = 0;
ry = 0;
rw = pageData.getScaledCropBoxWidth(pageNumber);
rh = pageData.getScaledCropBoxHeight(pageNumber);
if(pageData.getRotation(pageNumber)%180!=0){
rh = pageData.getScaledCropBoxWidth(pageNumber);
rw = pageData.getScaledCropBoxHeight(pageNumber);
}
}
return userAnnot;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy