diff options
author | Sebastian Geerken <devnull@localhost> | 2013-09-16 22:01:15 +0200 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2013-09-16 22:01:15 +0200 |
commit | 679c1ff1091a0f2d2c401a3951af8bef9d76d553 (patch) | |
tree | 7d4488495037514d44057e6d983d1cbbffc5ad89 | |
parent | c8a4d1e1da9534f030908c792e8922d8509eb2a4 (diff) |
ExternalImgRenderer for textblock works. (Unfortunately, still crashes.)
-rw-r--r-- | dw/textblock.cc | 122 | ||||
-rw-r--r-- | dw/textblock.hh | 41 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 10 |
3 files changed, 173 insertions, 0 deletions
diff --git a/dw/textblock.cc b/dw/textblock.cc index d7e1704e..035bb4d0 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -41,6 +41,85 @@ namespace dw { int Textblock::CLASS_ID = -1; +Textblock::WordImgRenderer::WordImgRenderer (Textblock *textblock, + Word *word) +{ + //printf ("new WordImgRenderer %p\n", this); + + this->textblock = textblock; + this->word = word; + dataSet = false; +} + +Textblock::WordImgRenderer::~WordImgRenderer () +{ + //printf ("delete WordImgRenderer %p\n", this); +} + +void Textblock::WordImgRenderer::setData (int xWordWidget, int lineNo) +{ + dataSet = true; + this->xWordWidget = xWordWidget; + this->lineNo = lineNo; +} + +bool Textblock::WordImgRenderer::readyToDraw () +{ + return dataSet && textblock->wasAllocated () + && lineNo < textblock->lines->size(); +} + +void Textblock::WordImgRenderer::getArea (int *x, int *y, int *width, + int *height) +{ + Line *line = textblock->lines->getRef (lineNo); + *x = textblock->allocation.x + this->xWordWidget; + *y = textblock->lineYOffsetCanvas (line); + *width = word->size.width; + *height = line->boxAscent + line->boxDescent; +} + +void Textblock::WordImgRenderer::getRefArea (int *xRef, int *yRef, + int *widthRef, int *heightRef) +{ + /** + * \todo Reference should be the containing block (which will be + * introduced later), not the widget allocation. (And also, + * there should be one single method for this.) + */ + *xRef = textblock->allocation.x; + *yRef = textblock->allocation.y; + *widthRef = textblock->allocation.width; + *heightRef = textblock->getHeight (); +} + +core::style::Style *Textblock::WordImgRenderer::getStyle () +{ + return word->style; +} + +void Textblock::WordImgRenderer::draw (int x, int y, int width, int height) +{ + textblock->queueDrawArea (x - textblock->allocation.x, + y - textblock->allocation.y, width, height); + +} + +void Textblock::SpaceImgRenderer::getArea (int *x, int *y, int *width, + int *height) +{ + WordImgRenderer::getArea (x, y, width, height); + *x += *width; + *width = word->effSpace; +} + +core::style::Style *Textblock::SpaceImgRenderer::getStyle () +{ + return word->spaceStyle; +} + +// ---------------------------------------------------------------------- + Textblock::DivChar Textblock::divChars[NUM_DIV_CHARS] = { // soft hyphen (U+00AD) { "\xc2\xad", true, false, true, PENALTY_HYPHEN, -1 }, @@ -181,8 +260,22 @@ Textblock::~Textblock () for (int i = 0; i < words->size(); i++) { Word *word = words->getRef (i); + if (word->content.type == core::Content::WIDGET) delete word->content.widget; + + if (word->wordImgRenderer) { + word->style->backgroundImage->removeExternalImgRenderer + (word->wordImgRenderer); + delete word->wordImgRenderer; + } + + if (word->spaceImgRenderer) { + word->spaceStyle->backgroundImage->removeExternalImgRenderer + (word->spaceImgRenderer); + delete word->spaceImgRenderer; + } + word->style->unref (); word->spaceStyle->unref (); } @@ -1365,6 +1458,21 @@ void Textblock::fillWord (Word *word, int width, int ascent, int descent, word->style = style; word->spaceStyle = style; + + if (word->style->backgroundImage) { + word->wordImgRenderer = new WordImgRenderer (this, word); + word->style->backgroundImage->putExternalImgRenderer + (word->wordImgRenderer); + } else + word->wordImgRenderer = NULL; + + if (word->spaceStyle->backgroundImage) { + word->spaceImgRenderer = new SpaceImgRenderer (this, word); + word->spaceStyle->backgroundImage->putExternalImgRenderer + (word->spaceImgRenderer); + } else + word->spaceImgRenderer = NULL; + style->ref (); style->ref (); } @@ -1894,9 +2002,23 @@ void Textblock::fillSpace (Word *word, core::style::Style *style) //DBG_OBJ_ARRSET_NUM (this, "words.%d.content.space", wordIndex, // word->content.space); + + if (word->spaceImgRenderer) { + word->spaceStyle->backgroundImage->removeExternalImgRenderer + (word->spaceImgRenderer); + delete word->spaceImgRenderer; + } + word->spaceStyle->unref (); word->spaceStyle = style; style->ref (); + + if (word->spaceStyle->backgroundImage) { + word->spaceImgRenderer = new SpaceImgRenderer (this, word); + word->spaceStyle->backgroundImage->putExternalImgRenderer + (word->spaceImgRenderer); + } else + word->spaceImgRenderer = NULL; } } diff --git a/dw/textblock.hh b/dw/textblock.hh index aae0edad..33bb5dbc 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -237,6 +237,42 @@ private: static const char *hyphenDrawChar; protected: + struct Word; + + /** + * \brief Implementation used for words. + */ + class WordImgRenderer: public core::style::StyleImage::ExternalImgRenderer + { + protected: + Textblock *textblock; + Word *word; + bool dataSet; + int xWordWidget, lineNo; + + public: + WordImgRenderer (Textblock *textblock, Word *word); + ~WordImgRenderer (); + + void setData (int xWordWidget, int lineNo); + + bool readyToDraw (); + void getArea (int *x, int *y, int *width, int *height); + void getRefArea (int *xRef, int *yRef, int *widthRef, int *heightRef); + core::style::Style *getStyle (); + void draw (int x, int y, int width, int height); + }; + + class SpaceImgRenderer: public WordImgRenderer + { + public: + inline SpaceImgRenderer (Textblock *textblock, Word *word) : + WordImgRenderer (textblock, word) { } + + void getArea (int *x, int *y, int *width, int *height); + core::style::Style *getStyle (); + }; + struct Paragraph { int firstWord; /* first word's index in word vector */ @@ -349,6 +385,11 @@ protected: core::style::Style *style; core::style::Style *spaceStyle; /* initially the same as of the word, later set by a_Dw_page_add_space */ + + // These two are used rarely, so there is perhaps a way to store + // them which is consuming less memory. + WordImgRenderer *wordImgRenderer; + SpaceImgRenderer *spaceImgRenderer; }; void printWordShort (Word *word); diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc index d1b0df85..bf47140e 100644 --- a/dw/textblock_linebreaking.cc +++ b/dw/textblock_linebreaking.cc @@ -418,6 +418,16 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord, //printf (": "); //words->getRef(line->lastWord)->badnessAndPenalty.print (); //printf ("\n"); + + int xWidget = lineXOffsetWidget(line); + for (int i = firstWord; i <= lastWord; i++) { + Word *word = words->getRef (i); + if (word->wordImgRenderer) + word->wordImgRenderer->setData (xWidget, lines->size () - 1); + if (word->spaceImgRenderer) + word->spaceImgRenderer->setData (xWidget, lines->size () - 1); + xWidget += word->size.width + word->effSpace; + } return line; } |