| 1 | /* |
| 2 | * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 | * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 | * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
| 5 | * |
| 6 | * This library is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU Library General Public |
| 8 | * License as published by the Free Software Foundation; either |
| 9 | * version 2 of the License, or (at your option) any later version. |
| 10 | * |
| 11 | * This library is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | * Library General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU Library General Public License |
| 17 | * along with this library; see the file COPYING.LIB. If not, write to |
| 18 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 19 | * Boston, MA 02110-1301, USA. |
| 20 | * |
| 21 | */ |
| 22 | |
| 23 | #pragma once |
| 24 | |
| 25 | #include "InlineFlowBox.h" |
| 26 | #include "RenderBoxModelObject.h" |
| 27 | #include "RenderLineBoxList.h" |
| 28 | |
| 29 | namespace WebCore { |
| 30 | |
| 31 | class Position; |
| 32 | class RenderFragmentContainer; |
| 33 | |
| 34 | class RenderInline : public RenderBoxModelObject { |
| 35 | WTF_MAKE_ISO_ALLOCATED(RenderInline); |
| 36 | public: |
| 37 | RenderInline(Element&, RenderStyle&&); |
| 38 | RenderInline(Document&, RenderStyle&&); |
| 39 | |
| 40 | LayoutUnit marginLeft() const final; |
| 41 | LayoutUnit marginRight() const final; |
| 42 | LayoutUnit marginTop() const final; |
| 43 | LayoutUnit marginBottom() const final; |
| 44 | LayoutUnit marginBefore(const RenderStyle* otherStyle = 0) const final; |
| 45 | LayoutUnit marginAfter(const RenderStyle* otherStyle = 0) const final; |
| 46 | LayoutUnit marginStart(const RenderStyle* otherStyle = 0) const final; |
| 47 | LayoutUnit marginEnd(const RenderStyle* otherStyle = 0) const final; |
| 48 | |
| 49 | void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const final; |
| 50 | void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override; |
| 51 | |
| 52 | LayoutSize offsetFromContainer(RenderElement&, const LayoutPoint&, bool* offsetDependsOnPoint = nullptr) const final; |
| 53 | |
| 54 | LayoutRect borderBoundingBox() const final |
| 55 | { |
| 56 | return LayoutRect(LayoutPoint(), linesBoundingBox().size()); |
| 57 | } |
| 58 | |
| 59 | WEBCORE_EXPORT IntRect linesBoundingBox() const; |
| 60 | LayoutRect linesVisualOverflowBoundingBox() const; |
| 61 | LayoutRect linesVisualOverflowBoundingBoxInFragment(const RenderFragmentContainer*) const; |
| 62 | |
| 63 | InlineFlowBox* createAndAppendInlineFlowBox(); |
| 64 | |
| 65 | void dirtyLineBoxes(bool fullLayout); |
| 66 | void deleteLines(); |
| 67 | |
| 68 | RenderLineBoxList& lineBoxes() { return m_lineBoxes; } |
| 69 | const RenderLineBoxList& lineBoxes() const { return m_lineBoxes; } |
| 70 | |
| 71 | InlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); } |
| 72 | InlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); } |
| 73 | InlineBox* firstLineBoxIncludingCulling() const { return alwaysCreateLineBoxes() ? firstLineBox() : culledInlineFirstLineBox(); } |
| 74 | InlineBox* lastLineBoxIncludingCulling() const { return alwaysCreateLineBoxes() ? lastLineBox() : culledInlineLastLineBox(); } |
| 75 | |
| 76 | #if PLATFORM(IOS_FAMILY) |
| 77 | void absoluteQuadsForSelection(Vector<FloatQuad>& quads) const override; |
| 78 | #endif |
| 79 | |
| 80 | void updateDragState(bool dragOn) final; |
| 81 | |
| 82 | LayoutSize offsetForInFlowPositionedInline(const RenderBox* child) const; |
| 83 | |
| 84 | void addFocusRingRects(Vector<LayoutRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) final; |
| 85 | void paintOutline(PaintInfo&, const LayoutPoint&); |
| 86 | |
| 87 | bool alwaysCreateLineBoxes() const { return renderInlineAlwaysCreatesLineBoxes(); } |
| 88 | void setAlwaysCreateLineBoxes() { setRenderInlineAlwaysCreatesLineBoxes(true); } |
| 89 | void updateAlwaysCreateLineBoxes(bool fullLayout); |
| 90 | |
| 91 | LayoutRect localCaretRect(InlineBox*, unsigned, LayoutUnit* ) final; |
| 92 | |
| 93 | bool hitTestCulledInline(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset); |
| 94 | |
| 95 | protected: |
| 96 | void willBeDestroyed() override; |
| 97 | |
| 98 | void styleWillChange(StyleDifference, const RenderStyle& newStyle) override; |
| 99 | void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override; |
| 100 | |
| 101 | void updateFromStyle() override; |
| 102 | |
| 103 | private: |
| 104 | const char* renderName() const override; |
| 105 | |
| 106 | bool canHaveChildren() const final { return true; } |
| 107 | |
| 108 | LayoutRect culledInlineVisualOverflowBoundingBox() const; |
| 109 | InlineBox* culledInlineFirstLineBox() const; |
| 110 | InlineBox* culledInlineLastLineBox() const; |
| 111 | |
| 112 | template<typename GeneratorContext> |
| 113 | void generateLineBoxRects(GeneratorContext& yield) const; |
| 114 | template<typename GeneratorContext> |
| 115 | void generateCulledLineBoxRects(GeneratorContext& yield, const RenderInline* container) const; |
| 116 | |
| 117 | void layout() final { ASSERT_NOT_REACHED(); } // Do nothing for layout() |
| 118 | |
| 119 | void paint(PaintInfo&, const LayoutPoint&) final; |
| 120 | |
| 121 | bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) final; |
| 122 | |
| 123 | bool requiresLayer() const override { return isInFlowPositioned() || createsGroup() || hasClipPath() || willChangeCreatesStackingContext() || hasRunningAcceleratedAnimations(); } |
| 124 | |
| 125 | LayoutUnit offsetLeft() const final; |
| 126 | LayoutUnit offsetTop() const final; |
| 127 | LayoutUnit offsetWidth() const final { return linesBoundingBox().width(); } |
| 128 | LayoutUnit offsetHeight() const final { return linesBoundingBox().height(); } |
| 129 | |
| 130 | LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override; |
| 131 | LayoutRect rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const final; |
| 132 | |
| 133 | Optional<LayoutRect> computeVisibleRectInContainer(const LayoutRect&, const RenderLayerModelObject* container, VisibleRectContext) const final; |
| 134 | LayoutRect computeVisibleRectUsingPaintOffset(const LayoutRect&) const; |
| 135 | |
| 136 | void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override; |
| 137 | const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override; |
| 138 | |
| 139 | VisiblePosition positionForPoint(const LayoutPoint&, const RenderFragmentContainer*) final; |
| 140 | |
| 141 | LayoutRect frameRectForStickyPositioning() const final { return linesBoundingBox(); } |
| 142 | |
| 143 | virtual std::unique_ptr<InlineFlowBox> createInlineFlowBox(); // Subclassed by RenderSVGInline |
| 144 | |
| 145 | void dirtyLinesFromChangedChild(RenderObject& child) final { m_lineBoxes.dirtyLinesFromChangedChild(*this, child); } |
| 146 | |
| 147 | LayoutUnit lineHeight(bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const final; |
| 148 | int baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const final; |
| 149 | |
| 150 | void updateHitTestResult(HitTestResult&, const LayoutPoint&) final; |
| 151 | |
| 152 | void imageChanged(WrappedImagePtr, const IntRect* = 0) final; |
| 153 | |
| 154 | #if ENABLE(DASHBOARD_SUPPORT) |
| 155 | void addAnnotatedRegions(Vector<AnnotatedRegionValue>&) final; |
| 156 | #endif |
| 157 | |
| 158 | void paintOutlineForLine(GraphicsContext&, const LayoutPoint&, const LayoutRect& prevLine, const LayoutRect& thisLine, const LayoutRect& nextLine, const Color&); |
| 159 | |
| 160 | bool willChangeCreatesStackingContext() const |
| 161 | { |
| 162 | return style().willChange() && style().willChange()->canCreateStackingContext(); |
| 163 | } |
| 164 | |
| 165 | RenderLineBoxList m_lineBoxes; // All of the line boxes created for this inline flow. For example, <i>Hello<br>world.</i> will have two <i> line boxes. |
| 166 | }; |
| 167 | |
| 168 | } // namespace WebCore |
| 169 | |
| 170 | SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderInline, isRenderInline()) |
| 171 | |