VisiblePosition RenderReplaced::positionForPoint(const IntPoint& point) { InlineBox* box = inlineBoxWrapper(); if (!box) return createVisiblePosition(0, DOWNSTREAM); // FIXME: This code is buggy if the replaced element is relative positioned. RootInlineBox* root = box->root(); int top = root->selectionTop(); int bottom = root->selectionBottom(); int blockDirectionPosition = box->isHorizontal() ? point.y() + y() : point.x() + x(); int lineDirectionPosition = box->isHorizontal() ? point.x() + x() : point.y() + y(); if (blockDirectionPosition < top) return createVisiblePosition(caretMinOffset(), DOWNSTREAM); // coordinates are above if (blockDirectionPosition >= bottom) return createVisiblePosition(caretMaxOffset(), DOWNSTREAM); // coordinates are below if (node()) { if (lineDirectionPosition <= box->logicalLeft() + (box->logicalWidth() / 2)) return createVisiblePosition(0, DOWNSTREAM); return createVisiblePosition(1, DOWNSTREAM); } return RenderBox::positionForPoint(point); }
// FIXME: This doesn't behave correctly for floating or positioned images, but WebCore doesn't handle those well // during selection creation yet anyway. // FIXME: We can't tell whether or not we contain the start or end of the selected Range using only the offsets // of the start and end, we need to know the whole Position. void RenderImage::collectSelectionRects(Vector<SelectionRect>& rects, unsigned, unsigned) { RenderBlock* containingBlock = this->containingBlock(); IntRect imageRect; // FIXME: It doesn't make sense to package line bounds into SelectionRects. We should find // the right and left extent of the selection once for the entire selected Range, perhaps // using the Range's common ancestor. IntRect lineExtentRect; bool isFirstOnLine = false; bool isLastOnLine = false; InlineBox* inlineBox = inlineBoxWrapper(); if (!inlineBox) { // This is a block image. imageRect = IntRect(0, 0, width(), height()); isFirstOnLine = true; isLastOnLine = true; lineExtentRect = imageRect; if (containingBlock->isHorizontalWritingMode()) { lineExtentRect.setX(containingBlock->x()); lineExtentRect.setWidth(containingBlock->width()); } else { lineExtentRect.setY(containingBlock->y()); lineExtentRect.setHeight(containingBlock->height()); } } else { LayoutUnit selectionTop = !containingBlock->style().isFlippedBlocksWritingMode() ? inlineBox->root().selectionTop() - logicalTop() : logicalBottom() - inlineBox->root().selectionBottom(); imageRect = IntRect(0, selectionTop, logicalWidth(), inlineBox->root().selectionHeight()); isFirstOnLine = !inlineBox->previousOnLineExists(); isLastOnLine = !inlineBox->nextOnLineExists(); LogicalSelectionOffsetCaches cache(*containingBlock); LayoutUnit leftOffset = containingBlock->logicalLeftSelectionOffset(*containingBlock, inlineBox->logicalTop(), cache); LayoutUnit rightOffset = containingBlock->logicalRightSelectionOffset(*containingBlock, inlineBox->logicalTop(), cache); lineExtentRect = IntRect(leftOffset - logicalLeft(), imageRect.y(), rightOffset - leftOffset, imageRect.height()); if (!inlineBox->isHorizontal()) { imageRect = imageRect.transposedRect(); lineExtentRect = lineExtentRect.transposedRect(); } } bool isFixed = false; IntRect absoluteBounds = localToAbsoluteQuad(FloatRect(imageRect), UseTransforms, &isFixed).enclosingBoundingBox(); IntRect lineExtentBounds = localToAbsoluteQuad(FloatRect(lineExtentRect)).enclosingBoundingBox(); if (!containingBlock->isHorizontalWritingMode()) lineExtentBounds = lineExtentBounds.transposedRect(); // FIXME: We should consider either making SelectionRect a struct or better organize its optional fields into // an auxiliary struct to simplify its initialization. rects.append(SelectionRect(absoluteBounds, containingBlock->style().direction(), lineExtentBounds.x(), lineExtentBounds.maxX(), lineExtentBounds.maxY(), 0, false /* line break */, isFirstOnLine, isLastOnLine, false /* contains start */, false /* contains end */, containingBlock->style().isHorizontalWritingMode(), isFixed, false /* ruby text */, view().pageNumberForBlockProgressionOffset(absoluteBounds.x()))); }