Warning, file /frameworks/khtml/src/rendering/render_text.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * This file is part of the DOM implementation for KDE.
0003  *
0004  * Copyright (C) 1999-2003 Lars Knoll <knoll@kde.org>
0005  * Copyright (C) 2000-2003 Dirk Mueller <mueller@kde.org>
0006  * Copyright (C) 2003, 2006 Apple Computer, Inc.
0007  *
0008  * This library is free software; you can redistribute it and/or
0009  * modify it under the terms of the GNU Library General Public
0010  * License as published by the Free Software Foundation; either
0011  * version 2 of the License, or (at your option) any later version.
0012  *
0013  * This library is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * Library General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Library General Public License
0019  * along with this library; see the file COPYING.LIB.  If not, write to
0020  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0021  * Boston, MA 02110-1301, USA.
0022  *
0023  */
0024 #ifndef RENDERTEXT_H
0025 #define RENDERTEXT_H
0026 
0027 #include "dom/dom_string.h"
0028 #include "xml/dom_stringimpl.h"
0029 #include "xml/dom_textimpl.h"
0030 #include "rendering/render_object.h"
0031 #include "rendering/render_line.h"
0032 
0033 #include <QMutableVectorIterator>
0034 #include <assert.h>
0035 
0036 class QPainter;
0037 class QFontMetrics;
0038 
0039 // Define a constant for soft hyphen's unicode value.
0040 #define SOFT_HYPHEN 173
0041 
0042 const int cNoTruncation = -1;
0043 const int cFullTruncation = -2;
0044 
0045 namespace khtml
0046 {
0047 class RenderText;
0048 class RenderStyle;
0049 
0050 class InlineTextBox : public InlineRunBox
0051 {
0052 public:
0053     InlineTextBox(RenderObject *obj)
0054         : InlineRunBox(obj),
0055           // ### necessary as some codepaths (<br>) do *not* initialize these (LS)
0056           m_start(0), m_len(0), m_truncation(cNoTruncation), m_reversed(false), m_toAdd(0)
0057     {
0058     }
0059 
0060     uint start() const
0061     {
0062         return m_start;
0063     }
0064     uint end() const
0065     {
0066         return m_len ? m_start + m_len - 1 : m_start;
0067     }
0068     uint len() const
0069     {
0070         return m_len;
0071     }
0072 
0073     void detach(RenderArena *renderArena, bool noRemove = false) override;
0074 
0075     InlineTextBox *nextTextBox() const
0076     {
0077         return static_cast<InlineTextBox *>(nextLineBox());
0078     }
0079     InlineTextBox *prevTextBox() const
0080     {
0081         return static_cast<InlineTextBox *>(prevLineBox());
0082     }
0083 
0084     void clearTruncation() override
0085     {
0086         m_truncation = cNoTruncation;
0087     }
0088     int placeEllipsisBox(bool ltr, int blockEdge, int ellipsisWidth, bool &foundBox) override;
0089 
0090     // Overloaded new operator.  Derived classes must override operator new
0091     // in order to allocate out of the RenderArena.
0092     void *operator new(size_t sz, RenderArena *renderArena) throw();
0093 
0094     // Overridden to prevent the normal delete from being called.
0095     void operator delete(void *ptr, size_t sz);
0096 
0097 private:
0098     // The normal operator new is disallowed.
0099     void *operator new(size_t sz) throw();
0100 
0101 public:
0102     void setSpaceAdd(int add)
0103     {
0104         m_width -= m_toAdd;
0105         m_toAdd = add;
0106         m_width += m_toAdd;
0107     }
0108     int spaceAdd()
0109     {
0110         return m_toAdd;
0111     }
0112 
0113     bool isInlineTextBox() const override
0114     {
0115         return true;
0116     }
0117 
0118     void paint(RenderObject::PaintInfo &i, int tx, int ty) override;
0119     void paintDecoration(QPainter *pt, const Font *f, int _tx, int _ty, int decoration);
0120     void paintShadow(QPainter *pt, const Font *f, int _tx, int _ty, const ShadowData *shadow);
0121     void paintSelection(const Font *f, RenderText *text, QPainter *p, RenderStyle *style, int tx, int ty, int startPos, int endPos, int deco);
0122 
0123     void selectionStartEnd(int &sPos, int &ePos);
0124     RenderObject::SelectionState selectionState();
0125 
0126     // Return before, after (offset set to max), or inside the text, at @p offset
0127     FindSelectionResult checkSelectionPoint(int _x, int _y, int _tx, int _ty, int &offset);
0128 
0129     bool checkVerticalPoint(int _y, int _ty, int _h, int height)
0130     {
0131         if ((_ty + m_y > _y + _h) || (_ty + m_y + m_baseline + height < _y)) {
0132             return false;
0133         } return true;
0134     }
0135 
0136     /**
0137      * determines the offset into the DOMString of the character the given
0138      * coordinate points to.
0139      * The returned offset is never out of range.
0140      * @param _x given coordinate (relative to containing block)
0141      * @param ax returns exact coordinate the offset corresponds to
0142      *      (relative to containing block)
0143      * @return the offset (relative to the RenderText object, not to this run)
0144      */
0145     int offsetForPoint(int _x, int &ax) const;
0146 
0147     /**
0148      * calculates the with of the specified chunk in this text box.
0149      * @param pos zero-based position within the text box up to which
0150      *  the width is to be determined
0151      * @return the width in pixels
0152      */
0153     int widthFromStart(int pos) const;
0154 
0155     long caretMinOffset() const override;
0156     long caretMaxOffset() const override;
0157     unsigned long caretMaxRenderedOffset() const override;
0158 
0159     /** returns the associated render text
0160      */
0161     const RenderText *renderText() const;
0162     RenderText *renderText();
0163 
0164     void extractLine() override;
0165     void deleteLine(RenderArena *arena) override;
0166     void attachLine() override;
0167 
0168     int m_start;
0169     unsigned short m_len;
0170 
0171     int m_truncation; // Where to truncate when text overflow is applied.
0172     // We use special constants to denote no truncation (the whole run paints)
0173     // and full truncation (nothing paints at all).
0174 
0175     bool m_reversed : 1;
0176     unsigned m_toAdd : 14; // for justified text
0177 private:
0178     friend class RenderText;
0179 };
0180 
0181 class RenderText : public RenderObject
0182 {
0183     friend class InlineTextBox;
0184 
0185 public:
0186     RenderText(DOM::NodeImpl *node, DOM::DOMStringImpl *_str);
0187     virtual ~RenderText();
0188 
0189     virtual bool isTextFragment() const;
0190     virtual DOM::DOMStringImpl *originalString() const;
0191 
0192     const char *renderName() const override
0193     {
0194         return "RenderText";
0195     }
0196 
0197     void setStyle(RenderStyle *style) override;
0198 
0199     void detach() override;
0200 
0201     void deleteInlineBoxes(RenderArena *arena = nullptr) override;
0202     void dirtyInlineBoxes(bool fullLayout, bool) override;
0203     void removeInlineBox(InlineBox *_box) override;
0204 
0205     DOM::DOMString data() const
0206     {
0207         return str;
0208     }
0209     DOM::DOMStringImpl *string() const
0210     {
0211         return str;
0212     }
0213 
0214     InlineBox *createInlineBox(bool, bool) override;
0215 
0216     void layout() override
0217     {
0218         assert(false);
0219     }
0220 
0221     bool nodeAtPoint(NodeInfo &info, int x, int y, int tx, int ty, HitTestAction hitTestAction, bool inBox) override;
0222 
0223     RenderPosition positionForCoordinates(int _x, int _y) override;
0224 
0225     // Return before, after (offset set to max), or inside the text, at @p offset
0226     virtual FindSelectionResult checkSelectionPoint(int _x, int _y, int _tx, int _ty,
0227             DOM::NodeImpl *&node, int &offset,
0228             SelPointState &);
0229 
0230     unsigned int length() const override
0231     {
0232         if (str) {
0233             return str->l;
0234         } else {
0235             return 0;
0236         }
0237     }
0238     QChar *text() const
0239     {
0240         if (str) {
0241             return str->s;
0242         } else {
0243             return nullptr;
0244         }
0245     }
0246     unsigned int stringLength() const
0247     {
0248         return str->l;    // non virtual implementation of length()
0249     }
0250     void position(InlineBox *box, int from, int len, bool reverse) override;
0251 
0252     virtual unsigned int width(unsigned int from, unsigned int len, const Font *f) const;
0253     virtual unsigned int width(unsigned int from, unsigned int len, bool firstLine = false) const;
0254     short width() const override;
0255     int height() const override;
0256 
0257     // height of the contents (without paddings, margins and borders)
0258     short lineHeight(bool firstLine) const override;
0259     short baselinePosition(bool firstLine) const override;
0260 
0261     // overrides
0262     void calcMinMaxWidth() override;
0263     short minWidth() const override
0264     {
0265         return m_minWidth;
0266     }
0267     int maxWidth() const override
0268     {
0269         return m_maxWidth;
0270     }
0271 
0272     void trimmedMinMaxWidth(int &beginMinW, bool &beginWS,
0273                             int &endMinW, bool &endWS,
0274                             bool &hasBreakableChar, bool &hasBreak,
0275                             int &beginMaxW, int &endMaxW,
0276                             int &minW, int &maxW, bool &stripFrontSpaces);
0277 
0278     bool containsOnlyWhitespace(unsigned int from, unsigned int len) const;
0279 
0280     ushort startMin() const
0281     {
0282         return m_startMin;
0283     }
0284     ushort endMin() const
0285     {
0286         return m_endMin;
0287     }
0288 
0289     // returns the minimum x position of all runs relative to the parent.
0290     // defaults to 0.
0291     int minXPos() const;
0292 
0293     int inlineXPos() const override;
0294     int inlineYPos() const override;
0295 
0296     bool hasReturn() const
0297     {
0298         return m_hasReturn;
0299     }
0300 
0301     virtual const QFont &font();
0302     short verticalPositionHint(bool firstLine) const override;
0303 
0304     bool isFixedWidthFont() const;
0305 
0306     void setText(DOM::DOMStringImpl *text, bool force = false);
0307 
0308     SelectionState selectionState() const override
0309     {
0310         return KDE_CAST_BF_ENUM(SelectionState, m_selectionState);
0311     }
0312     void setSelectionState(SelectionState s) override
0313     {
0314         m_selectionState = s;
0315     }
0316     void caretPos(int offset, int flags, int &_x, int &_y, int &width, int &height) const override;
0317     bool absolutePosition(int &/*xPos*/, int &/*yPos*/, bool f = false) const override;
0318     bool posOfChar(int ch, int &x, int &y) const;
0319     bool isPointInsideSelection(int x, int y, const DOM::Selection &) const override;
0320 
0321     short marginLeft() const override
0322     {
0323         return style()->marginLeft().minWidth(0);
0324     }
0325     short marginRight() const override
0326     {
0327         return style()->marginRight().minWidth(0);
0328     }
0329 
0330     void repaint(Priority p = NormalPriority) override;
0331 
0332     InlineTextBox *firstTextBox() const
0333     {
0334         return m_firstTextBox;
0335     }
0336     InlineTextBox *lastTextBox() const
0337     {
0338         return m_lastTextBox;
0339     }
0340 
0341     QList< QRectF > getClientRects() override;
0342 
0343     bool hasBreakableChar() const
0344     {
0345         return m_hasBreakableChar;
0346     }
0347     bool isSimpleText() const
0348     {
0349         return m_isSimpleText;
0350     }
0351     const QFontMetrics &metrics(bool firstLine) const;
0352     const Font *htmlFont(bool firstLine) const;
0353 
0354     DOM::TextImpl *element() const
0355     {
0356         return static_cast<DOM::TextImpl *>(RenderObject::element());
0357     }
0358 
0359     InlineBox *inlineBox(long offset) override;
0360 
0361     void removeTextBox(InlineTextBox *box);
0362     void attachTextBox(InlineTextBox *box);
0363     void extractTextBox(InlineTextBox *box);
0364 
0365 #ifdef ENABLE_DUMP
0366     void dump(QTextStream &stream, const QString &ind) const override;
0367 #endif
0368 
0369     long caretMinOffset() const override;
0370     long caretMaxOffset() const override;
0371     unsigned long caretMaxRenderedOffset() const override;
0372 
0373     /** Find the text box that includes the character at @p offset
0374      * and return pos, which is the position of the char in the run.
0375      * @param offset zero-based offset into DOM string
0376      * @param pos returns relative position within text box
0377      * @param checkFirstLetter passing @p true will also regard :first-letter
0378      *      boxes, if available.
0379      * @return the text box, or 0 if no match has been found
0380      */
0381     const InlineTextBox *findInlineTextBox(int offset, int &pos,
0382                                            bool checkFirstLetter = false) const;
0383 
0384     // helper methods to convert Position from rendered text into DOM position
0385     // (takes into account space collapsing)
0386     unsigned convertToDOMPosition(unsigned position) const;
0387     unsigned convertToRenderedPosition(unsigned position) const;
0388 protected:
0389     virtual void setTextInternal(DOM::DOMStringImpl *text);
0390 
0391     // members
0392     InlineTextBox *m_firstTextBox;
0393     InlineTextBox *m_lastTextBox;
0394 
0395     DOM::DOMStringImpl *str; //
0396 
0397     short m_lineHeight;
0398     short m_minWidth;
0399     int   m_maxWidth;
0400     short m_beginMinWidth;
0401     short m_endMinWidth;
0402 
0403     KDE_BF_ENUM(SelectionState) m_selectionState : 3;
0404     bool m_hasReturn : 1;
0405     bool m_hasBreakableChar : 1;
0406     bool m_hasBreak : 1;
0407     bool m_hasBeginWS : 1;
0408     bool m_hasEndWS : 1;
0409     bool m_isSimpleText : 1;
0410 
0411     ushort m_startMin : 8;
0412     ushort m_endMin : 8;
0413 };
0414 
0415 inline const RenderText *InlineTextBox::renderText() const
0416 {
0417     return static_cast<RenderText *>(object());
0418 }
0419 
0420 inline RenderText *InlineTextBox::renderText()
0421 {
0422     return static_cast<RenderText *>(object());
0423 }
0424 
0425 // Used to represent a text substring of an element, e.g., for text runs that are split because of
0426 // first letter and that must therefore have different styles (and positions in the render tree).
0427 // We cache offsets so that text transformations can be applied in such a way that we can recover
0428 // the original unaltered string from our corresponding DOM node.
0429 class RenderTextFragment : public RenderText
0430 {
0431 public:
0432     RenderTextFragment(DOM::NodeImpl *_node, DOM::DOMStringImpl *_str,
0433                        int startOffset, int endOffset);
0434     RenderTextFragment(DOM::NodeImpl *_node, DOM::DOMStringImpl *_str);
0435     ~RenderTextFragment();
0436 
0437     bool isTextFragment() const override;
0438     const char *renderName() const override
0439     {
0440         return "RenderTextFragment";
0441     }
0442 
0443     uint start() const
0444     {
0445         return m_start;
0446     }
0447     uint end() const
0448     {
0449         return m_end;
0450     }
0451 
0452     DOM::DOMStringImpl *contentString() const
0453     {
0454         return m_generatedContentStr;
0455     }
0456     DOM::DOMStringImpl *originalString() const override;
0457 
0458     RenderObject *firstLetter() const
0459     {
0460         return m_firstLetter;
0461     }
0462     void setFirstLetter(RenderObject *firstLetter)
0463     {
0464         m_firstLetter = firstLetter;
0465     }
0466 
0467     // overrides
0468     void detach() override;
0469 private:
0470     void setTextInternal(DOM::DOMStringImpl *text) override;
0471 
0472     uint m_start;
0473     uint m_end;
0474     DOM::DOMStringImpl *m_generatedContentStr;
0475     RenderObject *m_firstLetter;
0476 };
0477 } // end namespace
0478 #endif