aboutsummaryrefslogtreecommitdiff
path: root/dw/textblock.hh
diff options
context:
space:
mode:
Diffstat (limited to 'dw/textblock.hh')
-rw-r--r--dw/textblock.hh155
1 files changed, 83 insertions, 72 deletions
diff --git a/dw/textblock.hh b/dw/textblock.hh
index 80e16393..15f81eb1 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -6,8 +6,6 @@
namespace dw {
-using namespace lout;
-
/**
* \brief A Widget for rendering text blocks, i.e. paragraphs or sequences
* of paragraphs.
@@ -16,118 +14,118 @@ using namespace lout;
* floats have been implementet. Will be updated and extended soon.
*
* <h3>Signals</h3>
- *
+ *
* dw::Textblock uses the signals defined in
- * dw::core::Widget::LinkReceiver, related to links. The coordinates are
+ * dw::core::Layout::LinkReceiver, related to links. The coordinates are
* always -1.
- *
- *
+ *
+ *
* <h3>Collapsing Spaces</h3>
- *
+ *
* The idea behind this is that every paragraph has a specific vertical
* space around and that they are combined to one space, according to
* rules stated below. A paragraph consists either of the lines between
* two paragraph breaks within a dw::Textblock, or of a dw::Textblock
* within a dw::Textblock, in a single line; the latter is used for
* indented boxes and list items.
- *
+ *
* The rules:
- *
+ *
* <ol>
* <li> If a paragraph is following by another, the space between them is the
* maximum of both box spaces:
- *
+ *
* \image html dw-textblock-collapsing-spaces-1-1.png
- *
+ *
* are combined like this:
- *
+ *
* \image html dw-textblock-collapsing-spaces-1-2.png
- *
+ *
* <li> a) If one paragraph is the first paragraph within another, the upper
* space of these paragraphs collapse. b) The analogue is the case for the
* last box:
- *
+ *
* \image html dw-textblock-collapsing-spaces-2-1.png
- *
+ *
* If B and C are put into A, the result is:
- *
+ *
* \image html dw-textblock-collapsing-spaces-2-2.png
* </ol>
- *
+ *
* For achieving this, there are some features of dw::Textblock:
- *
+ *
* <ul>
* <li> Consequent breaks are automatically combined, according to
* rule 1. See the code of dw::Textblock::addParBreak for details.
- *
+ *
* <li> If a break is added as the first word of the dw::Textblock within
* another dw::Textblock, collapsing according to rule 2a is done
* automatically. See the code of dw::Textblock::addParBreak.
- *
+ *
* <li> To collapse spaces according to rule 2b,
* dw::Textblock::addParBreak::handOverBreak must be called for
* the \em inner widget. The HTML parser does this in
* Html_eventually_pop_dw.
* </ul>
- *
- *
+ *
+ *
* <h3>Collapsing Margins</h3>
- *
+ *
* Collapsing margins, as defined in the CSS2 specification, are,
* supported in addition to collapsing spaces. Also, spaces and margins
* collapse themselves. I.e., the space between two paragraphs is the
* maximum of the space calculated as described in "Collapsing Spaces"
* and the space calculated according to the rules for collapsing margins.
- *
+ *
* (This is an intermediate hybrid state, collapsing spaces are used in
* the current version of dillo, while I implemented collapsing margins
* for the CSS prototype and integrated it already into the main trunk. For
* a pure CSS-based dillo, collapsing spaces will not be needed anymore, and
* may be removed for simplicity.)
- *
- *
+ *
+ *
* <h3>Some Internals</h3>
- *
- * There are two lists, dw::Textblock::words and
- * dw::Textblock::lines. The word list is quite static; only new words
- * may be added. A word is either text, a widget, a break or an
- * anchor. Anchors are stored in the text, because it may be necessary to
- * correct the scroller positions at rewrapping.
- *
- * Lines refer to the word list (first and last), they are completely
+ *
+ * There are 3 lists, dw::Textblock::words, dw::Textblock::lines, and
+ * dw::Textblock::anchors. The word list is quite static; only new words
+ * may be added. A word is either text, a widget, or a break.
+ *
+ * Lines refer to the word list (first and last). They are completely
* redundant, i.e., they can be rebuilt from the words. Lines can be
* rewrapped either completely or partially (see "Incremental Resizing"
* below). For the latter purpose, several values are accumulated in the
* lines. See dw::Textblock::Line for details.
- *
- *
+ *
+ * Anchors associate the anchor name with the index of the next word at
+ * the point of the anchor.
+ *
* <h4>Incremental Resizing</h4>
- *
+ *
* dw::Textblock makes use of incremental resizing as described in \ref
* dw-widget-sizes. The parentRef is, for children of a dw::Textblock, simply
* the number of the line.
- *
+ *
* Generally, there are three cases which may change the size of the
* widget:
- *
+ *
* <ul>
* <li> The available size of the widget has changed, e.g., because the
* user has changed the size of the browser window. In this case,
* it is necessary to rewrap all the lines.
- *
+ *
* <li> A child widget has changed its size. In this case, only a rewrap
* down from the line where this widget is located is necessary.
- *
+ *
* (This case is very important for tables. Tables are quite at the
* bottom, so that a partial rewrap is relevant. Otherwise, tables
* change their size quite often, so that this is necessary for a
* fast, non-blocking rendering)
- *
+ *
* <li> A word (or widget, break etc.) is added to the text block. This
* makes it possible to reuse the old size by simply adjusting the
* current width and height, so no rewrapping is necessary.
* </ul>
- *
+ *
* The state of the size calculation is stored in wrapRef within
* dw::Textblock, which has the value -1 if no rewrapping of lines
* necessary, or otherwise the line from which a rewrap is necessary.
@@ -141,7 +139,7 @@ private:
class FloatSide
{
protected:
- class Float: public object::Object
+ class Float: public lout::object::Object
{
public:
Textblock *floatGenerator;
@@ -150,8 +148,8 @@ private:
};
Textblock *floatContainer;
- container::typed::Vector<Float> *floats;
- container::typed::HashTable<object::TypedPointer<dw::core::Widget>, Float> *floatsByWidget;
+ lout::container::typed::Vector<Float> *floats;
+ lout::container::typed::HashTable<lout::object::TypedPointer<dw::core::Widget>, Float> *floatsByWidget;
Float *findFloat(int y);
@@ -198,13 +196,13 @@ private:
protected:
struct Line
{
- int firstWord; /* first-word's position in DwPageWord [0 based] */
- int lastWord; /* last-word's position in DwPageWord [1 based] */
+ int firstWord; /* first word's index in word vector */
+ int lastWord; /* last word's index in word vector */
/* "top" is always relative to the top of the first line, i.e.
* page->lines[0].top is always 0. */
- int top, ascent, descent, breakSpace;
- int leftOffset; /* nonzero for centered and rightly-aligned text */
+ int top, boxAscent, boxDescent, contentAscent, contentDescent,
+ breakSpace, leftOffset;
int boxLeft, boxRight;
/* This is similar to descent, but includes the bottom margins of the
@@ -229,9 +227,9 @@ protected:
/* TODO: perhaps add a xLeft? */
core::Requisition size;
/* Space after the word, only if it's not a break: */
- unsigned short origSpace; /* from font, set by addSpace */
- unsigned short effSpace; /* effective space, set by wordWrap,
- * used for drawing etc. */
+ short origSpace; /* from font, set by addSpace */
+ short effSpace; /* effective space, set by wordWrap,
+ * used for drawing etc. */
core::Content content;
core::style::Style *style;
@@ -239,6 +237,12 @@ protected:
later set by a_Dw_page_add_space */
};
+ struct Anchor
+ {
+ char *name;
+ int wordIndex;
+ };
+
class TextblockIterator: public core::Iterator
{
private:
@@ -250,8 +254,8 @@ protected:
TextblockIterator (Textblock *textblock, core::Content::Type mask,
int index);
- object::Object *clone();
- int compareTo(misc::Comparable *other);
+ lout::object::Object *clone();
+ int compareTo(lout::misc::Comparable *other);
bool next ();
bool prev ();
@@ -263,7 +267,7 @@ protected:
friend class TextblockIterator;
/* These fields provide some ad-hoc-functionality, used by sub-classes. */
- bool listItem; /* If true, the first word of the page is treated
+ bool hasListitemValue; /* If true, the first word of the page is treated
specially (search in source). */
int innerPadding; /* This is an additional padding on the left side
(used by ListItem). */
@@ -304,17 +308,13 @@ protected:
int lastLineParMax;
int wrapRef; /* [0 based] */
- misc::SimpleVector <Line> *lines;
- misc::SimpleVector <Word> *words;
+ lout::misc::SimpleVector <Line> *lines;
+ lout::misc::SimpleVector <Word> *words;
+ lout::misc::SimpleVector <Anchor> *anchors;
struct {int index, nChar;}
hlStart[core::HIGHLIGHT_NUM_LAYERS], hlEnd[core::HIGHLIGHT_NUM_LAYERS];
- /* The word index of the link under a button press, and the char
- * position */
- int linkPressedIndex;
- int link_pressedCharPos;
-
int hoverLink; /* The link under the button. */
core::style::Tooltip *hoverTooltip; /* The tooltip under the button. No ref
* hold. */
@@ -324,17 +324,24 @@ protected:
void getWordExtremes (Word *word, core::Extremes *extremes);
void markChange (int ref);
void justifyLine (Line *line, int availWidth);
- void addLine (int wordInd, bool newPar);
+ Line *addLine (int wordInd, bool newPar);
void calcWidgetSize (core::Widget *widget, core::Requisition *size);
void rewrap ();
+ void decorateText(core::View *view, core::style::Style *style,
+ core::style::Color::Shading shading,
+ int x, int yBase, int width);
+ void drawText(int wordIndex, core::View *view, core::Rectangle *area,
+ int xWidget, int yWidgetBase);
+ void drawSpace(int wordIndex, core::View *view, core::Rectangle *area,
+ int xWidget, int yWidgetBase);
void drawLine (Line *line, core::View *view, core::Rectangle *area);
int findLineIndex (int y);
int findLineOfWord (int wordIndex);
- int findWord (int x, int y);
+ Word *findWord (int x, int y, bool *inSpace);
Word *addWord (int width, int ascent, int descent,
core::style::Style *style);
- void calcTextSize (const char *text, core::style::Style *style,
+ void calcTextSize (const char *text, size_t len, core::style::Style *style,
core::Requisition *size);
void addFloatIntoContainer(core::Widget *widget, Textblock *floatGenerator);
@@ -355,7 +362,7 @@ protected:
*/
inline int lineXOffsetContents (Line *line)
{
- return innerPadding + line->leftOffset + line->boxLeft +
+ return innerPadding + line->leftOffset + line->boxLeft +
(line == lines->getRef (0) ? line1OffsetEff : 0);
}
@@ -371,7 +378,7 @@ protected:
inline int lineYOffsetWidgetAllocation (Line *line,
core::Allocation *allocation)
{
- return line->top + (allocation->ascent - lines->getRef(0)->ascent);
+ return line->top + (allocation->ascent - lines->getRef(0)->boxAscent);
}
inline int lineYOffsetWidget (Line *line)
@@ -400,7 +407,7 @@ protected:
{
return lineYOffsetWidget (lines->getRef (lineIndex));
}
-
+
inline int lineYOffsetCanvasI (int lineIndex)
{
return lineYOffsetCanvas (lines->getRef (lineIndex));
@@ -423,7 +430,7 @@ protected:
void setWidth (int width);
void setAscent (int ascent);
void setDescent (int descent);
- void draw (core::View *view, core::Rectangle *area);
+ void draw (core::View *view, core::Rectangle *area);
bool buttonPressImpl (core::EventButton *event);
bool buttonReleaseImpl (core::EventButton *event);
@@ -439,11 +446,15 @@ public:
Textblock(bool limitTextWidth);
~Textblock();
- core::Iterator *iterator (core::Content::Type mask, bool atEnd);
+ core::Iterator *iterator (core::Content::Type mask, bool atEnd);
void flush ();
- void addText (const char *text, core::style::Style *style);
+ void addText (const char *text, size_t len, core::style::Style *style);
+ inline void addText (const char *text, core::style::Style *style)
+ {
+ addText (text, strlen(text), style);
+ }
void addWidget (core::Widget *widget, core::style::Style *style);
bool addAnchor (const char *name, core::style::Style *style);
void addSpace(core::style::Style *style);