📄 render_inline.cpp
字号:
bool below = direction < 0; if (last.x() == cur.x()) { // new segment is vertical bool t = oldBS == RenderObject::BSTop; bool b = oldBS == RenderObject::BSBottom; if ((t || b) && last.y() != cur.y()) return (cur.y() < last.y()) ^ (t && below || b && !below) ? RenderObject::BSLeft : RenderObject::BSRight; } else /*if (last.y() == cur.y())*/ { // new segment is horizontal bool l = oldBS == RenderObject::BSLeft; bool r = oldBS == RenderObject::BSRight; if ((l || r) && last.x() != cur.x()) return (cur.x() < last.x()) ^ (l && below || r && !below) ? RenderObject::BSTop : RenderObject::BSBottom; } return oldBS; // same direction}/** * Draws an outline segment between the given two points. * @param o render object * @param p painter * @param tx absolute x-coordinate of containing block * @param ty absolute y-coordinate of containing block * @param p1 starting point * @param p2 end point * @param prevBS border side of previous segment * @param curBS border side of this segment * @param nextBS border side of next segment */static void paintOutlineSegment(RenderObject *o, QPainter *p, int tx, int ty, const QPoint &p1, const QPoint &p2, RenderObject::BorderSide prevBS, RenderObject::BorderSide curBS, RenderObject::BorderSide nextBS){ int ow = o->style()->outlineWidth(); EBorderStyle os = o->style()->outlineStyle(); QColor oc = o->style()->outlineColor(); // ### outline-offset is not this simple to merge anymore int offset = 0; // o->style()->outlineOffset(); int x1 = tx + p1.x() - offset; int y1 = ty + p1.y() - offset; int x2 = tx + p2.x() + offset; int y2 = ty + p2.y() + offset; if (x1 > x2) { kSwap(x1, x2); if (bsOrientation(curBS) == BSHorizontal) kSwap(prevBS, nextBS); } if (y1 > y2) { kSwap(y1, y2); if (bsOrientation(curBS) == BSVertical) kSwap(prevBS, nextBS); }// kdDebug(6040) << "segment(" << x1 << "," << y1 << ") - (" << x2 << "," << y2 << ")" << endl;/* p->setPen(Qt::gray); p->drawLine(x1,y1,x2,y2);*/ switch (curBS) { case RenderObject::BSLeft: case RenderObject::BSRight:/* p->setPen(QColor("#ffe4dd")); p->drawLine( x1 - (curBS == RenderObject::BSLeft ? ow : 0), y1 - (prevBS == RenderObject::BSTop ? ow : 0), x2 + (curBS == RenderObject::BSRight ? ow : 0), y2 + (nextBS == RenderObject::BSBottom ? ow : 0) );*/ o->drawBorder(p, x1 - (curBS == RenderObject::BSLeft ? ow : 0), y1 - (prevBS == RenderObject::BSTop ? ow : 0), x2 + (curBS == RenderObject::BSRight ? ow : 0), y2 + (nextBS == RenderObject::BSBottom ? ow : 0), curBS, oc, o->style()->color(), os, prevBS == RenderObject::BSTop ? ow : prevBS == RenderObject::BSBottom ? -ow : 0, nextBS == RenderObject::BSTop ? -ow : nextBS == RenderObject::BSBottom ? ow : 0, true); break; case RenderObject::BSBottom: case RenderObject::BSTop:// kdDebug(6040) << "BSTop/BSBottom: prevBS " << prevBS << " curBS " << curBS << " nextBS " << nextBS << endl; o->drawBorder(p, x1 - (prevBS == RenderObject::BSLeft ? ow : 0), y1 - (curBS == RenderObject::BSTop ? ow : 0), x2 + (nextBS == RenderObject::BSRight ? ow : 0), y2 + (curBS == RenderObject::BSBottom ? ow : 0), curBS, oc, o->style()->color(), os, prevBS == RenderObject::BSLeft ? ow : prevBS == RenderObject::BSRight ? -ow : 0, nextBS == RenderObject::BSLeft ? -ow : nextBS == RenderObject::BSRight ? ow : 0, true); break; }}void RenderInline::paintOutlinePath(QPainter *p, int tx, int ty, const QPoint *begin, const QPoint *end, BorderSide bs, int direction, BorderSide endingBS){ int ow = style()->outlineWidth(); if (ow == 0 || m_isContinuation) // Continuations get painted by the original inline. return; QPoint last = *begin; BorderSide lastBS = bs; Q_ASSERT(begin != end); ++begin;// kdDebug(6040) << "last: " << last << endl; bs = newBorderSide(bs, direction, last, *begin);// kdDebug(6040) << "newBorderSide: " << lastBS << " " << direction << "d " << last << " - " << *begin << " => " << bs << endl; for (const QPoint *it = begin; it != end; ++it) { QPoint cur = *it;// kdDebug(6040) << "cur: " << cur << endl; BorderSide nextBS; if (it + 1 != end) { QPoint diff = cur - last; direction = diff.x() + diff.y(); nextBS = newBorderSide(bs, direction, cur, *(it + 1));// kdDebug(6040) << "newBorderSide*: " << bs << " " << direction << "d " << cur << " - " << *(it + 1) << " => " << nextBS << endl; } else nextBS = endingBS; Q_ASSERT(bsOrientation(bs) != bsOrientation(nextBS)); paintOutlineSegment(this, p, tx, ty, last, cur, lastBS, bs, nextBS); lastBS = bs; last = cur; bs = nextBS; }}void RenderInline::calcMinMaxWidth(){ KHTMLAssert( !minMaxKnown() );#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << renderName() << "(RenderInline)::calcMinMaxWidth() this=" << this << endl;#endif // Irrelevant, since some enclosing block will actually measure us and our children. m_minWidth = 0; m_maxWidth = 0; setMinMaxKnown();}short RenderInline::width() const{ // Return the width of the minimal left side and the maximal right side. short leftSide = 0; short rightSide = 0; for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) { if (curr == firstLineBox() || curr->xPos() < leftSide) leftSide = curr->xPos(); if (curr == firstLineBox() || curr->xPos() + curr->width() > rightSide) rightSide = curr->xPos() + curr->width(); } return rightSide - leftSide;}int RenderInline::height() const{ int h = 0; if (firstLineBox()) h = lastLineBox()->yPos() + lastLineBox()->height() - firstLineBox()->yPos(); return h;}int RenderInline::offsetLeft() const{ int x = RenderFlow::offsetLeft(); if (firstLineBox()) x += firstLineBox()->xPos(); return x;}int RenderInline::offsetTop() const{ int y = RenderFlow::offsetTop(); if (firstLineBox()) y += firstLineBox()->yPos(); return y;}const char *RenderInline::renderName() const{ if (isRelPositioned()) return "RenderInline (relative positioned)"; if (isAnonymous()) return "RenderInline (anonymous)"; return "RenderInline";}bool RenderInline::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction, bool inside){ if ( hitTestAction != HitTestSelfOnly ) { for (RenderObject* child = lastChild(); child; child = child->previousSibling()) if (!child->layer() && !child->isFloating() && child->nodeAtPoint(info, _x, _y, _tx, _ty, HitTestAll)) inside = true; } // Check our line boxes if we're still not inside. if (hitTestAction != HitTestChildrenOnly && !inside && style()->visibility() != HIDDEN) { // See if we're inside one of our line boxes. for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) { if((_y >=_ty + curr->m_y) && (_y < _ty + curr->m_y + curr->m_height) && (_x >= _tx + curr->m_x) && (_x <_tx + curr->m_x + curr->m_width) ) { inside = true; break; } } } if (inside && element()) { if (info.innerNode() && info.innerNode()->renderer() && !info.innerNode()->renderer()->isInline()) { // Within the same layer, inlines are ALWAYS fully above blocks. Change inner node. info.setInnerNode(element()); // Clear everything else. info.setInnerNonSharedNode(0); info.setURLElement(0); } if (!info.innerNode()) info.setInnerNode(element()); if(!info.innerNonSharedNode()) info.setInnerNonSharedNode(element()); } return inside;}void RenderInline::caretPos(int offset, int flags, int &_x, int &_y, int &width, int &height){ _x = -1; RenderBlock *cb = containingBlock(); bool rtl = cb->style()->direction() == RTL; bool outsideEnd = flags & CFOutsideEnd; // I need to explain that: outsideEnd contains a meaningful value if // and only if flags & CFOutside is set. If it is not, then randomly // either the first or the last line box is returned. // This doesn't matter because the only case this can happen is on an // empty inline element, whose first and last line boxes are actually // the same. InlineFlowBox *line = !outsideEnd ^ rtl ? firstLineBox() : lastLineBox(); if (!line) { // umpf, handle "gracefully" RenderFlow::caretPos(offset, flags, _x, _y, width, height); return; } _x = line->xPos(); width = 1; // ### regard CFOverride // Place caret outside the border if (flags & CFOutside) { RenderStyle *s = element() && element()->parent() && element()->parent()->renderer() ? element()->parent()->renderer()->style() : style(); const QFontMetrics &fm = s->fontMetrics(); _y = line->yPos() + line->baseline() - fm.ascent(); height = fm.height(); if (!outsideEnd ^ rtl) { _x -= line->marginBorderPaddingLeft(); } else { _x += line->width() + line->marginBorderPaddingRight(); } } else { const QFontMetrics &fm = style()->fontMetrics(); _y = line->yPos() + line->baseline() - fm.ascent(); height = fm.height(); } int absx, absy; if (cb && cb->absolutePosition(absx,absy)) { //kdDebug(6040) << "absx=" << absx << " absy=" << absy << endl; _x += absx; _y += absy; } else { // we don't know our absolute position, and there is no point returning // just a relative one _x = _y = -1; }}inline int minXPos(const RenderInline *o){ int retval=6666666; if (!o->firstLineBox()) return 0; for (InlineRunBox* curr = o->firstLineBox(); curr; curr = curr->nextLineBox()) retval = kMin( retval, int( curr->m_x )); return retval;}int RenderInline::inlineXPos() const{ return minXPos(this);}int RenderInline::inlineYPos() const{ return firstLineBox() ? firstLineBox()->yPos() : 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -