1 /* 2 * (C) 1999 Lars Knoll (knoll (at) kde.org) 3 * (C) 2000 Dirk Mueller (mueller (at) kde.org) 4 * Copyright (C) 2004, 2005, 2006, 2009, 2010, 2011 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 #ifndef InlineTextBox_h 24 #define InlineTextBox_h 25 26 #include "core/platform/graphics/TextRun.h" 27 #include "core/rendering/InlineBox.h" 28 #include "core/rendering/RenderText.h" // so textRenderer() can be inline 29 #include "wtf/Forward.h" 30 31 namespace WebCore { 32 33 struct CompositionUnderline; 34 class DocumentMarker; 35 36 const unsigned short cNoTruncation = USHRT_MAX; 37 const unsigned short cFullTruncation = USHRT_MAX - 1; 38 39 // Helper functions shared by InlineTextBox / SVGRootInlineBox 40 void updateGraphicsContext(GraphicsContext*, const Color& fillColor, const Color& strokeColor, float strokeThickness, ColorSpace); 41 Color correctedTextColor(Color textColor, Color backgroundColor); 42 43 class InlineTextBox : public InlineBox { 44 public: 45 InlineTextBox(RenderObject* obj) 46 : InlineBox(obj) 47 , m_prevTextBox(0) 48 , m_nextTextBox(0) 49 , m_start(0) 50 , m_len(0) 51 , m_truncation(cNoTruncation) 52 { 53 } 54 55 virtual void destroy() OVERRIDE FINAL; 56 57 InlineTextBox* prevTextBox() const { return m_prevTextBox; } 58 InlineTextBox* nextTextBox() const { return m_nextTextBox; } 59 void setNextTextBox(InlineTextBox* n) { m_nextTextBox = n; } 60 void setPreviousTextBox(InlineTextBox* p) { m_prevTextBox = p; } 61 62 // FIXME: These accessors should ASSERT(!isDirty()). See https://bugs.webkit.org/show_bug.cgi?id=97264 63 unsigned start() const { return m_start; } 64 unsigned end() const { return m_len ? m_start + m_len - 1 : m_start; } 65 unsigned len() const { return m_len; } 66 67 void setStart(unsigned start) { m_start = start; } 68 void setLen(unsigned len) { m_len = len; } 69 70 void offsetRun(int d) { ASSERT(!isDirty()); m_start += d; } 71 72 unsigned short truncation() { return m_truncation; } 73 74 virtual void markDirty(bool dirty = true) OVERRIDE FINAL; 75 76 using InlineBox::hasHyphen; 77 using InlineBox::setHasHyphen; 78 using InlineBox::canHaveLeadingExpansion; 79 using InlineBox::setCanHaveLeadingExpansion; 80 81 static inline bool compareByStart(const InlineTextBox* first, const InlineTextBox* second) { return first->start() < second->start(); } 82 83 virtual int baselinePosition(FontBaseline) const OVERRIDE FINAL; 84 virtual LayoutUnit lineHeight() const OVERRIDE FINAL; 85 86 bool getEmphasisMarkPosition(RenderStyle*, TextEmphasisPosition&) const; 87 88 LayoutRect logicalOverflowRect() const; 89 void setLogicalOverflowRect(const LayoutRect&); 90 LayoutUnit logicalTopVisualOverflow() const { return logicalOverflowRect().y(); } 91 LayoutUnit logicalBottomVisualOverflow() const { return logicalOverflowRect().maxY(); } 92 LayoutUnit logicalLeftVisualOverflow() const { return logicalOverflowRect().x(); } 93 LayoutUnit logicalRightVisualOverflow() const { return logicalOverflowRect().maxX(); } 94 95 #ifndef NDEBUG 96 virtual void showBox(int = 0) const; 97 virtual const char* boxName() const; 98 #endif 99 100 private: 101 LayoutUnit selectionTop(); 102 LayoutUnit selectionBottom(); 103 LayoutUnit selectionHeight(); 104 105 // charactersWithHyphen, if provided, must not be destroyed before the TextRun. 106 TextRun constructTextRun(RenderStyle*, const Font&, StringBuilder* charactersWithHyphen = 0) const; 107 TextRun constructTextRun(RenderStyle*, const Font&, StringView, int maximumLength, StringBuilder* charactersWithHyphen = 0) const; 108 109 public: 110 virtual FloatRect calculateBoundaries() const { return FloatRect(x(), y(), width(), height()); } 111 112 virtual LayoutRect localSelectionRect(int startPos, int endPos); 113 bool isSelected(int startPos, int endPos) const; 114 void selectionStartEnd(int& sPos, int& ePos); 115 116 protected: 117 virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom); 118 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE; 119 120 public: 121 RenderText* textRenderer() const; 122 123 private: 124 virtual void deleteLine() OVERRIDE FINAL; 125 virtual void extractLine() OVERRIDE FINAL; 126 virtual void attachLine() OVERRIDE FINAL; 127 128 public: 129 virtual RenderObject::SelectionState selectionState() OVERRIDE FINAL; 130 131 private: 132 virtual void clearTruncation() OVERRIDE FINAL { m_truncation = cNoTruncation; } 133 virtual float placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox) OVERRIDE FINAL; 134 135 public: 136 virtual bool isLineBreak() const OVERRIDE FINAL; 137 138 void setExpansion(int newExpansion) 139 { 140 m_logicalWidth -= expansion(); 141 InlineBox::setExpansion(newExpansion); 142 m_logicalWidth += newExpansion; 143 } 144 145 private: 146 virtual bool isInlineTextBox() const OVERRIDE FINAL { return true; } 147 148 public: 149 virtual int caretMinOffset() const OVERRIDE FINAL; 150 virtual int caretMaxOffset() const OVERRIDE FINAL; 151 152 private: 153 float textPos() const; // returns the x position relative to the left start of the text line. 154 155 public: 156 virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const; 157 virtual float positionForOffset(int offset) const; 158 159 bool containsCaretOffset(int offset) const; // false for offset after line break 160 161 private: 162 InlineTextBox* m_prevTextBox; // The previous box that also uses our RenderObject 163 InlineTextBox* m_nextTextBox; // The next box that also uses our RenderObject 164 165 int m_start; 166 unsigned short m_len; 167 168 unsigned short m_truncation; // Where to truncate when text overflow is applied. We use special constants to 169 // denote no truncation (the whole run paints) and full truncation (nothing paints at all). 170 171 protected: 172 void paintCompositionBackground(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, int startPos, int endPos); 173 void paintDocumentMarkers(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, bool background); 174 void paintCompositionUnderline(GraphicsContext*, const FloatPoint& boxOrigin, const CompositionUnderline&); 175 176 private: 177 void paintDecoration(GraphicsContext*, const FloatPoint& boxOrigin, TextDecoration, TextDecorationStyle, const ShadowData*); 178 void paintSelection(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, Color textColor); 179 void paintDocumentMarker(GraphicsContext*, const FloatPoint& boxOrigin, DocumentMarker*, RenderStyle*, const Font&, bool grammar); 180 void paintTextMatchMarker(GraphicsContext*, const FloatPoint& boxOrigin, DocumentMarker*, RenderStyle*, const Font&); 181 182 TextRun::ExpansionBehavior expansionBehavior() const 183 { 184 return (canHaveLeadingExpansion() ? TextRun::AllowLeadingExpansion : TextRun::ForbidLeadingExpansion) 185 | (expansion() && nextLeafChild() ? TextRun::AllowTrailingExpansion : TextRun::ForbidTrailingExpansion); 186 } 187 }; 188 189 inline InlineTextBox* toInlineTextBox(InlineBox* inlineBox) 190 { 191 ASSERT_WITH_SECURITY_IMPLICATION(!inlineBox || inlineBox->isInlineTextBox()); 192 return static_cast<InlineTextBox*>(inlineBox); 193 } 194 195 inline const InlineTextBox* toInlineTextBox(const InlineBox* inlineBox) 196 { 197 ASSERT_WITH_SECURITY_IMPLICATION(!inlineBox || inlineBox->isInlineTextBox()); 198 return static_cast<const InlineTextBox*>(inlineBox); 199 } 200 201 // This will catch anyone doing an unnecessary cast. 202 void toInlineTextBox(const InlineTextBox*); 203 204 inline RenderText* InlineTextBox::textRenderer() const 205 { 206 return toRenderText(renderer()); 207 } 208 209 void alignSelectionRectToDevicePixels(FloatRect&); 210 211 } // namespace WebCore 212 213 #endif // InlineTextBox_h 214