⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qtexthtmlparser.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
      hasCssBlockIndent(false), hasCssListIndent(false), isEmptyParagraph(false), isTextFrame(false), direction(3),      displayMode(QTextHtmlElement::DisplayInline), fontPointSize(-1), fontPixelSize(-1), fontSizeAdjustment(0),      fontWeight(-1), alignment(0), verticalAlignment(QTextCharFormat::AlignNormal),      listStyle(QTextListFormat::ListStyleUndefined), imageWidth(-1), imageHeight(-1), tableBorder(0),      tableCellRowSpan(1), tableCellColSpan(1), tableCellSpacing(2), tableCellPadding(0), cssBlockIndent(0),      cssListIndent(0), text_indent(0), wsm(WhiteSpaceModeUndefined){    margin[QTextHtmlParser::MarginLeft] = 0;    margin[QTextHtmlParser::MarginRight] = 0;    margin[QTextHtmlParser::MarginTop] = 0;    margin[QTextHtmlParser::MarginBottom] = 0;}QTextCharFormat QTextHtmlParserNode::charFormat() const{    QTextCharFormat format;    if (fontItalic != Unspecified) {        format.setFontItalic(fontItalic == On);    }    if (fontUnderline != Unspecified) {        format.setFontUnderline(fontUnderline == On);    }    if (fontOverline != Unspecified) {        format.setFontOverline(fontOverline == On);    }    if (fontStrikeOut != Unspecified) {        format.setFontStrikeOut(fontStrikeOut == On);    }    if (fontFixedPitch != Unspecified) {        format.setFontFixedPitch(fontFixedPitch == On);    }    if (fontFamily.size())        format.setFontFamily(fontFamily);    if (hasFontPointSize)        format.setFontPointSize(fontPointSize);    else if (hasFontPixelSize)        format.setProperty(QTextFormat::FontPixelSize, fontPixelSize);    if (hasFontSizeAdjustment)        format.setProperty(QTextFormat::FontSizeAdjustment, fontSizeAdjustment);    if (fontWeight > 0)        format.setFontWeight(fontWeight);    if (color.isValid())        format.setForeground(QBrush(color));    if (bgColor.isValid())        format.setBackground(QBrush(bgColor));    if (verticalAlignment != QTextCharFormat::AlignNormal)        format.setVerticalAlignment(verticalAlignment);    if (isAnchor) {        format.setAnchor(true);        format.setAnchorHref(anchorHref);        format.setAnchorName(anchorName);    }    return format;}QTextBlockFormat QTextHtmlParserNode::blockFormat() const{    QTextBlockFormat format;    if (alignment)        format.setAlignment(alignment);    if (direction < 2)        format.setLayoutDirection(Qt::LayoutDirection(direction));    if (hasCssBlockIndent)        format.setIndent(cssBlockIndent);    if (text_indent != 0.)        format.setTextIndent(text_indent);    return format;}void QTextHtmlParser::dumpHtml(){    for (int i = 0; i < count(); ++i) {        qDebug().nospace() << qPrintable(QString(depth(i)*4, ' '))                           << qPrintable(at(i).tag) << ":"                           << quoteNewline(at(i).text);            ;    }}QTextHtmlParserNode *QTextHtmlParser::newNode(int parent){    QTextHtmlParserNode *lastNode = &nodes.last();    QTextHtmlParserNode *newNode = 0;    bool reuseLastNode = true;    if (nodes.count() == 1) {        reuseLastNode = false;    } else if (lastNode->tag.isEmpty()) {        if (lastNode->text.isEmpty()) {            reuseLastNode = true;        } else { // last node is a text node (empty tag) with some text            if (lastNode->text == QLatin1String(" ")) {                int lastSibling = count() - 2;                while (lastSibling                       && at(lastSibling).parent != lastNode->parent                       && at(lastSibling).displayMode == QTextHtmlElement::DisplayInline) {                    lastSibling = at(lastSibling).parent;                }                                if (at(lastSibling).displayMode == QTextHtmlElement::DisplayInline) {                    reuseLastNode = false;                } else {                    reuseLastNode = true;                }            } else {                // text node with real (non-whitespace) text -> nothing to re-use                reuseLastNode = false;            }        }    } else {        // last node had a proper tag -> nothing to re-use        reuseLastNode = false;    }    if (reuseLastNode) {        newNode = lastNode;        newNode->tag.clear();        newNode->text.clear();        newNode->id = -1;    } else {        nodes.resize(nodes.size() + 1);        newNode = &nodes.last();    }    newNode->parent = parent;    return newNode;}void QTextHtmlParser::parse(const QString &text){    nodes.clear();    nodes.resize(1);    txt = text;    pos = 0;    len = txt.length();    textEditMode = false;    parse();    //dumpHtml();}int QTextHtmlParser::depth(int i) const{    int depth = 0;    while (i) {        i = at(i).parent;        ++depth;    }    return depth;}int QTextHtmlParser::margin(int i, int mar) const {    int m = 0;    const QTextHtmlParserNode *node;    if (mar == MarginLeft        || mar == MarginRight) {        while (i) {            node = &at(i);            if (!node->isBlock)                return 0;            if (node->isTableCell)                break;            m += node->margin[mar];            i = node->parent;        }    }    return m;}int QTextHtmlParser::topMargin(int i) const{    if (!i)        return 0;    return at(i).margin[MarginTop];    // we do margin collapsing in QTextDocumentFragment#if 0    int m = 0;    const QTextHtmlParserNode *node;    while (i) {        node = &at(i);        if (!node->isBlock)            return 0;        m = qMax(m, node->margin[MarginTop]);        // collapsing margins across table cells makes no sense        if (node->isTableCell)            break;        // don't collapse margins across list items        // (the top margin of the list is merged as part of the block        // merging in documentfragment.cpp)        if (node->isListItem)            break;        // <ul>        //  ..        //  <ul> <-- this one should not take the first <ul>'s margin into account        if (node->isNestedList(this))            break;        // get previous block        while (i-1 && !at(i-1).isBlock)            --i;        if (i && node->parent == at(i).parent)            break;        i = node->parent;    }    return m;#endif}int QTextHtmlParser::bottomMargin(int i) const{    if (!i)        return 0;    return at(i).margin[MarginBottom];#if 0    // we do margin collapsing in QTextDocumentFragment    int m = 0;    const QTextHtmlParserNode *node;    while (i) {        node = &at(i);        if (!node->isBlock)            return 0;        m = qMax(m, node->margin[MarginBottom]);        // collapsing margins across table cells makes no sense        if (node->isTableCell)            break;        // don't collapse margins across list items        if (node->isListItem)            break;        // <ul>        //  ..        //  <ul> <-- this one should not take the first <ul>'s margin into account        if (node->isNestedList(this))            break;        // get next block        while (i+1 < count() && !at(i+1).isBlock)            ++i;        if (i && node->parent == at(i).parent)            break;        i = node->parent;    }    return m;#endif}void QTextHtmlParser::eatSpace(){    while (pos < len && txt.at(pos).isSpace() && txt.at(pos) != QChar::ParagraphSeparator)        pos++;}void QTextHtmlParser::parse() {    QTextHtmlParserNode::WhiteSpaceMode wsm = QTextHtmlParserNode::WhiteSpaceNormal;    while (pos < len) {                QChar c = txt.at(pos++);        if (c == QLatin1Char('<')) {            parseTag();            wsm = nodes.last().wsm;        } else if (c == QLatin1Char('&')) {            nodes.last().text += parseEntity();        } else {            if (c.isSpace() && c != QChar(QChar::Nbsp) && c != QChar::ParagraphSeparator) {                if (wsm == QTextHtmlParserNode::WhiteSpacePre                    || textEditMode) {                    if (c == QLatin1Char('\n'))                        c = QChar::LineSeparator;                    else if (c == QLatin1Char('\r'))                        continue;                    if (textEditMode                        && c == QChar::LineSeparator)                        continue;                } else if (wsm != QTextHtmlParserNode::WhiteSpacePreWrap) { // non-pre mode: collapse whitespace except nbsp                    while (pos < len && txt.at(pos).isSpace()                           && txt.at(pos) != QChar::Nbsp)                        pos++;                    if (wsm == QTextHtmlParserNode::WhiteSpaceNoWrap)                        c = QChar::Nbsp;                    else                        c = QLatin1Char(' ');                }            }            nodes.last().text += c;        }    }}// parses a tag after "<"void QTextHtmlParser::parseTag(){    eatSpace();    // handle comments and other exclamation mark declarations    if (hasPrefix(QLatin1Char('!'))) {        parseExclamationTag();        if (nodes.last().wsm != QTextHtmlParserNode::WhiteSpacePre            && nodes.last().wsm != QTextHtmlParserNode::WhiteSpacePreWrap            && !textEditMode)            eatSpace();        return;    }    // if close tag just close    if (hasPrefix(QLatin1Char('/'))) {        parseCloseTag();        return;    }    int p = last();    while (p && at(p).tag.size() == 0)        p = at(p).parent;    QTextHtmlParserNode *node = newNode(p);    // parse tag name    node->tag = parseWord().toLower();    const QTextHtmlElement *elem = ::lookupElement(node->tag);    if (elem->name) {        node->id = elem->id;        node->isBlock = (elem->displayMode == QTextHtmlElement::DisplayBlock);        node->displayMode = elem->displayMode;    } else {        node->id = -1;    }    node->isListItem = (node->id == Html_li);    node->isListStart = (node->id == Html_ol || node->id == Html_ul);    node->isTableCell = (node->id == Html_td || node->id == Html_th);    resolveParent();    resolveNode();    QColor inheritedNodeColor = node->color;    node->color = QColor();    // _need_ at least one space after the tag name, otherwise there can't be attributes    if (pos < len && txt.at(pos).isSpace())        parseAttributes();    // special handling for anchors with href attribute (hyperlinks)    if (node->isAnchor && !node->anchorHref.isEmpty()) {        node->fontUnderline = On; // #### remove 4.2        if (!node->color.isValid())            node->color = Qt::blue; // #### remove 4.2    } else {        if (!node->color.isValid())            node->color = inheritedNodeColor;    }    // finish tag    bool tagClosed = false;    while (pos < len && txt.at(pos) != QLatin1Char('>')) {        if (txt.at(pos) == QLatin1Char('/'))             tagClosed = true;                pos++;    }    pos++;    if (node->wsm != QTextHtmlParserNode::WhiteSpacePre        && node->wsm != QTextHtmlParserNode::WhiteSpacePreWrap        && !textEditMode)        eatSpace();    if (node->mayNotHaveChildren() || tagClosed) {        newNode(node->parent);        resolveNode();    }}// parses a tag beginning with "/"void QTextHtmlParser::parseCloseTag(){    ++pos;    QString tag = parseWord().toLower().trimmed();    while (pos < len) {        QChar c = txt.at(pos++);        if (c == QLatin1Char('>'))            break;    }    // find corresponding open node    int p = last();    if (p > 0        && at(p - 1).tag == tag        && at(p - 1).mayNotHaveChildren())        p--;    while (p && at(p).tag != tag)        p = at(p).parent;    // simply ignore the tag if we can't find    // a corresponding open node, for broken    // html such as <font>blah</font></font>    if (!p)        return;    newNode(at(p).parent);    resolveNode();}// parses a tag beginning with "!"void QTextHtmlParser::parseExclamationTag()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -