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

📄 render_inline.cpp

📁 konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版本源码包.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{    if (pointArray.size() < 3) return false;    QValueVector<QPoint>::Iterator it = pointArray.end();    QPoint p0 = *--it;    QPoint p1 = *--it;    QPoint p2 = *--it;    bool elide = false;    if (p0.x() == p1.x() && p1.x() == p2.x()        && (p1.y() < p0.y() && p0.y() < p2.y()            || p2.y() < p0.y() && p0.y() < p1.y()            || p1.y() < p2.y() && p2.y() < p0.y()            || p0.y() < p2.y() && p2.y() < p1.y()            || (elide = p2.y() == p0.y() && p0.y() < p1.y())            || (elide = p1.y() < p0.y() && p0.y() == p2.y()))        || p0.y() == p1.y() && p1.y() == p2.y()        && (p1.x() < p0.x() && p0.x() < p2.x()            || p2.x() < p0.x() && p0.x() < p1.x()            || p1.x() < p2.x() && p2.x() < p0.x()            || p0.x() < p2.x() && p2.x() < p1.x()            || (elide = p2.x() == p0.x() && p0.x() < p1.x())            || (elide = p1.x() < p0.x() && p0.x() == p2.x())))    {//     kdDebug(6040) << "spikered p2" << (elide ? " (elide)" : "") << ": " << p2 << " p1: " << p1 << " p0: " << p0 << endl;        pointArray.pop_back(); pointArray.pop_back();        if (!elide)            pointArray.push_back(p0);        return true;    }    return false;}/** * Reduces segment separators. * * A segment separator separates a segment into two segments, thus causing * two adjacent segment with the same orientation. * * 2       1     0 * x-------x---->x * (0 means stack-top) * * Here, 1 is a segment separator. As segment separators not only make * the line drawing algorithm inefficient, but also make the spike-reduction * fail, they must be eliminated: * * 1             0 * x------------>x * * Preconditions: * - No other segment separators exist in the whole point-array except *   at most one at the end * - No two succeeding points are ever equal * - For each two succeeding points either p1.x == p2.x or p1.y == p2.y holds *   true * - No such spike exists where 2 is situated between 0 and 1. * * Postcondition: * - No segment separators exist in the whole point-array * * If no segment separator is found at the end of the point-array, it is * left unchanged. * @return \c true if a segment separator was actually reduced. */inline static bool reduceSegmentSeparator(QValueVector<QPoint> &pointArray){    if (pointArray.size() < 3) return false;    QValueVector<QPoint>::Iterator it = pointArray.end();    QPoint p0 = *--it;    QPoint p1 = *--it;    QPoint p2 = *--it;//     kdDebug(6040) << "checking p2: " << p2 << " p1: " << p1 << " p0: " << p0 << endl;    if (p0.x() == p1.x() && p1.x() == p2.x()        && (p2.y() < p1.y() && p1.y() < p0.y()            || p0.y() < p1.y() && p1.y() < p2.y())        || p0.y() == p1.y() && p1.y() == p2.y()        && (p2.x() < p1.x() && p1.x() < p0.x()            || p0.x() < p1.x() && p1.x() < p2.x()))    {//     kdDebug(6040) << "segred p2: " << p2 << " p1: " << p1 << " p0: " << p0 << endl;        pointArray.pop_back(); pointArray.pop_back();        pointArray.push_back(p0);        return true;    }    return false;}/** * Appends the given point to the point-array, doing necessary reductions to * produce a path without spikes and segment separators. */static void appendPoint(QValueVector<QPoint> &pointArray, QPoint &pnt){  if (!appendIfNew(pointArray, pnt)) return;//   kdDebug(6040) << "appendPoint: appended " << pnt << endl;  reduceSegmentSeparator(pointArray)  || reduceSpike(pointArray);}/** * Traverses the horizontal inline boxes and appends the point coordinates to * the given array. * @param box inline box * @param pointArray array collecting coordinates * @param bottom \c true, collect bottom coordinates, \c false, collect top * 	coordinates. * @param limit lower limit that an y-coordinate must at least reach. Note *	that limit designates the highest y-coordinate for \c bottom, and *	the lowest for !\c bottom. */static void collectHorizontalBoxCoordinates(InlineBox *box,                                            QValueVector<QPoint> &pointArray,                                            bool bottom, int limit = -500000){//   kdDebug(6000) << "collectHorizontalBoxCoordinates: " << endl;    int y = box->yPos() + bottom*box->height();    if (limit != -500000 && (bottom ? y < limit : y > limit))        y = limit;    int x = box->xPos() + bottom*box->width();    QPoint newPnt(x, y);    // Add intersection point if point-array not empty.    if (!pointArray.isEmpty()) {        QPoint lastPnt = pointArray.back();        QPoint insPnt(newPnt.x(), lastPnt.y());//         kdDebug(6040) << "left: " << lastPnt << " == " << insPnt << ": " << (insPnt == lastPnt) << endl;        appendPoint(pointArray, insPnt);    }    // Insert starting point of box    appendPoint(pointArray, newPnt);    newPnt.rx() += bottom ? -box->width() : box->width();    if (box->isInlineFlowBox()) {        InlineFlowBox *flowBox = static_cast<InlineFlowBox *>(box);        for (InlineBox *b = bottom ? flowBox->lastChild() : flowBox->firstChild(); b; b = bottom ? b->prevOnLine() : b->nextOnLine()) {            // Don't let boxes smaller than this flow box' height influence            // the vertical position of the outline if they have a different            // x-coordinate            int l2;            if (b->xPos() != box->xPos() && b->xPos() + b->width() != box->xPos() + box->width())              l2 = y;            else              l2 = limit;            collectHorizontalBoxCoordinates(b, pointArray, bottom, l2);        }        // Add intersection point if flow box contained any children        if (flowBox->firstChild()) {            QPoint lastPnt = pointArray.back();            QPoint insPnt(lastPnt.x(), newPnt.y());//             kdDebug(6040) << "right: " << lastPnt << " == " << insPnt << ": " << (insPnt == lastPnt) << endl;            appendPoint(pointArray, insPnt);        }    }    // Insert ending point of box    appendPoint(pointArray, newPnt);//     kdDebug(6000) << "collectHorizontalBoxCoordinates: " << "ende" << endl;}/** * Checks whether the given line box' extents and the following line box' * extents are disjount (i. e. do not share the same x-coordinate range). * @param line line box * @param toBegin \c true, compare with preceding line box, \c false, with *	succeeding * @return \c true if this and the next box are disjoint */inline static bool lineBoxesDisjoint(InlineRunBox *line, bool toBegin){  InlineRunBox *next = toBegin ? line->prevLineBox() : line->nextLineBox();  return !next || next->xPos() + next->width() < line->xPos()               || next->xPos() > line->xPos() + line->width();}/** * Traverses the vertical outer borders of the given render flow's line * boxes and appends the point coordinates to the given point array. * @param line line box to begin traversal * @param pointArray point array * @param left \c true, traverse the left vertical coordinates, *	\c false, traverse the right vertical coordinates. * @param lastline if not 0, returns the pointer to the last line box traversed */static void collectVerticalBoxCoordinates(InlineRunBox *line,                                          QValueVector<QPoint> &pointArray,                                          bool left, InlineRunBox **lastline = 0){    InlineRunBox *last = 0;    for (InlineRunBox* curr = line; curr && !last; curr = left ? curr->prevLineBox() : curr->nextLineBox()) {        InlineBox *root = curr;        bool isLast = lineBoxesDisjoint(curr, left);        if (isLast) last = curr;        if (root != line && !isLast)            while (root->parent()) root = root->parent();        QPoint newPnt(curr->xPos() + !left*curr->width(),                      left ? root->topOverflow() : root->bottomOverflow());        if (!pointArray.isEmpty()) {            QPoint lastPnt = pointArray.back();            if (newPnt.x()>lastPnt.x() && !left)                pointArray.back().setY( kMin(lastPnt.y(), root->topOverflow()) );            else if (newPnt.x()<lastPnt.x() && left)                pointArray.back().setY( kMax(lastPnt.y(), root->bottomOverflow()) );            QPoint insPnt(newPnt.x(), pointArray.back().y());//         kdDebug(6040) << "left: " << lastPnt << " == " << insPnt << ": " << (insPnt == lastPnt) << endl;            appendPoint(pointArray, insPnt);        }        appendPoint(pointArray, newPnt);    }    if (lastline) *lastline = last;}/** * Links up the end of the given point-array such that the starting point * is not a segment separator. * * To achieve this, improper points are removed from the beginning of * the point-array (by changing the array's starting iterator), and * proper ones appended to the point-array's back. * * @param pointArray point-array * @return actual begin of point array */static QPoint *linkEndToBegin(QValueVector<QPoint> &pointArray){    uint index = 0;    Q_ASSERT(pointArray.size() >= 3);    // if first and last points match, ignore the last one.    bool linkup = false; QPoint linkupPnt;    if (pointArray.front() == pointArray.back()) {        linkupPnt = pointArray.back();        pointArray.pop_back();        linkup = true;    }    const QPoint *it = pointArray.begin() + index;    QPoint pfirst = *it;    QPoint pnext = *++it;    QPoint plast = pointArray.back();//     kdDebug(6040) << "linkcheck plast: " << plast << " pfirst: " << pfirst << " pnext: " << pnext << endl;    if (plast.x() == pfirst.x() && pfirst.x() == pnext.x()        || plast.y() == pfirst.y() && pfirst.y() == pnext.y()) {        ++index;        appendPoint(pointArray, pfirst);        appendPoint(pointArray, pnext);    } else if (linkup)      pointArray.push_back(linkupPnt);    return pointArray.begin() + index;}void RenderInline::paintOutlines(QPainter *p, int _tx, int _ty){    if (style()->outlineWidth() == 0 || style()->outlineStyle() <= BHIDDEN)        return;    // We may have to draw more than one outline path as they may be    // disjoint.    for (InlineRunBox *curr = firstLineBox(); curr; curr = curr->nextLineBox()) {        QValueVector<QPoint> path;        // collect topmost outline        collectHorizontalBoxCoordinates(curr, path, false);        // collect right outline        collectVerticalBoxCoordinates(curr, path, false, &curr);        // collect bottommost outline        collectHorizontalBoxCoordinates(curr, path, true);        // collect left outline        collectVerticalBoxCoordinates(curr, path, true);        const QPoint *begin = linkEndToBegin(path);        // paint the outline        paintOutlinePath(p, _tx, _ty, begin, path.end(), BSLeft, -1, BSTop);    }}template<class T> inline void kSwap(T &a1, T &a2){    T tmp = a2;    a2 = a1;    a1 = tmp;}enum BSOrientation { BSHorizontal, BSVertical };/** * Returns the orientation of the given border side. */inline BSOrientation bsOrientation(RenderObject::BorderSide bs){    switch (bs) {    case RenderObject::BSTop:    case RenderObject::BSBottom:        return BSHorizontal;    case RenderObject::BSLeft:    case RenderObject::BSRight:        return BSVertical;    }    return BSHorizontal;	// make gcc happy (sigh)}/** * Determines the new border side by evaluating the new direction as determined * by the given coordinates, the old border side, and the relative direction. * * The relative direction specifies whether the old border side meets with the * straight given by the coordinates from below (negative), or above (positive). */inline RenderObject::BorderSide newBorderSide(RenderObject::BorderSide oldBS, int direction, const QPoint &last, const QPoint &cur){

⌨️ 快捷键说明

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