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 "InlineBox.h" 27 #include "RenderText.h" // so textRenderer() can be inline 28 #include "TextRun.h" 29 30 namespace WebCore { 31 32 struct CompositionUnderline; 33 struct DocumentMarker; 34 35 const unsigned short cNoTruncation = USHRT_MAX; 36 const unsigned short cFullTruncation = USHRT_MAX - 1; 37 38 // Helper functions shared by InlineTextBox / SVGRootInlineBox 39 void updateGraphicsContext(GraphicsContext*, const Color& fillColor, const Color& strokeColor, float strokeThickness, ColorSpace); 40 Color correctedTextColor(Color textColor, Color backgroundColor); 41 42 class InlineTextBox : public InlineBox { 43 public: 44 InlineTextBox(RenderObject* obj) 45 : InlineBox(obj) 46 , m_prevTextBox(0) 47 , m_nextTextBox(0) 48 , m_start(0) 49 , m_len(0) 50 , m_truncation(cNoTruncation) 51 { 52 } 53 54 virtual void destroy(RenderArena*); 55 56 InlineTextBox* prevTextBox() const { return m_prevTextBox; } 57 InlineTextBox* nextTextBox() const { return m_nextTextBox; } 58 void setNextTextBox(InlineTextBox* n) { m_nextTextBox = n; } 59 void setPreviousTextBox(InlineTextBox* p) { m_prevTextBox = p; } 60 61 unsigned start() const { return m_start; } 62 unsigned end() const { return m_len ? m_start + m_len - 1 : m_start; } 63 unsigned len() const { return m_len; } 64 65 void setStart(unsigned start) { m_start = start; } 66 void setLen(unsigned len) { m_len = len; } 67 68 void offsetRun(int d) { m_start += d; } 69 70 unsigned short truncation() { return m_truncation; } 71 72 bool hasHyphen() const { return m_hasEllipsisBoxOrHyphen; } 73 void setHasHyphen(bool hasHyphen) { m_hasEllipsisBoxOrHyphen = hasHyphen; } 74 75 bool canHaveLeadingExpansion() const { return m_hasSelectedChildrenOrCanHaveLeadingExpansion; } 76 void setCanHaveLeadingExpansion(bool canHaveLeadingExpansion) { m_hasSelectedChildrenOrCanHaveLeadingExpansion = canHaveLeadingExpansion; } 77 78 static inline bool compareByStart(const InlineTextBox* first, const InlineTextBox* second) { return first->start() < second->start(); } 79 80 virtual int baselinePosition(FontBaseline) const; 81 virtual int lineHeight() const; 82 83 bool getEmphasisMarkPosition(RenderStyle*, TextEmphasisPosition&) const; 84 85 IntRect logicalOverflowRect() const; 86 void setLogicalOverflowRect(const IntRect&); 87 int logicalTopVisualOverflow() const { return logicalOverflowRect().y(); } 88 int logicalBottomVisualOverflow() const { return logicalOverflowRect().maxY(); } 89 int logicalLeftVisualOverflow() const { return logicalOverflowRect().x(); } 90 int logicalRightVisualOverflow() const { return logicalOverflowRect().maxX(); } 91 92 private: 93 int selectionTop(); 94 int selectionBottom(); 95 int selectionHeight(); 96 97 public: 98 virtual IntRect calculateBoundaries() const { return IntRect(x(), y(), width(), height()); } 99 100 virtual IntRect selectionRect(int absx, int absy, int startPos, int endPos); 101 bool isSelected(int startPos, int endPos) const; 102 void selectionStartEnd(int& sPos, int& ePos); 103 104 protected: 105 virtual void paint(PaintInfo&, int tx, int ty, int lineTop, int lineBottom); 106 virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int x, int y, int tx, int ty, int lineTop, int lineBottom); 107 108 public: 109 RenderText* textRenderer() const; 110 111 private: 112 virtual void deleteLine(RenderArena*); 113 virtual void extractLine(); 114 virtual void attachLine(); 115 116 public: 117 virtual RenderObject::SelectionState selectionState(); 118 119 private: 120 virtual void clearTruncation() { m_truncation = cNoTruncation; } 121 virtual float placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, bool& foundBox); 122 123 public: 124 virtual bool isLineBreak() const; 125 126 void setExpansion(float expansion) { m_logicalWidth -= m_expansion; m_expansion = expansion; m_logicalWidth += m_expansion; } 127 128 private: 129 virtual bool isInlineTextBox() const { return true; } 130 131 public: 132 virtual int caretMinOffset() const; 133 virtual int caretMaxOffset() const; 134 135 private: 136 virtual unsigned caretMaxRenderedOffset() const; 137 138 float textPos() const; // returns the x position relative to the left start of the text line. 139 140 public: 141 virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const; 142 virtual float positionForOffset(int offset) const; 143 144 bool containsCaretOffset(int offset) const; // false for offset after line break 145 146 // Needs to be public, so the static paintTextWithShadows() function can use it. 147 static FloatSize applyShadowToGraphicsContext(GraphicsContext*, const ShadowData*, const FloatRect& textRect, bool stroked, bool opaque, bool horizontal); 148 149 private: 150 InlineTextBox* m_prevTextBox; // The previous box that also uses our RenderObject 151 InlineTextBox* m_nextTextBox; // The next box that also uses our RenderObject 152 153 int m_start; 154 unsigned short m_len; 155 156 unsigned short m_truncation; // Where to truncate when text overflow is applied. We use special constants to 157 // denote no truncation (the whole run paints) and full truncation (nothing paints at all). 158 159 protected: 160 void paintCompositionBackground(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, int startPos, int endPos); 161 void paintDocumentMarkers(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, bool background); 162 void paintCompositionUnderline(GraphicsContext*, const FloatPoint& boxOrigin, const CompositionUnderline&); 163 #if PLATFORM(MAC) 164 void paintCustomHighlight(int tx, int ty, const AtomicString& type); 165 #endif 166 167 private: 168 void paintDecoration(GraphicsContext*, const FloatPoint& boxOrigin, int decoration, const ShadowData*); 169 void paintSelection(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&); 170 void paintSpellingOrGrammarMarker(GraphicsContext*, const FloatPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&, bool grammar); 171 void paintTextMatchMarker(GraphicsContext*, const FloatPoint& boxOrigin, const DocumentMarker&, RenderStyle*, const Font&); 172 void computeRectForReplacementMarker(const DocumentMarker&, RenderStyle*, const Font&); 173 174 TextRun::ExpansionBehavior expansionBehavior() const 175 { 176 return (canHaveLeadingExpansion() ? TextRun::AllowLeadingExpansion : TextRun::ForbidLeadingExpansion) 177 | (m_expansion && nextLeafChild() ? TextRun::AllowTrailingExpansion : TextRun::ForbidTrailingExpansion); 178 } 179 }; 180 181 inline RenderText* InlineTextBox::textRenderer() const 182 { 183 return toRenderText(renderer()); 184 } 185 186 } // namespace WebCore 187 188 #endif // InlineTextBox_h 189