diff --git a/generators/xpdf/generator_pdf.cpp b/generators/xpdf/generator_pdf.cpp index 31539e721..eae82de1f 100644 --- a/generators/xpdf/generator_pdf.cpp +++ b/generators/xpdf/generator_pdf.cpp @@ -1,4 +1,4 @@ -/*************************************************************************** +/***************************** ********************************************** * Copyright (C) 2004 by Albert Astals Cid * * Copyright (C) 2004 by Enrico Ros * * * @@ -200,12 +200,12 @@ bool PDFGenerator::loadDocument( const QString & filePath, QValueVector & pagesVector, int rotation==-1, bool clear) +void PDFGenerator::loadPages(QValueVector pagesVector, int rotation, bool clear) { // TODO XPDF 3.01 check - KPDFTextDev td; + // KPDFTextDev td; int count=pagesVector.count(); - for ( uint i = 0; i < count ; i++ ) + for ( int i = 0; i < count ; i++ ) { // get xpdf page Page * p = pdfdoc->getCatalog()->getPage( i + 1 ); @@ -235,14 +235,16 @@ void PDFGenerator::loadPages(QValueVector & pagesVector, int rotation TextPage * PDFGenerator::fastTextPage (KPDFPage * page) { - // TODO XPDF 3.01 check // fetch ourselves a textpage - KPDFTextDev td; + TextOutputDev td(NULL, gTrue, gFalse, gFalse); docLock.lock(); - pdfdoc->displayPage( &td, page->number()+1, 72, 72, page->rotation(), true, false ); - TextPage * textPage = td.takeTextPage(); + pdfdoc->displayPage( &td, page->number()+1, 72, 72, page->rotation(), false, true, false ); + // ..and attach it to the page + TextPage *p=td.takeText(); + if (prefersInternalSearching()) + page->setSearchPage( abstractTextPage(p, page->height(), page->width()) ); docLock.unlock(); - return textPage; + return p; } QString * PDFGenerator::getText( const RegularAreaRect * area, KPDFPage * page ) @@ -258,7 +260,6 @@ QString * PDFGenerator::getText( const RegularAreaRect * area, KPDFPage * page right = (int)( rect->right * page->width() ); bottom = (int)( rect->bottom * page->height() ); *text= textPage->getText( left, top, right, bottom )->getCString(); - return text; } @@ -288,29 +289,24 @@ RegularAreaRect * PDFGenerator::findText (const QString & text, SearchDir dir, // this loop is only for 'bad case' Reses bool found = false; + GBool sCase= strictCase ? gTrue : gFalse; while ( !found ) { if ( dir == FromTop ) - found = textPage->findText( const_cast(static_cast(u)), len, gTrue, gTrue, gFalse, gFalse, &sLeft, &sTop, &sRight, &sBottom ); + found = textPage->findText( const_cast(static_cast(u)), len, + gTrue, gTrue, gFalse, gFalse, sCase, gFalse, &sLeft, &sTop, &sRight, &sBottom ); else if ( dir == NextRes ) - found = textPage->findText( const_cast(static_cast(u)), len, gFalse, gTrue, gTrue, gFalse, &sLeft, &sTop, &sRight, &sBottom ); + found = textPage->findText( const_cast(static_cast(u)), len, + gFalse, gTrue, gTrue, gFalse, sCase, gFalse, &sLeft, &sTop, &sRight, &sBottom ); else if ( dir == PrevRes ) - // FIXME: this doesn't work as expected (luckily backward search isn't yet used) - found = textPage->findText( const_cast(static_cast(u)), len, gTrue, gFalse, gFalse, gTrue, &sLeft, &sTop, &sRight, &sBottom ); + found = textPage->findText( const_cast(static_cast(u)), len, + gTrue, gFalse, gFalse, gTrue, sCase, gFalse, &sLeft, &sTop, &sRight, &sBottom ); // if not found (even in case unsensitive search), terminate if ( !found ) break; - - // check for case sensitivity - if ( strictCase ) - { - found = QString::fromUtf8( (textPage->getText( sLeft, sTop, sRight, sBottom ))->getCString() ) == text; - if ( !found && dir == FromTop ) - dir = NextRes; - } } - + delete textPage; // if the page was found, return a new normalizedRect if ( found ) { @@ -499,7 +495,8 @@ void PDFGenerator::generatePixmap( PixmapRequest * request ) // note: thread safety is set on 'false' for the GUI (this) thread kpdfOutputDev->setParams( request->width, request->height, genObjectRects, genObjectRects, false ); // TODO: check if this should not get a rotation parameter - pdfdoc->displayPage( kpdfOutputDev, page->number() + 1, fakeDpiX, fakeDpiY, page->rotation(), false, true, genObjectRects ); + pdfdoc->displayPage( kpdfOutputDev, page->number() + 1, fakeDpiX, fakeDpiY, page->rotation(), + false, true, genObjectRects ); // 2. Take data from outputdev and attach it to the Page page->setPixmap( request->id, kpdfOutputDev->takePixmap() ); @@ -510,7 +507,10 @@ void PDFGenerator::generatePixmap( PixmapRequest * request ) // 3. UNLOCK [re-enables shared access] docLock.unlock(); if ( genTextPage ) - generateSyncTextPage( page ); + { + TextOutputDev td(NULL, gTrue, gFalse, gFalse); + page->setSearchPage( abstractTextPage(td.takeText(), page->height(), page->width()) ); + } // update ready state ready = true; @@ -635,7 +635,7 @@ QString PDFGenerator::getMetaData( const QString & key, const QString & option ) bool PDFGenerator::reparseConfig() { // load paper color from Settings or use the white default color - QColor color = ( (Settings::renderMode() == KpdfSettings::EnumRenderMode::Paper ) && + QColor color = ( (KpdfSettings::renderMode() == KpdfSettings::EnumRenderMode::Paper ) && KpdfSettings::changeColors() ) ? KpdfSettings::paperColor() : Qt::white; // if paper color is changed we have to rebuild every visible pixmap in addition // to the outputDevice. it's the 'heaviest' case, other effect are just recoloring @@ -660,7 +660,7 @@ bool PDFGenerator::reparseConfig() } //END Generator inherited functions -static QString unicodeToQString(Unicode* u, int len) { +static QString unicodeToQString(const Unicode* u, int len) { QString ret; // we dont want to move that pointer ret.setLength(len); @@ -671,8 +671,7 @@ static QString unicodeToQString(Unicode* u, int len) { } inline void append (KPDFTextPage* ktp, - QString s, double l, double b, double r, double t, - double baseline, double rot, bool eoline) + QString s, double l, double b, double r, double t, double rot) { ktp->append( s , new NormalizedRect( @@ -681,32 +680,19 @@ inline void append (KPDFTextPage* ktp, r, t ), - baseline, - rot, eoline); + static_cast(rot)); } -inline void append(KPDFTextPage* ktp, - Unicode g, double l, double b, double r, double t, - double baseline, double rot, bool eoline) -{ - Unicode * glyph=new Unicode(g); - QString s=unicodeToQString( glyph, 1); - append(ktp, - s, l, b, r, t, - baseline, rot, eoline); - delete glyph; -} KPDFTextPage * PDFGenerator::abstractTextPage(TextPage *tp, double height, double width) { KPDFTextPage* ktp=new KPDFTextPage; TextWordList *list = tp->makeWordList(true); TextWord * word, *next; - double baseline; int wordCount=list->getLength(); int charCount=0; int i,j,rot; - QString s; + QString s,t; NormalizedRect * wordRect = new NormalizedRect; for (i=0;igetBBox(&wordRect->left,&wordRect->bottom,&wordRect->right,&wordRect->top); charCount=word->getLength(); rot=word->getRotation(); - baseline=word->getBaseline(); next=word->nextWord(); + if ( word->hasSpaceAfter() == gTrue && next ) + t=" "; + else if ( !next ) + t="\n"; + else + t=""; switch (rot) { case 0: @@ -724,32 +715,30 @@ KPDFTextPage * PDFGenerator::abstractTextPage(TextPage *tp, double height, doubl // only x boundaries change the order of letters is normal not reversed for (j=0;jgetChar(j) , + s=unicodeToQString( word->getChar(j),1); + append(ktp, s+t, // this letters boundary word->getEdge(j)/width, wordRect->bottom/height, // next letters boundary word->getEdge(j+1)/width, wordRect->top/height, - baseline, - rot, - !next); + rot); } break; - + case 1: // 90 degrees, x boundaries not changed // y ones change, the order of letters is normal not reversed for (j=0;jgetChar(j) , + s=unicodeToQString( word->getChar(j),1); + append(ktp, s+t, wordRect->left/width, word->getEdge(j)/height, wordRect->right/width, word->getEdge(j+1)/height, - baseline, - rot, - !next); + rot); } break; @@ -757,88 +746,31 @@ KPDFTextPage * PDFGenerator::abstractTextPage(TextPage *tp, double height, doubl // same as case 0 but reversed order of letters for (j=0;jgetChar(j) , + s=unicodeToQString( word->getChar(j),1); + append(ktp, s+t, word->getEdge(j+1)/width, wordRect->bottom/height, word->getEdge(j)/width, wordRect->top/height, - baseline, - rot, - !next); + rot); } break; - + case 3: for (j=0;jgetChar(j) , + s=unicodeToQString( word->getChar(j),1); + append(ktp, s+t, wordRect->left/width, word->getEdge(j+1)/height, wordRect->right/width, word->getEdge(j)/height, - baseline, - rot, - !next); + rot); } break; } - // if is followed by a space and is not last on the line - if ( word->hasSpaceAfter() == gTrue && next ) - { - - - switch (rot) - { - case 0: - append(ktp,QString(" ") , - word->getEdge(charCount)/width, - wordRect->bottom/height, - next->getEdge(0)/width, - wordRect->top/height, - baseline, - rot, - false); - break; - - case 1: - append(ktp,QString(" ") , - wordRect->left/width, - word->getEdge(charCount)/height, - wordRect->right/width, - next->getEdge(0)/height, - baseline, - rot, - false); - break; - - case 2: - append(ktp,QString(" ") , - next->getEdge(0)/width, - wordRect->bottom/height, - word->getEdge(charCount)/width, - wordRect->top/height, - baseline, - rot, - false); - - break; - - case 3: - append(ktp,QString(" ") , - wordRect->left/width, - next->getEdge(0)/height, - wordRect->right/width, - word->getEdge(charCount)/height, - baseline, - rot, - false); - break; - } - - } } - delete wordRect; delete tp; return ktp; @@ -1325,8 +1257,8 @@ void PDFGenerator::addAnnotations( Page * pdfPage, KPDFPage * page ) double MTX[6]; for ( int i = 0; i < 6; i+=2 ) { - MTX[i] = gfxCTM[i] / pdfPage->getWidth(); - MTX[i+1] = gfxCTM[i+1] / pdfPage->getHeight(); + MTX[i] = gfxCTM[i] / pdfPage->getCropWidth(); + MTX[i+1] = gfxCTM[i+1] / pdfPage->getCropHeight(); } delete gfxState; @@ -2296,7 +2228,7 @@ void PDFPixmapGeneratorThread::run() d->generator->kpdfOutputDev->setParams( width, height, genObjectRects, genObjectRects, TRUE /*thread safety*/ ); d->generator->pdfdoc->displayPage( d->generator->kpdfOutputDev, page->number() + 1, - fakeDpiX, fakeDpiY, d->currentRequest->rotation , true, genObjectRects ); + fakeDpiX, fakeDpiY, d->currentRequest->rotation , false,true, genObjectRects ); // 2. grab data from the OutputDev and store it locally (note takeIMAGE) #ifndef NDEBUG diff --git a/generators/xpdf/generator_pdf.h b/generators/xpdf/generator_pdf.h index 955608934..ff6f77fe4 100644 --- a/generators/xpdf/generator_pdf.h +++ b/generators/xpdf/generator_pdf.h @@ -55,12 +55,12 @@ class PDFGenerator : public Generator // [INHERITED] load a document and fill up the pagesVector bool loadDocument( const QString & fileName, QValueVector & pagesVector ); - void loadPages(QValueVector & pagesVector, int rotation, bool clear=false); + void loadPages(QValueVector pagesVector, int rotation=-1, bool clear=false); // [INHERITED] document informations const DocumentInfo * generateDocumentInfo(); const DocumentSynopsis * generateDocumentSynopsis(); const DocumentFonts * generateDocumentFonts(); - + // [INHERITED] document informations bool isAllowed( int permissions ); diff --git a/generators/xpdf/xpdf/xpdf/TextOutputDev.h b/generators/xpdf/xpdf/xpdf/TextOutputDev.h index faaef55d3..a475f006e 100644 --- a/generators/xpdf/xpdf/xpdf/TextOutputDev.h +++ b/generators/xpdf/xpdf/xpdf/TextOutputDev.h @@ -95,7 +95,7 @@ public: #if TEXTOUT_WORD_LIST int getLength() { return len; } - Unicode getChar(int idx) { return text[idx]; } + const Unicode* getChar(int idx) { return &text[idx]; } GString *getText(); GString *getFontName() { return font->fontName; } void getColor(double *r, double *g, double *b) @@ -103,7 +103,6 @@ public: void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA) { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; } double getFontSize() { return fontSize; } - int getRotation() { return rot; } int getCharPos() { return charPos; } int getCharLen() { return charLen; } #endif