Details
-
Suggestion
-
Resolution: Unresolved
-
P3: Somewhat important
-
None
-
4.5.0
-
None
Description
Adds basic outlining(TOC), to the printer class and implements it for the PDF printer. This will enable, the on-the-side bookmarks/toc/outline that one often finds in pdf readers. Two functions are added to the print engine api, one for starting an outline section, as arguments it takes the name of the section, the page where it starts, and the location on the page, (0.0,0.0) being top left and (1.0, 1.0) being bottom right. And a second call that ends a section. This way sections are handled in a stack like fashion.
Patch:
diff -ur qt-x11-opensource-src-4.5.0-old/src/gui/painting/qprintengine.h qt-x11-opensource-src-4.5.0/src/gui/painting/qprintengine.h
— qt-x11-opensource-src-4.5.0-old/src/gui/painting/qprintengine.h 2009-02-25 22:09:23.000000000 +0100
+++ qt-x11-opensource-src-4.5.0/src/gui/painting/qprintengine.h 2009-03-10 20:31:32.000000000 +0100
@@ -95,6 +95,8 @@
virtual QVariant property(PrintEnginePropertyKey key) const = 0;
virtual bool newPage() = 0;
+ virtual void beginSectionOutline(const QString & text, uint page, const QPointF & location)
+ virtual void endSectionOutline() {}
virtual bool abort() = 0;
virtual int metric(QPaintDevice::PaintDeviceMetric) const = 0;
diff -ur qt-x11-opensource-src-4.5.0-old/src/gui/painting/qprintengine_pdf.cpp qt-x11-opensource-src-4.5.0/src/gui/painting/qprintengine_pdf.cpp
— qt-x11-opensource-src-4.5.0-old/src/gui/painting/qprintengine_pdf.cpp 2009-02-25 22:09:23.000000000 +0100
+++ qt-x11-opensource-src-4.5.0/src/gui/painting/qprintengine_pdf.cpp 2009-03-10 20:31:32.000000000 +0100
@@ -115,6 +115,28 @@
state = QPrinter::Idle;
}
+void QPdfEngine::beginSectionOutline(const QString & text, uint p, const QPointF & location) {
+ Q_D(QPdfEngine);
+ if(d->outlineCurrent == NULL)
+ QPdfEnginePrivate::OutlineItem * i = new QPdfEnginePrivate::OutlineItem(text, p, location);
+ i->parent = d->outlineCurrent;
+ i->prev = d->outlineCurrent->lastChild;
+ if(d->outlineCurrent->firstChild)
+ d->outlineCurrent->lastChild->next = i;
+ else
+ d->outlineCurrent->firstChild = i;
+ d->outlineCurrent->lastChild = i;
+ d->outlineCurrent = i;
+}
+
+void QPdfEngine::endSectionOutline()
+
QPdfEngine::~QPdfEngine()
{
}
@@ -156,6 +178,24 @@
bool QPdfEngine::end()
{
Q_D(QPdfEngine);
+
+ if(d->outlineRoot)
+
+ d->catalog = d->addXrefEntry(-1);
+ d->xprintf("<<\n"
+ "/Type /Catalog\n"
+ "/Pages %d 0 R\n", d->pageRoot);
+ if(d->outlineRoot)
+ d->xprintf("/Outlines %d 0 R\n"
+ "/PageMode /UseOutlines", d->outlineRoot->obj);
+ d->xprintf(">>\n"
+ "endobj\n");
d->writeTail();
d->stream->unsetDevice();
@@ -305,14 +345,59 @@
stream = new QDataStream;
pageOrder = QPrinter::FirstPageFirst;
orientation = QPrinter::Portrait;
+ outlineRoot = NULL;
+ outlineCurrent = NULL;
fullPage = false;
}
QPdfEnginePrivate::~QPdfEnginePrivate()
{ + if(outlineRoot) delete outlineRoot; delete stream; }+void QPdfEnginePrivate::writeOutlineChildren(OutlineItem * node) {
+ for(OutlineItem * i = node->firstChild; i != NULL; i = i->next)
+ i->obj = requestObject();
+ for(OutlineItem * i = node->firstChild; i != NULL; i = i->next) {
+ QPdfEnginePrivate::writeOutlineChildren;
+ addXrefEntry(i->obj);
+ xprintf("<</Title (",254,255);
+ const ushort * tit = i->text.utf16();
+ int l=0;
+ for(;tit[l]; ++l);
+ ushort * buff = new ushort[l*2+2];
+ buff[0] = 0xFEFF;
+ char * buff_;
+ for(int j=0; j<l;++j) buff[j+1] = tit[j];
+ ++l;
+ buff_ = (char*)buff;
+ if((unsigned char)buff_[0] == 0xFF)
+ for(int j=0; j < l;++j)
+
+ stream->writeRawData(buff_, l*2);
+ streampos += l*2;
+ delete[] buff;
+ double x = width() * qMax(0.0,qMin(1.0,i->location.x()));
+ double y = height() * qMax(0.0,qMin(1.0,(1.0 - i->location.y())));
+ xprintf(")\n"
+ " /Parent %d 0 R\n"
+ " /Dest [%d 0 R /XYZ %lf %lf null]\n"
+ " /Count 0\n",
+ i->parent->obj,
+ pages[i->page<pages.size()?i->page:pages.size()-1],x,y);
+ if(i->next) xprintf(" /Next %d 0 R\n", i->next->obj);
+ if(i->prev) xprintf(" /Prev %d 0 R\n", i->prev->obj);
+ if(i->firstChild) xprintf(" /First %d 0 R\n", i->firstChild->obj);
+ if(i->lastChild) xprintf(" /Last %d 0 R\n", i->lastChild->obj);
+ xprintf(">>\n"
+ "endobj\n");
+ }
+}
#ifdef USE_NATIVE_GRADIENTS
int QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject)
@@ -901,13 +985,7 @@
writeInfo();
- catalog = addXrefEntry(-1);
pageRoot = requestObject(); - xprintf("<<\n"
- "/Type /Catalog\n"
- "/Pages %d 0 R\n"
- ">>\n"
- "endobj\n", pageRoot);
// graphics state
graphicsState = addXrefEntry(-1);
diff -ur qt-x11-opensource-src-4.5.0-old/src/gui/painting/qprintengine_pdf_p.h qt-x11-opensource-src-4.5.0/src/gui/painting/qprintengine_pdf_p.h
— qt-x11-opensource-src-4.5.0-old/src/gui/painting/qprintengine_pdf_p.h 2009-02-25 22:09:23.000000000 +0100
+++ qt-x11-opensource-src-4.5.0/src/gui/painting/qprintengine_pdf_p.h 2009-03-10 20:31:32.000000000 +0100
@@ -113,6 +113,8 @@
QString author() const;
void setDevice(QIODevice* dev);
+ void beginSectionOutline(const QString & text, uint page, const QPointF & location);
+ void endSectionOutline();
private:
Q_DISABLE_COPY(QPdfEngine)
@@ -124,5 +126,34 @@
{
Q_DECLARE_PUBLIC(QPdfEngine)
public:
+ class OutlineItem {
+ public:
+ OutlineItem * parent;
+ OutlineItem * next;
+ OutlineItem * prev;
+ OutlineItem * firstChild;
+ OutlineItem * lastChild;
+ uint obj;
+ QString text;
+ uint page;
+ QPointF location;
+
+ OutlineItem(const QString & t, uint p, const QPointF & l):
+ parent(NULL), next(NULL), prev(NULL), firstChild(NULL), lastChild(NULL),
+ obj(0), text(t), page(p), location(l) {}
+ ~OutlineItem() {
+ OutlineItem * i = firstChild;
+ while(i != NULL)
+ }
+ };
+
+ OutlineItem * outlineRoot;
+ OutlineItem * outlineCurrent;
+ void writeOutlineChildren(OutlineItem * node);
+
QPdfEnginePrivate(QPrinter::PrinterMode m);
~QPdfEnginePrivate();
Attachments
Issue Links
- is required for
-
QTBUG-25379 QtPrintSupport - PDF Issues
- Open
-
QTBUG-25385 QtPrintSupport - New Feature Requests
- Open