static void update_toc(GooList* items, int level) { unsigned short ucs[256]; char label[256]; int i, j; if (! items) return; if (items->getLength() < 1) return; for (i = 0; i < items->getLength(); i++) { OutlineItem* outlineItem = (OutlineItem*)items->get(i); Unicode* title = outlineItem->getTitle(); int tlen = outlineItem->getTitleLength(); if (tlen > sizeof(ucs) - 1) tlen = sizeof(ucs) - 1; for (j = 0; j < tlen; j++) ucs[j] = (unsigned short)title[j]; ucs[j] = 0; ucs2utf(ucs, label, sizeof(label)); LinkAction* a = outlineItem->getAction(); if (a && (a->getKind() == actionGoTo)) { // page number is contained/referenced in a LinkGoTo LinkGoTo* g = static_cast< LinkGoTo* >(a); LinkDest* destination = g->getDest(); if (!destination && g->getNamedDest()) { GooString* s = g->getNamedDest(); if (named_size <= named_count + 1) { named_size += 64; named_dest = (char**) realloc(named_dest, named_size * sizeof(char*)); } named_dest[named_count] = strdup(s->getCString()); add_toc_item(level, label, -1, 100000 + named_count); named_count++; } else if (destination && destination->isOk() && destination->isPageRef()) { Ref page_ref = destination->getPageRef(); int num = doc->findPage(page_ref.num, page_ref.gen); add_toc_item(level, label, num, num); } else { add_toc_item(level, label, -1, -1); } } else { add_toc_item(level, label, -1, -1); } outlineItem->open(); GooList* children = outlineItem->getKids(); if (children) update_toc(children, level + 1); outlineItem->close(); } }
void NSRPopplerDocument::renderPage(int page) { double dpix, dpiy; if (_doc == NULL || page > getNumberOfPages() || page < 1) return; _page = _catalog->getPage(page); if (isTextOnly()) { PDFRectangle *rect; GooString *text; TextOutputDev *dev; dev = new TextOutputDev (0, gFalse, gFalse, gFalse); _doc->displayPageSlice(dev, _page->getNum(), 72, 72, 0, gFalse, gTrue, gFalse, -1, -1, -1, -1); rect = _page->getCropBox(); text = dev->getText(rect->x1, rect->y1, rect->x2, rect->y2); _text = processText(QString::fromUtf8(text->getCString())); delete text; delete dev; _readyForLoad = true; return; } if (isZoomToWidth()) { double wZoom = ((double) getScreenWidth() / (double) _page->getCropWidth() * 100.0); setZoomSilent((int) wZoom); } if (getZoom() > getMaxZoom()) setZoomSilent (getMaxZoom()); else if (getZoom() < getMinZoom()) setZoomSilent (getMinZoom()); if (_readyForLoad) _dev->startPage(0, NULL); dpix = _dpix * getZoom() / 100.0; dpiy = _dpiy * getZoom() / 100.0; _page->display(_dev, dpix, dpiy, getRotation(), gFalse, gFalse, gTrue, _catalog); _readyForLoad = true; }
OutlineItem::OutlineItem(Dict *dict, XRef *xrefA) { Object obj1; GooString *s; int i; xref = xrefA; title = NULL; action = NULL; kids = NULL; if (dict->lookup("Title", &obj1)->isString()) { s = obj1.getString(); if ((s->getChar(0) & 0xff) == 0xfe && (s->getChar(1) & 0xff) == 0xff) { titleLen = (s->getLength() - 2) / 2; title = (Unicode *)gmallocn(titleLen, sizeof(Unicode)); for (i = 0; i < titleLen; ++i) { title[i] = ((s->getChar(2 + 2*i) & 0xff) << 8) | (s->getChar(3 + 2*i) & 0xff); } } else { titleLen = s->getLength(); title = (Unicode *)gmallocn(titleLen, sizeof(Unicode)); for (i = 0; i < titleLen; ++i) { title[i] = pdfDocEncoding[s->getChar(i) & 0xff]; } } } else { titleLen = 0; } obj1.free(); if (!dict->lookup("Dest", &obj1)->isNull()) { action = LinkAction::parseDest(&obj1); } else { obj1.free(); if (!dict->lookup("A", &obj1)->isNull()) { action = LinkAction::parseAction(&obj1); } } obj1.free(); dict->lookupNF("First", &firstRef); dict->lookupNF("Last", &lastRef); dict->lookupNF("Next", &nextRef); startsOpen = gFalse; if (dict->lookup("Count", &obj1)->isInt()) { if (obj1.getInt() > 0) { startsOpen = gTrue; } } obj1.free(); }
GDir::GDir(char *name, GBool doStatA) { path = new GooString(name); doStat = doStatA; #if defined(WIN32) GooString *tmp; tmp = path->copy(); tmp->append("/*.*"); hnd = FindFirstFile(tmp->getCString(), &ffd); delete tmp; #elif defined(ACORN) #elif defined(MACOS) #else dir = opendir(name); #ifdef VMS needParent = strchr(name, '[') != NULL; #endif #endif }
void GDir::rewind() { #ifdef WIN32 GooString *tmp; if (hnd != INVALID_HANDLE_VALUE) FindClose(hnd); tmp = path->copy(); tmp->append("/*.*"); hnd = FindFirstFile(tmp->getCString(), &ffd); delete tmp; #elif defined(ACORN) #elif defined(MACOS) #else if (dir) rewinddir(dir); #ifdef VMS needParent = strchr(path->getCString(), '[') != NULL; #endif #endif }
void TestGooString::testInsert() { { GooString goo; goo.insert(0, "."); goo.insert(0, "This is a very long long test string"); QCOMPARE(goo.getCString(), "This is a very long long test string."); } { GooString goo; goo.insert(0, "second-part-third-part"); goo.insert(0, "first-part-"); QCOMPARE(goo.getCString(), "first-part-second-part-third-part"); } }
void *StandardSecurityHandler::getAuthData() { #if HAVE_XPDFCORE XPDFCore *core; GooString *password; if (!(core = (XPDFCore *)doc->getGUIData()) || !(password = core->getPassword())) { return NULL; } return new StandardAuthData(password, password->copy()); #elif HAVE_WINPDFCORE WinPDFCore *core; GooString *password; if (!(core = (WinPDFCore *)doc->getGUIData()) || !(password = core->getPassword())) { return NULL; } return new StandardAuthData(password, password->copy()); #else return NULL; #endif }
static char * unicode_to_char (Unicode *unicode, int len) { static UnicodeMap *uMap = NULL; if (uMap == NULL) { GooString *enc = new GooString ("UTF-8"); uMap = globalParams->getUnicodeMap (enc); uMap->incRefCnt (); delete enc; } GooString gstr; char buf[8]; /* 8 is enough for mapping an unicode char to a string */ int i, n; for (i = 0; i < len; ++i) { n = uMap->mapUnicode (unicode[i], buf, sizeof (buf)); gstr.append (buf, n); } return strdup (gstr.getCString ()); }
int main(int argc, char *argv[]) { // parse args bool ok = parseArgs(argDesc, &argc, argv); if (!ok || argc < 2 || argc > 3 || printHelp) { fprintf(stderr, "pdftoipe version %s\n", PDFTOIPE_VERSION); printUsage("pdftoipe", "<PDF-file> [<XML-file>]", argDesc); return 1; } GooString *fileName = new GooString(argv[1]); globalParams = new GlobalParams(); if (quiet) globalParams->setErrQuiet(quiet); GooString *ownerPW, *userPW; if (ownerPassword[0]) { ownerPW = new GooString(ownerPassword); } else { ownerPW = 0; } if (userPassword[0]) { userPW = new GooString(userPassword); } else { userPW = 0; } // open PDF file PDFDoc *doc = new PDFDoc(fileName, ownerPW, userPW); delete userPW; delete ownerPW; if (!doc->isOk()) return 1; // construct XML file name std::string xmlFileName; if (argc == 3) { xmlFileName = argv[2]; } else { const char *p = fileName->c_str() + fileName->getLength() - 4; if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) { xmlFileName = std::string(fileName->c_str(), fileName->getLength() - 4); } else { xmlFileName = fileName->c_str(); } xmlFileName += ".ipe"; } // get page range if (firstPage < 1) firstPage = 1; if (lastPage < 1 || lastPage > doc->getNumPages()) lastPage = doc->getNumPages(); // write XML file XmlOutputDev *xmlOut = new XmlOutputDev(xmlFileName, doc->getXRef(), doc->getCatalog(), firstPage, lastPage); // tell output device about text handling xmlOut->setTextHandling(math, notext, literal, mergeLevel, unicodeLevel); int exitCode = 2; if (xmlOut->isOk()) { doc->displayPages(xmlOut, firstPage, lastPage, // double hDPI, double vDPI, int rotate, // bool useMediaBox, bool crop, bool printing, 72.0, 72.0, 0, false, false, false); exitCode = 0; } if (xmlOut->hasUnicode()) { fprintf(stderr, "The document contains Unicode (non-ASCII) text.\n"); if (unicodeLevel <= 1) fprintf(stderr, "Unknown Unicode characters were replaced by [U+XXX].\n"); else fprintf(stderr, "UTF-8 was set as document encoding in the preamble.\n"); } // clean up delete xmlOut; delete doc; delete globalParams; return exitCode; }
GooString *appendToPath(GooString *path, char *fileName) { #if defined(VMS) //---------- VMS ---------- //~ this should handle everything necessary for file //~ requesters, but it's certainly not complete char *p0, *p1, *p2; char *q1; p0 = path->getCString(); p1 = p0 + path->getLength() - 1; if (!strcmp(fileName, "-")) { if (*p1 == ']') { for (p2 = p1; p2 > p0 && *p2 != '.' && *p2 != '['; --p2) ; if (*p2 == '[') ++p2; path->del(p2 - p0, p1 - p2); } else if (*p1 == ':') { path->append("[-]"); } else { path->clear(); path->append("[-]"); } } else if ((q1 = strrchr(fileName, '.')) && !strncmp(q1, ".DIR;", 5)) { if (*p1 == ']') { path->insert(p1 - p0, '.'); path->insert(p1 - p0 + 1, fileName, q1 - fileName); } else if (*p1 == ':') { path->append('['); path->append(']'); path->append(fileName, q1 - fileName); } else { path->clear(); path->append(fileName, q1 - fileName); } } else { if (*p1 != ']' && *p1 != ':') path->clear(); path->append(fileName); } return path; #elif defined(WIN32) //---------- Win32 ---------- GooString *tmp; char buf[256]; char *fp; tmp = new GooString(path); tmp->append('/'); tmp->append(fileName); GetFullPathName(tmp->getCString(), sizeof(buf), buf, &fp); delete tmp; path->clear(); path->append(buf); return path; #elif defined(ACORN) //---------- RISCOS ---------- char *p; int i; path->append("."); i = path->getLength(); path->append(fileName); for (p = path->getCString() + i; *p; ++p) { if (*p == '/') { *p = '.'; } else if (*p == '.') { *p = '/'; } } return path; #elif defined(MACOS) //---------- MacOS ---------- char *p; int i; path->append(":"); i = path->getLength(); path->append(fileName); for (p = path->getCString() + i; *p; ++p) { if (*p == '/') { *p = ':'; } else if (*p == '.') { *p = ':'; } } return path; #elif defined(__EMX__) //---------- OS/2+EMX ---------- int i; // appending "." does nothing if (!strcmp(fileName, ".")) return path; // appending ".." goes up one directory if (!strcmp(fileName, "..")) { for (i = path->getLength() - 2; i >= 0; --i) { if (path->getChar(i) == '/' || path->getChar(i) == '\\' || path->getChar(i) == ':') break; } if (i <= 0) { if (path->getChar(0) == '/' || path->getChar(0) == '\\') { path->del(1, path->getLength() - 1); } else if (path->getLength() >= 2 && path->getChar(1) == ':') { path->del(2, path->getLength() - 2); } else { path->clear(); path->append(".."); } } else { if (path->getChar(i-1) == ':') ++i; path->del(i, path->getLength() - i); } return path; } // otherwise, append "/" and new path component if (path->getLength() > 0 && path->getChar(path->getLength() - 1) != '/' && path->getChar(path->getLength() - 1) != '\\') path->append('/'); path->append(fileName); return path; #else //---------- Unix ---------- int i; // appending "." does nothing if (!strcmp(fileName, ".")) return path; // appending ".." goes up one directory if (!strcmp(fileName, "..")) { for (i = path->getLength() - 2; i >= 0; --i) { if (path->getChar(i) == '/') break; } if (i <= 0) { if (path->getChar(0) == '/') { path->del(1, path->getLength() - 1); } else { path->clear(); path->append(".."); } } else { path->del(i, path->getLength() - i); } return path; } // otherwise, append "/" and new path component if (path->getLength() > 0 && path->getChar(path->getLength() - 1) != '/') path->append('/'); path->append(fileName); return path; #endif }
int main(int argc,char **argv) { unsigned int window_width=-1, window_height=-1; // sage window size sage::initUtil(); // parse command line arguments if (argc < 2){ sage::printLog("PDF> pdfviewer filename [width] [height] [-show_original] [-page num]"); return 0; } for (int argNum=2; argNum<argc; argNum++) { if (strcmp(argv[argNum], "-show_original") == 0) { useDXT = false; } else if(strcmp(argv[argNum], "-page") == 0) { int p = atoi(argv[argNum+1]); if (p != 0) firstPage = p-1; argNum++; } else if(atoi(argv[argNum]) != 0 && atoi(argv[argNum+1]) != 0) { window_width = atoi( argv[argNum] ); window_height = atoi( argv[argNum+1] ); argNum++; // increment because we read two args here } } fileName = string(argv[1]); #if defined(USE_POPPLER) #if SAGE_POPPLER_VERSION == 5 g_type_init(); sage::printLog("PDF> Poppler version %s", poppler_get_version()); backend = poppler_get_backend (); enum_value = g_enum_get_value ((GEnumClass *) g_type_class_ref (POPPLER_TYPE_BACKEND), backend); sage::printLog ("PDF> Backend is %s", enum_value->value_name); error = NULL; const string filename = string((const char*)"file://") + string(argv[1]); document = poppler_document_new_from_file (filename.c_str(), NULL, &error); if (document == NULL) { sage::printLog("PDF> error for [%s]: %s", filename.c_str(), error->message); exit(0); } // get the number of pages numImages = poppler_document_get_n_pages(document); pg_index = 0; // index starts at 0 page = poppler_document_get_page(document, pg_index); if (page == NULL) { sage::printLog("PDF> error for [%s]: %s", filename.c_str()); exit(0); } // page size double mwidth, mheight; poppler_page_get_size (page, &mwidth, &mheight); sage::printLog ("PDF> page size: %g by %g ", mwidth, mheight); x_resolution = 200.0; pg_w = mwidth * (x_resolution / 72.0); pg_h = mheight * (x_resolution / 72.0); if (pg_w > 4096) { pg_w = 4096.0; pg_h = 4096.0 / (mwidth/mheight); x_resolution = pg_w * 72.0 / mwidth; } if (pg_h > 4096) { pg_w = 4096.0 / (mheight/mwidth); pg_h = 4096.0; x_resolution = pg_h * 72.0 / mheight; } width = (unsigned int)pg_w; height = (unsigned int)pg_h; sage::printLog("PDF> Crop @ %d DPI: width %d height %d", int(x_resolution), int(pg_w), int(pg_h)); pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); gdk_pixbuf_fill (pixbuf, 0xffffffff); // print some information print_document_info (document); #endif #if SAGE_POPPLER_VERSION == 12 GooString *fileName; GooString *ownerPW, *userPW; Object info; UnicodeMap *uMap; // read config file globalParams = new GlobalParams(); // get mapping to output encoding if (!(uMap = globalParams->getTextEncoding())) { sage::printLog("PDF> Couldn't get text encoding"); } fileName = new GooString(argv[1]); ownerPW = NULL; userPW = NULL; doc = new PDFDoc(fileName, ownerPW, userPW, NULL); sage::printLog("PDF> file [%s] is OK: %d", argv[1], doc->isOk() ); numImages = doc->getNumPages(); sage::printLog("PDF> num pages: %d", numImages ); SplashColor paperColor; paperColor[0] = 255; paperColor[1] = 255; paperColor[2] = 255; splashOut = new SplashOutputDev(splashModeRGB8, 3, gFalse, paperColor); splashOut->startDoc(doc->getXRef()); pg_index = firstPage+1; double mwidth = doc->getPageMediaWidth(pg_index); double mheight = doc->getPageMediaHeight(pg_index); sage::printLog("PDF> Media width %d height %d", int(mwidth), int(mheight)); x_resolution = 200.0; pg_w = mwidth * (x_resolution / 72.0); pg_h = mheight * (x_resolution / 72.0); if (pg_w > 4096) { pg_w = 4096.0; pg_h = 4096.0 / (mwidth/mheight); x_resolution = pg_w * 72.0 / mwidth; } if (pg_h > 4096) { pg_w = 4096.0 / (mheight/mwidth); pg_h = 4096.0; x_resolution = pg_h * 72.0 / mheight; } width = pg_w; height = pg_h; sage::printLog("PDF> Crop @ %d DPI: width %d height %d", int(x_resolution), int(pg_w), int(pg_h)); doc->displayPageSlice(splashOut, 1, x_resolution, x_resolution, 0, gTrue, gFalse, gFalse, 0, 0, pg_w, pg_h); // print doc info doc->getDocInfo(&info); if (info.isDict()) { printInfoString(info.getDict(), (char*)"Title", (char*)"Title: ", uMap); printInfoString(info.getDict(), (char*)"Subject", (char*)"Subject: ", uMap); printInfoString(info.getDict(), (char*)"Keywords", (char*)"Keywords: ", uMap); printInfoString(info.getDict(), (char*)"Author", (char*)"Author: ", uMap); printInfoString(info.getDict(), (char*)"Creator", (char*)"Creator: ", uMap); printInfoString(info.getDict(), (char*)"Producer", (char*)"Producer: ", uMap); printInfoDate(info.getDict(), (char*)"CreationDate", (char*)"CreationDate: "); printInfoDate(info.getDict(), (char*)"ModDate", (char*)"ModDate: "); } info.free(); #endif #else // read file wand=NewMagickWand(); // set the resolution (pixel density) MagickSetResolution(wand, 200,200); status=MagickReadImage(wand, fileName.data()); if (status == MagickFalse) ThrowWandException(wand); numImages = MagickGetNumberImages(wand); MagickSetImageIndex(wand, firstPage); // get the image size width = MagickGetImageWidth(wand); height = MagickGetImageHeight(wand); // ------- TODO: need to keep track of images that have been flipped already... // crop the image if necessary to make sure it's a multiple of 4 if (useDXT) { if (width%4 != 0 || height%4 != 0) { fprintf(stderr, "\n**** Image cropped a few pixels to be a multiple of 4 for dxt"); width -= width%4; height -= height%4; } // flip the image to have the correct orientation for dxt MagickFlipImage(wand); } #endif // allocate buffers rgba = (byte*) memalign(16, width*height*4); if (useDXT) dxt = (byte*) memalign(16, width*height*4/8); // get the first page getRGBA(); // if the user didn't specify the window size, use the image size if (window_height == -1 && window_width == -1) { window_width = width; window_height = height; } // initialize SAIL // Search for a configuration file char *tmpconf = getenv("SAGE_APP_CONFIG"); if (tmpconf) { sage::printLog("PDFViewer> found SAGE_APP_CONFIG variable: [%s]", tmpconf); scfg.init(tmpconf); } else { sage::printLog("PDFViewer> using default pdfviewer.conf"); scfg.init((char*)"pdfviewer.conf"); } scfg.setAppName("pdfviewer"); scfg.resX = width; scfg.resY = height; // if it hasn't been specified by the config file, use the app-determined size if (scfg.winWidth == -1 || scfg.winHeight == -1) { scfg.winWidth = window_width; scfg.winHeight = window_height; } if (useDXT) { scfg.pixFmt = PIXFMT_DXT; scfg.rowOrd = BOTTOM_TO_TOP; } else { scfg.pixFmt = PIXFMT_888; scfg.rowOrd = TOP_TO_BOTTOM; } sageInf.init(scfg); // finally swap the first buffer swapBuffer(); // Wait the end while (1) { usleep(50000); // so that we don't keep spinning too frequently (0.5s) sageMessage msg; if (sageInf.checkMsg(msg, false) > 0) { char *data = (char*) msg.getData(); switch (msg.getCode()) { case APP_QUIT: // release the memory free(dxt); free(rgba); #if ! defined(USE_POPPLER) DestroyMagickWand(wand); #endif sageInf.shutdown(); exit(1); break; case EVT_CLICK: // Click event x and y location normalized to size of window float clickX, clickY; // Ckick device Id, button Id, and is down flag int clickDeviceId, clickButtonId, clickIsDown, clickEvent; // Parse message sscanf(data, "%d %f %f %d %d %d", &clickDeviceId, &clickX, &clickY, &clickButtonId, &clickIsDown, &clickEvent); // record the click position so we know how far we moved if (clickIsDown && clickEvent == EVT_PAN) { lastX = clickX; lastY = clickY; } if (clickIsDown) { bool doSwap = false; #if ! defined(USE_POPPLER) if (clickButtonId==1) doSwap = MagickPreviousImage(wand); else if(clickButtonId==2) doSwap = MagickNextImage(wand); #endif // if everything went well, swap the new page if (doSwap) { getRGBA(); swapBuffer(); } } break; case EVT_PAN: // Pan event properties int panDeviceId; bool doSwap = false; // Pan event x and y location and change in x, y and z direction // normalized to size of window float startX, startY, panDX, panDY, panDZ; sscanf(data, "%d %f %f %f %f %f", &panDeviceId, &startX, &startY, &panDX, &panDY, &panDZ); // keep track of distance dist += panDX; // we started a new drag if (lastX != startX) { lastX = startX; dist = 0; } // if we dragged more than a certain distance, change a page else if( fabs(dist) > 0.07 ) { #if ! defined(USE_POPPLER) if (dist > 0) doSwap = MagickPreviousImage(wand); else doSwap = MagickNextImage(wand); #endif // reset the counter lastX = startX; dist = 0; if (doSwap) { getRGBA(); swapBuffer(); //sprintf(l, "Page %ld of %d", MagickGetImageIndex(wand)+1, numImages); } } break; } // end switch } // end if } // end while return 0; }
Eina_List * epdf_page_text_find (const Epdf_Page *page, const char *text, unsigned char is_case_sensitive) { Epdf_Rectangle *match; TextOutputDev *output_dev; Eina_List *matches = NULL; double xMin, yMin, xMax, yMax; int length; int height; if (!page || !text) return NULL; GooString tmp (text); Unicode *s; { length = tmp.getLength(); s = (Unicode *)gmallocn(length, sizeof(Unicode)); bool anyNonEncoded = false; for (int j = 0; j < length && !anyNonEncoded; ++j) { s[j] = pdfDocEncoding[tmp.getChar(j) & 0xff]; if (!s[j]) anyNonEncoded = true; } if ( anyNonEncoded ) { for (int j = 0; j < length; ++j) { s[j] = tmp.getChar(j); } } } length = strlen (text); output_dev = new TextOutputDev (NULL, 1, 0, 0); epdf_page_size_get (page, NULL, &height); page->page->display (output_dev, 72, 72, 0, false, true, false, page->doc->pdfdoc->getCatalog()); xMin = 0; yMin = 0; #warning you probably want to add backwards as parameters while (output_dev->findText (s, tmp.getLength (), 0, 1, // startAtTop, stopAtBottom 1, 0, // startAtLast, stopAtLast is_case_sensitive, 0, // caseSensitive, backwards &xMin, &yMin, &xMax, &yMax)) { match = (Epdf_Rectangle *)malloc (sizeof (Epdf_Rectangle)); match->x1 = xMin; match->y1 = yMin;//height - yMax; match->x2 = xMax; match->y2 = yMax;//height - yMin; matches = eina_list_append (matches, match); } delete output_dev; return matches; }