diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2013-01-26 13:17:21 -0600 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2013-01-26 13:17:21 -0600 |
commit | dfe289850f068f19ba4a83ab4e7e22a7e09c13c9 (patch) | |
tree | c297348a55df66c571de4525646e0b9762427353 /khtml/rendering/render_inline.cpp | |
parent | b7658a0d5eca24a9d37c6e04f88298ef02389db0 (diff) | |
download | tdelibs-dfe289850f068f19ba4a83ab4e7e22a7e09c13c9.tar.gz tdelibs-dfe289850f068f19ba4a83ab4e7e22a7e09c13c9.zip |
Rename a number of libraries and executables to avoid conflicts with KDE4
Diffstat (limited to 'khtml/rendering/render_inline.cpp')
-rw-r--r-- | khtml/rendering/render_inline.cpp | 935 |
1 files changed, 0 insertions, 935 deletions
diff --git a/khtml/rendering/render_inline.cpp b/khtml/rendering/render_inline.cpp deleted file mode 100644 index c3eb08d4b..000000000 --- a/khtml/rendering/render_inline.cpp +++ /dev/null @@ -1,935 +0,0 @@ -/* - * This file is part of the render object implementation for KHTML. - * - * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) - * (C) 1999-2003 Antti Koivisto (koivisto@kde.org) - * (C) 2002-2003 Dirk Mueller (mueller@kde.org) - * (C) 2003 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include <kglobal.h> - -#include "rendering/render_arena.h" -#include "rendering/render_inline.h" -#include "rendering/render_block.h" -#include "xml/dom_docimpl.h" - -#include <tqvaluevector.h> - -using namespace khtml; - -void RenderInline::setStyle(RenderStyle* _style) -{ - RenderFlow::setStyle(_style); - setInline(true); - - // Ensure that all of the split inlines pick up the new style. We - // only do this if we're an inline, since we don't want to propagate - // a block's style to the other inlines. - // e.g., <font>foo <h4>goo</h4> moo</font>. The <font> inlines before - // and after the block share the same style, but the block doesn't - // need to pass its style on to anyone else. - RenderFlow* currCont = continuation(); - while (currCont) { - if (currCont->isInline()) { - RenderFlow* nextCont = currCont->continuation(); - currCont->setContinuation(0); - currCont->setStyle(style()); - currCont->setContinuation(nextCont); - } - currCont = currCont->continuation(); - } - - if (attached()) { - // Update replaced content - updateReplacedContent(); - // Update pseudos for ::before and ::after - updatePseudoChildren(); - } -} - -// Attach handles initial setStyle that requires parent nodes -void RenderInline::attach() -{ - RenderFlow::attach(); - - updateReplacedContent(); - updatePseudoChildren(); -} - -bool RenderInline::isInlineContinuation() const -{ - return m_isContinuation; -} - -void RenderInline::addChildToFlow(RenderObject* newChild, RenderObject* beforeChild) -{ - // Make sure we don't append things after :after-generated content if we have it. - if (!beforeChild && lastChild() && lastChild()->style()->styleType() == RenderStyle::AFTER) - beforeChild = lastChild(); - - if (!newChild->isText() && newChild->style()->position() != STATIC) - setOverhangingContents(); - - if (!newChild->isInline() && !newChild->isFloatingOrPositioned() ) - { - // We are placing a block inside an inline. We have to perform a split of this - // inline into continuations. This involves creating an anonymous block box to hold - // |newChild|. We then make that block box a continuation of this inline. We take all of - // the children after |beforeChild| and put them in a clone of this object. - - RenderBlock *newBox = createAnonymousBlock(); - RenderFlow* oldContinuation = continuation(); - setContinuation(newBox); - - splitFlow(beforeChild, newBox, newChild, oldContinuation); - return; - } - - RenderBox::addChild(newChild,beforeChild); - - newChild->setNeedsLayoutAndMinMaxRecalc(); -} - -RenderInline* RenderInline::cloneInline(RenderFlow* src) -{ - RenderInline *o = new (src->renderArena()) RenderInline(src->element()); - o->m_isContinuation = true; - o->setStyle(src->style()); - return o; -} - -void RenderInline::splitInlines(RenderBlock* fromBlock, RenderBlock* toBlock, - RenderBlock* middleBlock, - RenderObject* beforeChild, RenderFlow* oldCont) -{ - // Create a clone of this inline. - RenderInline* clone = cloneInline(this); - clone->setContinuation(oldCont); - - // Now take all of the children from beforeChild to the end and remove - // then from |this| and place them in the clone. - RenderObject* o = beforeChild; - while (o) { - RenderObject* tmp = o; - o = tmp->nextSibling(); - clone->addChildToFlow(removeChildNode(tmp), 0); - tmp->setNeedsLayoutAndMinMaxRecalc(); - } - - // Hook |clone| up as the continuation of the middle block. - middleBlock->setContinuation(clone); - - // We have been reparented and are now under the fromBlock. We need - // to walk up our inline parent chain until we hit the containing block. - // Once we hit the containing block we're done. - RenderFlow* curr = static_cast<RenderFlow*>(parent()); - RenderFlow* currChild = this; - while (curr && curr != fromBlock) { - // Create a new clone. - RenderInline* cloneChild = clone; - clone = cloneInline(curr); - - // Insert our child clone as the first child. - clone->addChildToFlow(cloneChild, 0); - - // Hook the clone up as a continuation of |curr|. - RenderFlow* oldCont = curr->continuation(); - curr->setContinuation(clone); - clone->setContinuation(oldCont); - - // Now we need to take all of the children starting from the first child - // *after* currChild and append them all to the clone. - o = currChild->nextSibling(); - while (o) { - RenderObject* tmp = o; - o = tmp->nextSibling(); - clone->appendChildNode(curr->removeChildNode(tmp)); - tmp->setNeedsLayoutAndMinMaxRecalc(); - } - - // Keep walking up the chain. - currChild = curr; - curr = static_cast<RenderFlow*>(curr->parent()); - } - - // Now we are at the block level. We need to put the clone into the toBlock. - toBlock->appendChildNode(clone); - - // Now take all the children after currChild and remove them from the fromBlock - // and put them in the toBlock. - o = currChild->nextSibling(); - while (o) { - RenderObject* tmp = o; - o = tmp->nextSibling(); - toBlock->appendChildNode(fromBlock->removeChildNode(tmp)); - } -} - -void RenderInline::splitFlow(RenderObject* beforeChild, RenderBlock* newBlockBox, - RenderObject* newChild, RenderFlow* oldCont) -{ - RenderBlock* pre = 0; - RenderBlock* block = containingBlock(); - bool madeNewBeforeBlock = false; - if (block->isAnonymousBlock()) { - // We can reuse this block and make it the preBlock of the next continuation. - pre = block; - block = block->containingBlock(); - } - else { - // No anonymous block available for use. Make one. - pre = block->createAnonymousBlock(); - madeNewBeforeBlock = true; - } - - RenderBlock* post = block->createAnonymousBlock(); - - RenderObject* boxFirst = madeNewBeforeBlock ? block->firstChild() : pre->nextSibling(); - if (madeNewBeforeBlock) - block->insertChildNode(pre, boxFirst); - block->insertChildNode(newBlockBox, boxFirst); - block->insertChildNode(post, boxFirst); - block->setChildrenInline(false); - - if (madeNewBeforeBlock) { - RenderObject* o = boxFirst; - while (o) - { - RenderObject* no = o; - o = no->nextSibling(); - pre->appendChildNode(block->removeChildNode(no)); - no->setNeedsLayoutAndMinMaxRecalc(); - } - } - - splitInlines(pre, post, newBlockBox, beforeChild, oldCont); - - // We already know the newBlockBox isn't going to contain inline kids, so avoid wasting - // time in makeChildrenNonInline by just setting this explicitly up front. - newBlockBox->setChildrenInline(false); - - // We don't just call addChild, since it would pass things off to the - // continuation, so we call addChildToFlow explicitly instead. We delayed - // adding the newChild until now so that the |newBlockBox| would be fully - // connected, thus allowing newChild access to a renderArena should it need - // to wrap itself in additional boxes (e.g., table construction). - newBlockBox->addChildToFlow(newChild, 0); - - // XXXdwh is any of this even necessary? I don't think it is. - pre->close(); - pre->setPos(0, -500000); - pre->setNeedsLayout(true); - newBlockBox->close(); - newBlockBox->setPos(0, -500000); - newBlockBox->setNeedsLayout(true); - post->close(); - post->setPos(0, -500000); - post->setNeedsLayout(true); - - updatePseudoChildren(); - - block->setNeedsLayoutAndMinMaxRecalc(); -} - -void RenderInline::paint(PaintInfo& i, int _tx, int _ty) -{ - paintLines(i, _tx, _ty); -} - -/** - * Appends the given coordinate-pair to the point-array if it is not - * equal to the last element. - * @param pointArray point-array - * @param pnt point to append - * @return \c true if \c pnt has actually been appended - */ -inline static bool appendIfNew(TQValueVector<TQPoint> &pointArray, const TQPoint &pnt) -{ -// if (!pointArray.isEmpty()) kdDebug(6040) << "appifnew: " << pointArray.back() << " == " << pnt << ": " << (pointArray.back() == pnt) << endl; -// else kdDebug(6040) << "appifnew: " << pnt << " (unconditional)" << endl; - if (!pointArray.isEmpty() && pointArray.back() == pnt) return false; - pointArray.append(pnt); - return true; -} - -/** - * Does spike-reduction on the given point-array's stack-top. - * - * Spikes are path segments of which one goes forward, and the sucessor - * goes backward on the predecessor's segment: - * - * 2 0 1 - * x------x<-----x - * (0 is stack-top in point-array) - * - * This will be reduced to - * 1 0 - * x------x - * - * Preconditions: - * - No other spikes 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 spikes exist in the whole point-array - * - * If no spike is found, the point-array is left unchanged. - * @return \c true if an actual reduction was done - */ -inline static bool reduceSpike(TQValueVector<TQPoint> &pointArray) -{ - if (pointArray.size() < 3) return false; - TQValueVector<TQPoint>::Iterator it = pointArray.end(); - TQPoint p0 = *--it; - TQPoint p1 = *--it; - TQPoint 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(TQValueVector<TQPoint> &pointArray) -{ - if (pointArray.size() < 3) return false; - TQValueVector<TQPoint>::Iterator it = pointArray.end(); - TQPoint p0 = *--it; - TQPoint p1 = *--it; - TQPoint 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(TQValueVector<TQPoint> &pointArray, TQPoint &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, - TQValueVector<TQPoint> &pointArray, - bool bottom, int offset, int limit = -500000) -{ -// kdDebug(6000) << "collectHorizontalBoxCoordinates: " << endl; - offset = bottom ? offset:-offset; - int y = box->yPos() + bottom*box->height() + offset; - if (limit != -500000 && (bottom ? y < limit : y > limit)) - y = limit; - int x = box->xPos() + bottom*box->width() + offset; - TQPoint newPnt(x, y); - // Add intersection point if point-array not empty. - if (!pointArray.isEmpty()) { - TQPoint lastPnt = pointArray.back(); - TQPoint insPnt(newPnt.x(), lastPnt.y()); - if (offset && ((bottom && lastPnt.y() > y) || (!bottom && lastPnt.y() < y))) { - insPnt.rx() = lastPnt.x(); - insPnt.ry() = 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()) - 2*offset; - - 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, kAbs(offset), l2); - } - - // Add intersection point if flow box contained any children - if (flowBox->firstChild()) { - TQPoint lastPnt = pointArray.back(); - TQPoint 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, int offset, bool toBegin) -{ - InlineRunBox *next = toBegin ? line->prevLineBox() : line->nextLineBox(); - return !next || next->xPos() + next->width() + 2*offset < line->xPos() - || next->xPos() > line->xPos() + line->width() + 2*offset; -} - -/** - * 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, - TQValueVector<TQPoint> &pointArray, - bool left, int offset, InlineRunBox **lastline = 0) -{ - InlineRunBox *last = 0; - offset = left ? -offset:offset; - for (InlineRunBox* curr = line; curr && !last; curr = left ? curr->prevLineBox() : curr->nextLineBox()) { - InlineBox *root = curr; - - bool isLast = lineBoxesDisjoint(curr, kAbs(offset), left); - if (isLast) last = curr; - - if (root != line && !isLast) - while (root->parent()) root = root->parent(); - TQPoint newPnt(curr->xPos() + !left*curr->width() + offset, - (left ? root->topOverflow() : root->bottomOverflow()) + offset); - if (!pointArray.isEmpty()) { - TQPoint lastPnt = pointArray.back(); - if (newPnt.x()>lastPnt.x() && !left) - pointArray.back().setY( kMin(lastPnt.y(), root->topOverflow()-offset) ); - else if (newPnt.x()<lastPnt.x() && left) - pointArray.back().setY( kMax(lastPnt.y(), root->bottomOverflow()+offset) ); - TQPoint 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 TQPoint *linkEndToBegin(TQValueVector<TQPoint> &pointArray) -{ - uint index = 0; - assert(pointArray.size() >= 3); - - // if first and last points match, ignore the last one. - bool linkup = false; TQPoint linkupPnt; - if (pointArray.front() == pointArray.back()) { - linkupPnt = pointArray.back(); - pointArray.pop_back(); - linkup = true; - } - - const TQPoint *it = pointArray.begin() + index; - TQPoint pfirst = *it; - TQPoint pnext = *++it; - TQPoint 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(TQPainter *p, int _tx, int _ty) -{ - if (style()->outlineWidth() == 0 || style()->outlineStyle() <= BHIDDEN) - return; - int offset = style()->outlineOffset(); - - // We may have to draw more than one outline path as they may be - // disjoint. - for (InlineRunBox *curr = firstLineBox(); curr; curr = curr->nextLineBox()) { - TQValueVector<TQPoint> path; - - // collect topmost outline - collectHorizontalBoxCoordinates(curr, path, false, offset); - // collect right outline - collectVerticalBoxCoordinates(curr, path, false, offset, &curr); - // collect bottommost outline - collectHorizontalBoxCoordinates(curr, path, true, offset); - // collect left outline - collectVerticalBoxCoordinates(curr, path, true, offset); - - if (path.size() < 3) continue; - - const TQPoint *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 TQPoint &last, const TQPoint &cur) -{ - 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, TQPainter *p, int tx, int ty, - const TQPoint &p1, const TQPoint &p2, - RenderObject::BorderSide prevBS, - RenderObject::BorderSide curBS, - RenderObject::BorderSide nextBS) -{ - int ow = o->style()->outlineWidth(); - EBorderStyle os = o->style()->outlineStyle(); - TQColor oc = o->style()->outlineColor(); - - int x1 = tx + p1.x(); - int y1 = ty + p1.y(); - int x2 = tx + p2.x(); - int y2 = ty + p2.y(); - 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(TQColor("#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(TQPainter *p, int tx, int ty, const TQPoint *begin, const TQPoint *end, BorderSide bs, int direction, BorderSide endingBS) -{ - int ow = style()->outlineWidth(); - if (ow == 0 || m_isContinuation) // Continuations get painted by the original inline. - return; - - TQPoint 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 TQPoint *it = begin; it != end; ++it) { - TQPoint cur = *it; -// kdDebug(6040) << "cur: " << cur << endl; - BorderSide nextBS; - if (it + 1 != end) { - TQPoint 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. - inside = hitTestLines(info, _x, _y, _tx, _ty, hitTestAction); - } - - 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 TQFontMetrics &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 TQFontMetrics &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; -} - |