00001 #ifndef __DW_TEXTBLOCK_HH__
00002 #define __DW_TEXTBLOCK_HH__
00003
00004 #include "core.hh"
00005 #include "../lout/misc.hh"
00006
00007 namespace dw {
00008
00131 class Textblock: public core::Widget
00132 {
00133 protected:
00134 struct Line
00135 {
00136 int firstWord;
00137 int lastWord;
00138
00139
00140
00141 int top, boxAscent, boxDescent, contentAscent, contentDescent,
00142 breakSpace, leftOffset;
00143
00144
00145
00146 int marginDescent;
00147
00148
00149
00150 int maxLineWidth;
00151 int maxWordMin;
00152 int maxParMax;
00153 int parMin;
00154
00155
00156 int parMax;
00157
00158
00159 };
00160
00161 struct Word
00162 {
00163
00164 core::Requisition size;
00165
00166 short origSpace;
00167 short effSpace;
00168
00169 core::Content content;
00170
00171 core::style::Style *style;
00172 core::style::Style *spaceStyle;
00173
00174 };
00175
00176 struct Anchor
00177 {
00178 char *name;
00179 int wordIndex;
00180 };
00181
00182 class TextblockIterator: public core::Iterator
00183 {
00184 private:
00185 int index;
00186
00187 public:
00188 TextblockIterator (Textblock *textblock, core::Content::Type mask,
00189 bool atEnd);
00190 TextblockIterator (Textblock *textblock, core::Content::Type mask,
00191 int index);
00192
00193 lout::object::Object *clone();
00194 int compareTo(lout::misc::Comparable *other);
00195
00196 bool next ();
00197 bool prev ();
00198 void highlight (int start, int end, core::HighlightLayer layer);
00199 void unhighlight (int direction, core::HighlightLayer layer);
00200 void getAllocation (int start, int end, core::Allocation *allocation);
00201 };
00202
00203 friend class TextblockIterator;
00204
00205
00206 bool hasListitemValue;
00207
00208 int innerPadding;
00209
00210 int line1Offset;
00211
00212
00213 int line1OffsetEff;
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 bool ignoreLine1OffsetSometimes;
00231
00232 bool mustQueueResize;
00233
00234 bool limitTextWidth;
00235
00236 int redrawY;
00237 int lastWordDrawn;
00238
00239
00240 int availWidth, availAscent, availDescent;
00241
00242 int lastLineWidth;
00243 int lastLineParMin;
00244 int lastLineParMax;
00245 int wrapRef;
00246
00247 lout::misc::SimpleVector <Line> *lines;
00248 lout::misc::SimpleVector <Word> *words;
00249 lout::misc::SimpleVector <Anchor> *anchors;
00250
00251 struct {int index, nChar;}
00252 hlStart[core::HIGHLIGHT_NUM_LAYERS], hlEnd[core::HIGHLIGHT_NUM_LAYERS];
00253
00254 int hoverLink;
00255
00256
00257 void queueDrawRange (int index1, int index2);
00258 void getWordExtremes (Word *word, core::Extremes *extremes);
00259 void markChange (int ref);
00260 void justifyLine (Line *line, int availWidth);
00261 Line *addLine (int wordInd, bool newPar);
00262 void calcWidgetSize (core::Widget *widget, core::Requisition *size);
00263 void rewrap ();
00264 void decorateText(core::View *view, core::style::Style *style,
00265 core::style::Color::Shading shading,
00266 int x, int yBase, int width);
00267 void drawText(int wordIndex, core::View *view, core::Rectangle *area,
00268 int xWidget, int yWidgetBase);
00269 void drawSpace(int wordIndex, core::View *view, core::Rectangle *area,
00270 int xWidget, int yWidgetBase);
00271 void drawLine (Line *line, core::View *view, core::Rectangle *area);
00272 int findLineIndex (int y);
00273 int findLineOfWord (int wordIndex);
00274 Word *findWord (int x, int y, bool *inSpace);
00275
00276 Word *addWord (int width, int ascent, int descent,
00277 core::style::Style *style);
00278 void calcTextSize (const char *text, size_t len, core::style::Style *style,
00279 core::Requisition *size);
00280
00281
00289 inline int lineXOffsetContents (Line *line)
00290 {
00291 return innerPadding + line->leftOffset +
00292 (line == lines->getRef (0) ? line1OffsetEff : 0);
00293 }
00294
00299 inline int lineXOffsetWidget (Line *line)
00300 {
00301 return lineXOffsetContents (line) + getStyle()->boxOffsetX ();
00302 }
00303
00304 inline int lineYOffsetWidgetAllocation (Line *line,
00305 core::Allocation *allocation)
00306 {
00307 return line->top + (allocation->ascent - lines->getRef(0)->boxAscent);
00308 }
00309
00310 inline int lineYOffsetWidget (Line *line)
00311 {
00312 return lineYOffsetWidgetAllocation (line, &allocation);
00313 }
00314
00318 inline int lineYOffsetCanvasAllocation (Line *line,
00319 core::Allocation *allocation)
00320 {
00321 return allocation->y + lineYOffsetWidgetAllocation(line, allocation);
00322 }
00323
00327 inline int lineYOffsetCanvas (Line *line)
00328 {
00329 return lineYOffsetCanvasAllocation(line, &allocation);
00330 }
00331
00332 inline int lineYOffsetWidgetI (int lineIndex)
00333 {
00334 return lineYOffsetWidget (lines->getRef (lineIndex));
00335 }
00336
00337 inline int lineYOffsetCanvasI (int lineIndex)
00338 {
00339 return lineYOffsetCanvas (lines->getRef (lineIndex));
00340 }
00341
00342 bool sendSelectionEvent (core::SelectionState::EventType eventType,
00343 core::MousePositionEvent *event);
00344
00345 virtual void wordWrap(int wordIndex);
00346
00347 void sizeRequestImpl (core::Requisition *requisition);
00348 void getExtremesImpl (core::Extremes *extremes);
00349 void sizeAllocateImpl (core::Allocation *allocation);
00350 void resizeDrawImpl ();
00351
00352 void markSizeChange (int ref);
00353 void markExtremesChange (int ref);
00354 void setWidth (int width);
00355 void setAscent (int ascent);
00356 void setDescent (int descent);
00357 void draw (core::View *view, core::Rectangle *area);
00358
00359 bool buttonPressImpl (core::EventButton *event);
00360 bool buttonReleaseImpl (core::EventButton *event);
00361 bool motionNotifyImpl (core::EventMotion *event);
00362 void enterNotifyImpl (core::EventCrossing *event);
00363 void leaveNotifyImpl (core::EventCrossing *event);
00364
00365 void removeChild (Widget *child);
00366
00367 public:
00368 static int CLASS_ID;
00369
00370 Textblock(bool limitTextWidth);
00371 ~Textblock();
00372
00373 core::Iterator *iterator (core::Content::Type mask, bool atEnd);
00374
00375 void flush ();
00376
00377 void addText (const char *text, size_t len, core::style::Style *style);
00378 inline void addText (const char *text, core::style::Style *style)
00379 {
00380 addText (text, strlen(text), style);
00381 }
00382 void addWidget (core::Widget *widget, core::style::Style *style);
00383 bool addAnchor (const char *name, core::style::Style *style);
00384 void addSpace(core::style::Style *style);
00385 void addParbreak (int space, core::style::Style *style);
00386 void addLinebreak (core::style::Style *style);
00387
00388 core::Widget *getWidgetAtPoint (int x, int y, int level);
00389 void handOverBreak (core::style::Style *style);
00390 void changeLinkColor (int link, int newColor);
00391 void changeWordStyle (int from, int to, core::style::Style *style,
00392 bool includeFirstSpace, bool includeLastSpace);
00393 };
00394
00395 }
00396
00397 #endif // __DW_TEXTBLOCK_HH__