00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "PDFCore.h"
00020 #include "PDFViewerLog.h"
00021 #include "controller.h"
00022 #include <math.h>
00023
00024 CPDFCore::CPDFCore(SplashColorMode colorModeA, int bitmapRowPadA,
00025 GBool reverseVideoA, SplashColorPtr paperColorA)
00026 {
00027 outputDev = NULL;
00028 textOut = NULL;
00029 pdfdoc = NULL;
00030 ctrl = NULL;
00031 }
00032
00033 CPDFCore::~CPDFCore(void)
00034 {
00035 if (outputDev) { delete outputDev; outputDev = NULL; }
00036 if (pdfdoc) { delete pdfdoc; pdfdoc = NULL; }
00037 ctrl = NULL;
00038 }
00039
00040
00041 int CPDFCore::open(GooString *fileNameA, GooString *ownerPassword,
00042 GooString *userPassword , void *guiDataA )
00043 {
00044 int ret = errNone;
00045
00046 if (pdfdoc)
00047 {
00048 PV_LOGPRINTF("Delete old doc %p\n", pdfdoc);
00049 delete pdfdoc;
00050 }
00051
00052
00053 pdfdoc = new PDFDoc(fileNameA, ownerPassword, userPassword, guiDataA);
00054
00055
00056 if (!pdfdoc->isOk())
00057 {
00058 ret = pdfdoc->getErrorCode();
00059 delete pdfdoc;
00060 PV_ERRORPRINTF("Open PDF document %s failed with error code %d",
00061 fileNameA->getCString(), ret);
00062 return errOpenFile;
00063 }
00064
00065
00066 if (NULL == outputDev)
00067 {
00068 SplashColor white;
00069 white[0] = 255;
00070 white[1] = 255;
00071 white[2] = 255;
00072 outputDev = new SplashOutputDev(splashModeMono8, 4, gFalse, white);
00073 }
00074 outputDev->startDoc(pdfdoc->getXRef());
00075 return ret;
00076 }
00077
00078 int CPDFCore::open(BaseStream *stream, GooString *ownerPassword ,
00079 GooString *userPassword , void *guiDataA)
00080 {
00081 return errNone;
00082 }
00083
00084
00085 void CPDFCore::close()
00086 {
00087 if (outputDev) { delete outputDev; outputDev = NULL; }
00088 if (pdfdoc) { delete pdfdoc; pdfdoc = NULL; }
00089 }
00090
00091 void CPDFCore::getPageBasicInfo(CPageInfo & info)
00092 {
00093 info.pageDx = pdfdoc->getPageCropWidth(info.pageNumber);
00094 info.pageDy = pdfdoc->getPageCropHeight(info.pageNumber);
00095 info.pageRotate = pdfdoc->getPageRotate(info.pageNumber);
00096 }
00097
00098 double CPDFCore::getPageWidth(const int pageNumber)
00099 {
00100 return pdfdoc->getPageCropWidth(pageNumber);
00101 }
00102
00103 double CPDFCore::getPageHeight(const int pageNumber)
00104 {
00105 return pdfdoc->getPageCropHeight(pageNumber);
00106 }
00107
00108 int CPDFCore::getPageRotate(const int pageNumber)
00109 {
00110 return pdfdoc->getPageRotate(pageNumber);
00111 }
00112
00113 int CPDFCore::getNumPages()
00114 {
00115 if (NULL == pdfdoc) return -1;
00116 return pdfdoc->getNumPages();
00117 }
00118
00119 RenderRet CPDFCore::renderPage(CPageInfo & info, GBool useMediaBox,
00120 GBool crop, GBool doLinks, GBool (*abortCheckCbk)(void *data) ,
00121 void *abortCheckCbkData )
00122 {
00123 if (NULL == pdfdoc)
00124 {
00125 PV_ERRORPRINTF("PDF document has not been opened!");
00126 return Render_Error;
00127 }
00128
00129 if (0 >= info.pageNumber || info.pageNumber > pdfdoc->getNumPages())
00130 {
00131 PV_ERRORPRINTF("PageNumber %d is invalid![1, %d]",
00132 info.pageNumber, pdfdoc->getNumPages());
00133 return Render_Error;
00134 }
00135
00136
00137 getPageBasicInfo(info);
00138
00139
00140 calculateLayout(info);
00141
00142
00143 #if (PV_PROFILE_ON)
00144 int t1 = ctrl->getHighTimeStamp();
00145 #endif
00146
00147 RenderRet ret = Render_Error;
00148
00149 ret = pdfdoc->displayPage(outputDev, info.pageNumber,
00150 info.hDPI, info.vDPI, info.rotate, useMediaBox, crop, doLinks,
00151 abortCheckCbk, abortCheckCbkData);
00152
00153
00154 if (ret == Render_Error || ret == Render_Invalid)
00155 {
00156 PV_ERRORPRINTF("Render page error!");
00157 return ret;
00158 }
00159
00160
00161 info.bitmap = outputDev->takeBitmap();
00162 if (ret == Render_Done)
00163 {
00164 #if (PV_PROFILE_ON)
00165 int t2 = ctrl->getHighTimeStamp();
00166 PV_DUMP("PDFDoc::displayPage %d uses %d\n", info.pageNumber, t2 - t1);
00167 #endif
00168
00169
00170 memcpy(info.ctm, outputDev->getDefCTM(), 6 * sizeof(double));
00171 memcpy(info.ictm, outputDev->getDefICTM(), 6 * sizeof(double));
00172
00173
00174 info.links = pdfdoc->takeLinks();
00175
00176
00177 if (textOut)
00178 {
00179 pdfdoc->displayPage(textOut, info.pageNumber, info.hDPI, info.vDPI, info.rotate,
00180 gFalse, gTrue, gFalse);
00181 info.text = textOut->takeText();
00182 }
00183 return Render_Done;
00184 }
00185 else if (ret == Render_Abort)
00186 {
00187 delete info.bitmap;
00188 info.bitmap = NULL;
00189 info.links = NULL;
00190 }
00191 return Render_Abort;
00192 }
00193
00194
00195 void CPDFCore::calculateLayout(CPageInfo & info)
00196 {
00197 PV_LOGPRINTF("info.pageZoom %lg\n", info.pageZoom);
00198 info.hDPI = info.pageZoom * 0.01 * DefDPI;
00199 info.vDPI = info.pageZoom * 0.01 * DefDPI;
00200 }
00201
00202
00203
00204 struct PageSpec
00205 {
00206 int hISO;
00207 int wISO;
00208 double zoomMax;
00209 };
00210
00211 static const PageSpec PageSpecTable [] =
00212 {
00213 {3371, 2384, A0ZoomMax},
00214 {2384, 1686, A1ZoomMax},
00215 {1686, 1192, A2ZoomMax},
00216 {1192, 843, A3ZoomMax},
00217 {843, 596, A4ZoomMax},
00218 {612, 792, A4ZoomMax},
00219 {596, 422, A5ZoomMax},
00220 {422, 298, A6ZoomMax},
00221 {298, 211, A7ZoomMax},
00222 {211, 149, A8ZoomMax},
00223 {149, 106, A9ZoomMax},
00224 };
00225 static const int PageSpecSize = sizeof(PageSpecTable)/ sizeof(PageSpecTable[0]);
00226
00227 int CPDFCore::getPageType(const int pageNumber)
00228 {
00229 if (NULL == pdfdoc)
00230 {
00231 PV_ERRORPRINTF("Try to access NULL pdfdoc pointer!");
00232 return -1;
00233 }
00234 if (pageNumber < 1 || pageNumber > pdfdoc->getNumPages())
00235 {
00236 PV_ERRORPRINTF("Invalid page number %d!", pageNumber);
00237 return -1;
00238 }
00239 int pageMx = (int)pdfdoc->getPageMediaWidth(pageNumber);
00240 int pageMy = (int)pdfdoc->getPageMediaHeight(pageNumber);
00241 for(int i = 0 ; i < PageSpecSize; ++i)
00242 {
00243 if ((pageMx >= PageSpecTable[i].hISO &&
00244 pageMy >= PageSpecTable[i].wISO) ||
00245 (pageMy >= PageSpecTable[i].hISO &&
00246 pageMx >= PageSpecTable[i].wISO))
00247 {
00248 return i;
00249 }
00250 }
00251 return -1;
00252 }
00253
00254 double CPDFCore::getZoomMax(const int pageNumber)
00255 {
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 int pageMx = (int)pdfdoc->getPageMediaWidth(pageNumber);
00269 int pageMy = (int)pdfdoc->getPageMediaHeight(pageNumber);
00270 for(int i = 0 ; i < PageSpecSize; ++i)
00271 {
00272 if ((pageMx >= PageSpecTable[i].hISO &&
00273 pageMy >= PageSpecTable[i].wISO) ||
00274 (pageMy >= PageSpecTable[i].hISO &&
00275 pageMx >= PageSpecTable[i].wISO))
00276 {
00277
00278 return PageSpecTable[i].zoomMax;
00279 }
00280 }
00281 return ZoomMax;
00282 }
00283
00285
00287 double CPDFCore::verifyZoomMax(double zoom,const int pageNumber)
00288 {
00289 double tmp = getZoomMax(pageNumber);
00290 if (zoom > tmp)
00291 {
00292 return tmp;
00293 }
00294 return zoom;
00295 }