File indexing completed on 2024-05-05 04:43:23
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2001-2007 by OpenMFG, LLC (info@openmfg.com) 0003 * Copyright (C) 2007-2008 by Adam Pigg (adam@piggz.co.uk) 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Lesser General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2.1 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Lesser General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Lesser General Public 0016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 0017 */ 0018 0019 #include "KReportPrintRenderer_p.h" 0020 #include "kreport_debug.h" 0021 #include "KReportRenderObjects.h" 0022 #include "KReportPageSize.h" 0023 #include "KReportUtils_p.h" 0024 0025 #include <QApplication> 0026 #include <QPainter> 0027 #include <QPrinter> 0028 0029 namespace KReportPrivate { 0030 0031 PrintRenderer::PrintRenderer() 0032 { 0033 } 0034 0035 PrintRenderer::~PrintRenderer() 0036 { 0037 } 0038 0039 bool PrintRenderer::setupPrinter( ORODocument * document, QPrinter * pPrinter) 0040 { 0041 if (document == nullptr || pPrinter == nullptr) 0042 return false; 0043 0044 pPrinter->setCreator(QLatin1String("KReport Print Renderer")); 0045 pPrinter->setDocName(document->title()); 0046 pPrinter->setFullPage(true); 0047 pPrinter->setOrientation((document->pageLayout().orientation() == QPageLayout::Portrait ? QPrinter::Portrait : QPrinter::Landscape)); 0048 pPrinter->setPageOrder(QPrinter::FirstPageFirst); 0049 0050 // if (!document->pageLayout().pageSize().isValid()) { 0051 // pPrinter->setPageSize(QPageSize(QSize(document->pageLayout().getCustomWidth(), document->pageLayout().getCustomHeight()), QLatin1String("Custom")); 0052 // } else { 0053 pPrinter->setPageSize(QPageSize(document->pageLayout().pageSize())); 0054 // } 0055 0056 return true; 0057 } 0058 0059 bool PrintRenderer::render(const KReportRendererContext &context, ORODocument *document, int page) 0060 { 0061 Q_UNUSED(page); 0062 if (document == nullptr || context.printer() == nullptr || context.painter() == nullptr) 0063 return false; 0064 0065 setupPrinter(document, context.printer()); 0066 0067 bool endWhenComplete = false; 0068 0069 0070 if (!context.painter()->isActive()) { 0071 endWhenComplete = true; 0072 if (!context.painter()->begin(context.printer())) 0073 return false; 0074 } 0075 0076 int fromPage = context.printer()->fromPage(); 0077 if (fromPage > 0) 0078 fromPage -= 1; 0079 int toPage = context.printer()->toPage(); 0080 if (toPage == 0 || toPage > document->pageCount()) 0081 toPage = document->pageCount(); 0082 0083 qreal scaleX = context.printer()->resolution() / qreal(KReportPrivate::dpiX()); 0084 qreal scaleY = context.printer()->resolution() / qreal(KReportPrivate::dpiY()); 0085 0086 0087 for (int copy = 0; copy < context.printer()->numCopies(); copy++) { 0088 for (int page = fromPage; page < toPage; page++) { 0089 if (page > fromPage) 0090 context.printer()->newPage(); 0091 0092 OROPage * p = document->page(page); 0093 if (context.printer()->pageOrder() == QPrinter::LastPageFirst) 0094 p = document->page(toPage - 1 - page); 0095 0096 // Render Page Objects 0097 for (int i = 0; i < p->primitiveCount(); i++) { 0098 OROPrimitive * prim = p->primitive(i); 0099 0100 0101 prim->setPosition(QPointF(prim->position().x() * scaleX, prim->position().y() * scaleY)); 0102 prim->setSize(QSizeF(prim->size().width() * scaleX, prim->size().height() * scaleY)); 0103 //kreportDebug() << "Rendering object" << i << "type" << prim->type(); 0104 if (OROTextBox *tb = dynamic_cast<OROTextBox*>(prim)) { 0105 QPointF ps = tb->position(); 0106 QSizeF sz = tb->size(); 0107 QRectF rc = QRectF(ps.x(), ps.y(), sz.width(), sz.height()); 0108 0109 context.painter()->save(); 0110 //Background 0111 0112 QColor bg = tb->textStyle().backgroundColor; 0113 bg.setAlphaF(0.01 * tb->textStyle().backgroundOpacity); 0114 0115 //_painter()->setBackgroundMode(Qt::OpaqueMode); 0116 context.painter()->fillRect(rc, bg); 0117 0118 //Text 0119 context.painter()->setBackgroundMode(Qt::TransparentMode); 0120 context.painter()->setFont(tb->textStyle().font); 0121 context.painter()->setPen(tb->textStyle().foregroundColor); 0122 context.painter()->drawText(rc, tb->flags(), tb->text()); 0123 0124 //outer line 0125 context.painter()->setPen(QPen(tb->lineStyle().color(), tb->lineStyle().weight() * scaleX, tb->lineStyle().penStyle())); 0126 context.painter()->drawRect(rc); 0127 0128 //Reset back to defaults for next element 0129 context.painter()->restore(); 0130 0131 } else if (OROLine *ln = dynamic_cast<OROLine*>(prim)) { 0132 QPointF s = ln->startPoint(); 0133 QPointF e(ln->endPoint().x() * scaleX, ln->endPoint().y() * scaleY); 0134 //QPen pen ( _painter()->pen() ); 0135 QPen pen(ln->lineStyle().color(), ln->lineStyle().weight() * scaleX, ln->lineStyle().penStyle()); 0136 0137 context.painter()->save(); 0138 context.painter()->setRenderHint(QPainter::Antialiasing, true); 0139 context.painter()->setPen(pen); 0140 context.painter()->drawLine(QLineF(s.x(), s.y(), e.x(), e.y())); 0141 context.painter()->setRenderHint(QPainter::Antialiasing, false); 0142 context.painter()->restore(); 0143 } else if (OROImage *im = dynamic_cast<OROImage*>(prim)) { 0144 QPointF ps = im->position(); 0145 QSizeF sz = im->size(); 0146 QRectF rc = QRectF(ps.x(), ps.y(), sz.width(), sz.height()); 0147 0148 QImage img = im->image(); 0149 if (im->isScaled()) 0150 img = img.scaled(rc.size().toSize(), (Qt::AspectRatioMode) im->aspectRatioMode(), (Qt::TransformationMode) im->transformationMode()); 0151 0152 QRectF sr = QRectF(QPointF(0.0, 0.0), rc.size().boundedTo(img.size())); 0153 context.painter()->drawImage(rc.topLeft(), img, sr); 0154 } else if (ORORect *re = dynamic_cast<ORORect*>(prim)) { 0155 QPointF ps = re->position(); 0156 QSizeF sz = re->size(); 0157 QRectF rc = QRectF(ps.x(), ps.y(), sz.width(), sz.height()); 0158 0159 context.painter()->save(); 0160 context.painter()->setPen(re->pen()); 0161 context.painter()->setBrush(re->brush()); 0162 context.painter()->drawRect(rc); 0163 context.painter()->restore(); 0164 } else if (OROEllipse *re = dynamic_cast<OROEllipse*>(prim)) { 0165 QPointF ps = re->position(); 0166 QSizeF sz = re->size(); 0167 QRectF rc = QRectF(ps.x(), ps.y(), sz.width(), sz.height()); 0168 0169 context.painter()->save(); 0170 context.painter()->setPen(re->pen()); 0171 context.painter()->setBrush(re->brush()); 0172 context.painter()->drawEllipse(rc); 0173 context.painter()->restore(); 0174 } else if (OROPicture *im = dynamic_cast<OROPicture*>(prim)) { 0175 QPointF ps = im->position(); 0176 QSizeF sz = im->size(); 0177 QRectF rc = QRectF(ps.x(), ps.y(), sz.width(), sz.height()); 0178 context.painter()->drawPicture(rc.topLeft(), *(im->picture())); 0179 } else if (OROCheckBox *chk = dynamic_cast<OROCheckBox*>(prim)) { 0180 QPointF ps = chk->position(); 0181 QSizeF sz = chk->size(); 0182 QRectF rc = QRectF(ps.x(), ps.y(), sz.width(), sz.height()); 0183 0184 context.painter()->save(); 0185 0186 context.painter()->setBackgroundMode(Qt::OpaqueMode); 0187 context.painter()->setRenderHint(QPainter::Antialiasing); 0188 0189 context.painter()->setPen(chk->foregroundColor()); 0190 0191 if (chk->lineStyle().penStyle() == Qt::NoPen || chk->lineStyle().weight() <= 0) { 0192 context.painter()->setPen(QPen(Qt::lightGray)); 0193 } else { 0194 context.painter()->setPen(QPen(chk->lineStyle().color(), chk->lineStyle().weight() * scaleX, chk->lineStyle().penStyle())); 0195 } 0196 0197 qreal ox = sz.width() / 5; 0198 qreal oy = sz.height() / 5; 0199 0200 //Checkbox Style 0201 if (chk->checkType() == OROCheckBox::Type::Cross) { 0202 context.painter()->drawRoundedRect(rc, sz.width() / 10 , sz.height() / 10); 0203 0204 if (chk->value()) { 0205 QPen lp; 0206 lp.setColor(chk->foregroundColor()); 0207 lp.setWidth(ox > oy ? oy : ox); 0208 context.painter()->setPen(lp); 0209 context.painter()->drawLine(QPointF(ox, oy) + ps, QPointF(sz.width() - ox, sz.height() - oy) + ps); 0210 context.painter()->drawLine(QPointF(ox, sz.height() - oy) + ps, QPoint(sz.width() - ox, oy) + ps); 0211 } 0212 } else if (chk->checkType() == OROCheckBox::Type::Dot) { 0213 //Radio Style 0214 context.painter()->drawEllipse(rc); 0215 0216 if (chk->value()) { 0217 QBrush lb(chk->foregroundColor()); 0218 context.painter()->setBrush(lb); 0219 context.painter()->setPen(Qt::NoPen); 0220 context.painter()->drawEllipse(rc.center(), sz.width() / 2 - ox, sz.height() / 2 - oy); 0221 } 0222 } else { 0223 //Tickbox Style 0224 context.painter()->drawRoundedRect(rc, sz.width() / 10 , sz.height() / 10); 0225 0226 if (chk->value()) { 0227 QPen lp; 0228 lp.setColor(chk->foregroundColor()); 0229 lp.setWidth(ox > oy ? oy : ox); 0230 context.painter()->setPen(lp); 0231 context.painter()->drawLine(QPointF(ox, sz.height() / 2) + ps, QPointF(sz.width() / 2, sz.height() - oy) + ps); 0232 context.painter()->drawLine(QPointF(sz.width() / 2, sz.height() - oy) + ps, QPointF(sz.width() - ox, oy) + ps); 0233 } 0234 } 0235 context.painter()->restore(); 0236 } 0237 } 0238 } 0239 } 0240 0241 if (endWhenComplete) 0242 context.painter()->end(); 0243 0244 return true; 0245 } 0246 0247 }