📄 qtextdocument.cpp
字号:
// Check that there is a valid device to print to. if (!p.isActive()) return; const QTextDocument *doc = this; QTextDocument *clonedDoc = 0; (void)doc->documentLayout(); // make sure that there is a layout QRectF body = QRectF(QPointF(0, 0), d->pageSize); QPointF pageNumberPos; if (d->pageSize.isValid() && d->pageSize.height() != INT_MAX) { extern int qt_defaultDpi(); qreal sourceDpiX = qt_defaultDpi(); qreal sourceDpiY = sourceDpiX; QPaintDevice *dev = doc->documentLayout()->paintDevice(); if (dev) { sourceDpiX = dev->logicalDpiX(); sourceDpiY = dev->logicalDpiY(); } const qreal dpiScaleX = qreal(printer->logicalDpiX()) / sourceDpiX; const qreal dpiScaleY = qreal(printer->logicalDpiY()) / sourceDpiY; // scale to dpi p.scale(dpiScaleX, dpiScaleY); QSizeF scaledPageSize = d->pageSize; scaledPageSize.rwidth() *= dpiScaleX; scaledPageSize.rheight() *= dpiScaleY; const QSizeF printerPageSize(printer->width(), printer->height()); // scale to page p.scale(printerPageSize.width() / scaledPageSize.width(), printerPageSize.height() / scaledPageSize.height()); } else { doc = clone(const_cast<QTextDocument *>(this)); clonedDoc = const_cast<QTextDocument *>(doc); QAbstractTextDocumentLayout *layout = doc->documentLayout(); layout->setPaintDevice(p.device()); const int dpiy = p.device()->logicalDpiY(); const int margin = (int) ((2/2.54)*dpiy); // 2 cm margins QTextFrameFormat fmt = doc->rootFrame()->frameFormat(); fmt.setMargin(margin); doc->rootFrame()->setFrameFormat(fmt); body = QRectF(0, 0, p.device()->width(), p.device()->height()); pageNumberPos = QPointF(body.width() - margin, body.height() - margin + QFontMetrics(doc->defaultFont(), p.device()).ascent() + 5 * p.device()->logicalDpiY() / 72); QFont font(doc->defaultFont()); font.setPointSize(10); // we define 10pt to be a nice base size for printing clonedDoc->setDefaultFont(font); clonedDoc->setPageSize(body.size()); } int docCopies; int pageCopies; if (printer->collateCopies() == true){ docCopies = 1; pageCopies = printer->numCopies(); } else { docCopies = printer->numCopies(); pageCopies = 1; } int fromPage = printer->fromPage(); int toPage = printer->toPage(); bool ascending = true; if (fromPage == 0 && toPage == 0) { fromPage = 1; toPage = doc->pageCount(); } if (printer->pageOrder() == QPrinter::LastPageFirst) { int tmp = fromPage; fromPage = toPage; toPage = tmp; ascending = false; } for (int i = 0; i < docCopies; ++i) { int page = fromPage; while (true) { for (int j = 0; j < pageCopies; ++j) { if (printer->printerState() == QPrinter::Aborted || printer->printerState() == QPrinter::Error) goto UserCanceled; printPage(page, &p, doc, body, pageNumberPos); if (j < pageCopies - 1) printer->newPage(); } if (page == toPage) break; if (ascending) ++page; else --page; printer->newPage(); } if ( i < docCopies - 1) printer->newPage(); }UserCanceled: delete clonedDoc;}#endif/*! \enum QTextDocument::ResourceType This enum describes the types of resources that can be loaded by QTextDocument's loadResource() function. \value HtmlResource The resource contains HTML. \value ImageResource The resource contains image data. \value UserResource The first available value for user defined resource types. \sa loadResource()*//*! Returns data of the specified \a type from the resource with the given \a name. This function is called by the rich text engine to request data that isn't directly stored by QTextDocument, but still associated with it. For example, images are referenced indirectly by the name attribute of a QTextImageFormat object. Resources are cached internally in the document. If a resource can not be found in the cache, loadResource is called to try to load the resource. loadResource should then use addResource to add the resource to the cache.*/QVariant QTextDocument::resource(int type, const QUrl &name) const{ Q_D(const QTextDocument); QVariant r = d->resources.value(name); if (!r.isValid()) { r = d->cachedResources.value(name); if (!r.isValid()) r = const_cast<QTextDocument *>(this)->loadResource(type, name); } return r;}/*! Adds the resource \a resource to the resource cache, using \a type and \a name as identifiers.*/void QTextDocument::addResource(int type, const QUrl &name, const QVariant &resource){ Q_UNUSED(type); Q_D(QTextDocument); d->resources.insert(name, resource);}/*! Loads data of the specified \a type from the resource with the given \a name. This function is called by the rich text engine to request data that isn't directly stored by QTextDocument, but still associated with it. For example, images are referenced indirectly by the name attribute of a QTextImageFormat object. When called by Qt, \a type is one of the values of QTextDocument::ResourceType. If the QTextDocument is a child object of a QTextEdit, QTextBrowser, or a QTextDocument itself then the default implementation tries to retrieve the data from the parent.*/QVariant QTextDocument::loadResource(int type, const QUrl &name){ Q_D(QTextDocument); QVariant r; if (QTextDocument *doc = qobject_cast<QTextDocument *>(parent())) r = doc->loadResource(type, name);#ifndef QT_NO_TEXTEDIT else if (QTextEdit *edit = qobject_cast<QTextEdit *>(parent())) r = edit->loadResource(type, name);#endif if (!r.isNull()) { if (type == ImageResource && r.type() == QVariant::ByteArray) { QPixmap pm; pm.loadFromData(r.toByteArray()); if (!pm.isNull()) r = pm; } d->cachedResources.insert(name, r); } return r;}static QTextFormat formatDifference(const QTextFormat &from, const QTextFormat &to){ QTextFormat diff = to; const QMap<int, QVariant> props = to.properties(); for (QMap<int, QVariant>::ConstIterator it = props.begin(), end = props.end(); it != end; ++it) if (it.value() == from.property(it.key())) diff.clearProperty(it.key()); return diff;}QTextHtmlExporter::QTextHtmlExporter(const QTextDocument *_doc) : doc(_doc), fragmentMarkers(false){ const QFont defaultFont = doc->defaultFont(); defaultCharFormat.setFont(defaultFont);}/*! Returns the document in HTML format. The conversion may not be perfect, especially for complex documents, due to the limitations of HTML.*/QString QTextHtmlExporter::toHtml(const QByteArray &encoding){ html = QLatin1String("<html><head><meta name=\"qrichtext\" content=\"1\" />"); html.reserve(doc->docHandle()->length()); if (!encoding.isEmpty()) html += QString("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%1\" />").arg(QString::fromAscii(encoding)); QString title = doc->metaInformation(QTextDocument::DocumentTitle); if (!title.isEmpty()) html += "<title>" + title + "</title>"; html += QString("</head><body style=\" white-space: pre-wrap;"); html += QLatin1String(" font-family:"); html += defaultCharFormat.fontFamily(); html += QLatin1Char(';'); if (defaultCharFormat.hasProperty(QTextFormat::FontPointSize)) { html += QLatin1String(" font-size:"); html += QString::number(defaultCharFormat.fontPointSize()); html += QLatin1String("pt;"); } html += QLatin1String(" font-weight:"); html += QString::number(defaultCharFormat.fontWeight() * 8); html += QLatin1Char(';'); html += QLatin1String(" font-style:"); html += (defaultCharFormat.fontItalic() ? QLatin1String("italic") : QLatin1String("normal")); html += QLatin1Char(';'); { html += QLatin1String(" text-decoration:"); bool atLeastOneDecorationSet = false; if (defaultCharFormat.fontUnderline()) { html += QLatin1String(" underline"); atLeastOneDecorationSet = true; } if (defaultCharFormat.fontOverline()) { html += QLatin1String(" overline"); atLeastOneDecorationSet = true; } if (defaultCharFormat.fontStrikeOut()) { html += QLatin1String(" line-through"); atLeastOneDecorationSet = true; } if (!atLeastOneDecorationSet) html += QLatin1String("none"); html += QLatin1Char(';'); } html += QLatin1Char('\"'); const QTextFrameFormat fmt = doc->rootFrame()->frameFormat(); QBrush bg = fmt.background(); if (bg != Qt::NoBrush) emitAttribute("bgcolor", bg.color().name()); html += QLatin1Char('>'); emitFrame(doc->rootFrame()->begin()); html += QLatin1String("</body></html>"); return html;}void QTextHtmlExporter::emitAttribute(const char *attribute, const QString &value){ html += QLatin1Char(' '); html += attribute; html += QLatin1String("=\""); html += value; html += QLatin1Char('"');}bool QTextHtmlExporter::emitCharFormatStyle(const QTextCharFormat &format){ bool attributesEmitted = false; { const QString family = format.fontFamily(); if (!family.isEmpty() && family != defaultCharFormat.fontFamily()) { html += QLatin1String(" font-family:"); html += family; html += QLatin1Char(';'); attributesEmitted = true; } } if (format.hasProperty(QTextFormat::FontPointSize) && format.fontPointSize() != defaultCharFormat.fontPointSize()) { html += QLatin1String(" font-size:"); html += QString::number(format.fontPointSize()); html += QLatin1String("pt;"); attributesEmitted = true; } if (format.fontWeight() != defaultCharFormat.fontWeight()) { html += QLatin1String(" font-weight:"); html += QString::number(format.fontWeight() * 8); html += QLatin1Char(';'); attributesEmitted = true; } if (format.fontItalic() != defaultCharFormat.fontItalic()) { html += QLatin1String(" font-style:"); html += (format.fontItalic() ? QLatin1String("italic") : QLatin1String("normal")); html += QLatin1Char(';'); attributesEmitted = true; } QLatin1String decorationTag(" text-decoration:"); html += decorationTag; bool hasDecoration = false; bool atLeastOneDecorationSet = false; if (format.fontUnderline() != defaultCharFormat.fontUnderline()) { hasDecoration = true; if (format.fontUnderline()) { html += QLatin1String(" underline"); atLeastOneDecorationSet = true; } } if (format.fontOverline() != defaultCharFormat.fontOverline()) { hasDecoration = true; if (format.fontOverline()) { html += QLatin1String(" overline"); atLeastOneDecorationSet = true; } } if (format.fontStrikeOut() != defaultCharFormat.fontStrikeOut()) { hasDecoration = true; if (format.fontStrikeOut()) { html += QLatin1String(" line-through"); atLeastOneDecorationSet = true; } } if (hasDecoration) { if (!atLeastOneDecorationSet) html += QLatin1String("none"); html += QLatin1Char(';'); attributesEmitted = true; } else { html.chop(qstrlen(decorationTag.latin1())); } if (format.foreground() != defaultCharFormat.foreground() && format.foreground().style() != Qt::NoBrush) { html += QLatin1String(" color:"); html += format.foreground().color().name(); html += QLatin1Char(';'); attributesEmitted = true; } if (format.background() != defaultCharFormat.background() && format.background().style() != Qt::NoBrush) { html += QLatin1String(" background-color:"); html += format.background().color().name(); html += QLatin1Char(';'); attributesEmitted = true; } if (format.verticalAlignment() != defaultCharFormat.verticalAlignment()) { html += QLatin1String(" vertical-align:"); QTextCharFormat::VerticalAlignment valign = format.verticalAlignment(); if (valign == QTextCharFormat::AlignSubScript) html += QLatin1String("sub"); else if (valign == QTextCharFormat::AlignSuperScript) html += QLatin1String("super"); html += QLatin1Char(';'); attributesEmitted = true; } return attributesEmitted;}bool QTextHtmlExporter::emitLogicalFontSize(const QTextCharFormat &format){ if (!format.hasProperty(QTextFormat::FontSizeAdjustment)) return false; int logSize = 3 + format.property(QTextFormat::FontSizeAdjustment).toInt(); html += QLatin1String("<font size=\""); html += QString::number(logSize); html += QLatin1String("\">"); return true;}void QTextHtmlExporter::emitTextLength(const char *attribute, const QTextLength &length){ if (length.type() == QTextLength::VariableLength) // default return; html += QLatin1Char(' '); html += attribute; html += QLatin1String("=\""); html += QString::number(length.rawValue()); if (length.type() == QTextLength::PercentageLength) html += QLatin1String("%\""); else html += QLatin1String("\"");}void QTextHtmlExporter::emitAlignment(Qt::Alignment align){ if (align & Qt::AlignLeft) return; else if (align & Qt::AlignRight) html += QLatin1String(" align=\"right\""); else if (align & Qt::AlignHCenter) html += QLatin1String(" align=\"center\""); else if (align & Qt::AlignJustify) html += QLatin1String(" align=\"justify\"");}void QTextHtmlExporter::emitFloatStyle(QTextFrameFormat::Position pos, StyleMode mode){ if (pos == QTextFrameFormat::InFlow) return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -