aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2013-09-16 22:01:15 +0200
committerSebastian Geerken <devnull@localhost>2013-09-16 22:01:15 +0200
commit679c1ff1091a0f2d2c401a3951af8bef9d76d553 (patch)
tree7d4488495037514d44057e6d983d1cbbffc5ad89
parentc8a4d1e1da9534f030908c792e8922d8509eb2a4 (diff)
ExternalImgRenderer for textblock works. (Unfortunately, still crashes.)
-rw-r--r--dw/textblock.cc122
-rw-r--r--dw/textblock.hh41
-rw-r--r--dw/textblock_linebreaking.cc10
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;
}