summaryrefslogtreecommitdiff
path: root/dw/textblock.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dw/textblock.cc')
-rw-r--r--dw/textblock.cc208
1 files changed, 194 insertions, 14 deletions
diff --git a/dw/textblock.cc b/dw/textblock.cc
index dec512d4..21aaa9dd 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -41,6 +41,103 @@ namespace dw {
int Textblock::CLASS_ID = -1;
+Textblock::WordImgRenderer::WordImgRenderer (Textblock *textblock,
+ int wordNo)
+{
+ //printf ("new WordImgRenderer %p\n", this);
+
+ this->textblock = textblock;
+ this->wordNo = wordNo;
+ 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 ()
+{
+ //print ();
+ //printf ("\n");
+
+ return dataSet && textblock->wasAllocated ()
+ && wordNo < textblock->words->size()
+ && lineNo < textblock->lines->size();
+}
+
+void Textblock::WordImgRenderer::getBgArea (int *x, int *y, int *width,
+ int *height)
+{
+ // TODO Subtract margin and border (padding box)?
+ Line *line = textblock->lines->getRef (lineNo);
+ *x = textblock->allocation.x + this->xWordWidget;
+ *y = textblock->lineYOffsetCanvas (line);
+ *width = textblock->words->getRef(wordNo)->size.width;
+ *height = line->boxAscent + line->boxDescent;
+}
+
+void Textblock::WordImgRenderer::getRefArea (int *xRef, int *yRef,
+ int *widthRef, int *heightRef)
+{
+ // See comment in Widget::drawBox about the reference area.
+ textblock->getPaddingArea (xRef, yRef, widthRef, heightRef);
+}
+
+core::style::Style *Textblock::WordImgRenderer::getStyle ()
+{
+ return textblock->words->getRef(wordNo)->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::WordImgRenderer::print ()
+{
+ printf ("%p: word #%d, ", this, wordNo);
+ if (wordNo < textblock->words->size())
+ textblock->printWordShort (textblock->words->getRef(wordNo));
+ else
+ printf ("<word %d does not exist>", wordNo);
+ printf (", data set: %s", dataSet ? "yes" : "no");
+}
+
+void Textblock::SpaceImgRenderer::getBgArea (int *x, int *y, int *width,
+ int *height)
+{
+ WordImgRenderer::getBgArea (x, y, width, height);
+ *x += *width;
+ *width = textblock->words->getRef(wordNo)->effSpace;
+}
+
+core::style::Style *Textblock::SpaceImgRenderer::getStyle ()
+{
+ return textblock->words->getRef(wordNo)->spaceStyle;
+}
+
+void Textblock::SpaceImgRenderer::print ()
+{
+ printf ("%p: word FOR SPACE #%d, ", this, wordNo);
+ if (wordNo < textblock->words->size())
+ textblock->printWordShort (textblock->words->getRef(wordNo));
+ else
+ printf ("<word %d does not exist>", wordNo);
+ printf (", data set: %s", dataSet ? "yes" : "no");
+}
+
+// ----------------------------------------------------------------------
+
Textblock::DivChar Textblock::divChars[NUM_DIV_CHARS] = {
// soft hyphen (U+00AD)
{ "\xc2\xad", true, false, true, PENALTY_HYPHEN, -1 },
@@ -188,8 +285,13 @@ 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;
+
+ removeWordImgRenderer (i);
+ removeSpaceImgRenderer (i);
+
word->style->unref ();
word->spaceStyle->unref ();
}
@@ -807,8 +909,8 @@ void Textblock::calcWidgetSize (core::Widget *widget, core::Requisition *size)
size->width = core::style::absLengthVal (wstyle->width)
+ wstyle->boxDiffWidth ();
else
- size->width = (int) (core::style::perLengthVal (wstyle->width)
- * availWidth);
+ size->width =
+ core::style::multiplyWithPerLength (availWidth, wstyle->width);
if (wstyle->height == core::style::LENGTH_AUTO) {
size->ascent = requisition.ascent;
@@ -820,9 +922,10 @@ void Textblock::calcWidgetSize (core::Widget *widget, core::Requisition *size)
+ wstyle->boxDiffHeight ();
size->descent = 0;
} else {
- double len = core::style::perLengthVal (wstyle->height);
- size->ascent = (int) (len * availAscent);
- size->descent = (int) (len * availDescent);
+ size->ascent =
+ core::style::multiplyWithPerLength (wstyle->height, availAscent);
+ size->descent =
+ core::style::multiplyWithPerLength (wstyle->height, availDescent);
}
}
@@ -1353,14 +1456,77 @@ Textblock::Word *Textblock::addWord (int width, int ascent, int descent,
short flags, core::style::Style *style)
{
words->increase ();
- Word *word = words->getLastRef ();
- fillWord (word, width, ascent, descent, flags, style);
- return word;
+ int wordNo = words->size () - 1;
+ initWord (wordNo);
+ fillWord (wordNo, width, ascent, descent, flags, style);
+ return words->getRef (wordNo);;
+}
+
+/**
+ * Basic initialization, which is neccessary before fillWord.
+ */
+void Textblock::initWord (int wordNo)
+{
+ Word *word = words->getRef (wordNo);
+
+ word->style = word->spaceStyle = NULL;
+ word->wordImgRenderer = NULL;
+ word->spaceImgRenderer = NULL;
+}
+
+void Textblock::removeWordImgRenderer (int wordNo)
+{
+ Word *word = words->getRef (wordNo);
+
+ if (word->style && word->wordImgRenderer) {
+ word->style->backgroundImage->removeExternalImgRenderer
+ (word->wordImgRenderer);
+ delete word->wordImgRenderer;
+ word->wordImgRenderer = NULL;
+ }
}
-void Textblock::fillWord (Word *word, int width, int ascent, int descent,
+void Textblock::setWordImgRenderer (int wordNo)
+{
+ Word *word = words->getRef (wordNo);
+
+ if (word->style->backgroundImage) {
+ word->wordImgRenderer = new WordImgRenderer (this, wordNo);
+ word->style->backgroundImage->putExternalImgRenderer
+ (word->wordImgRenderer);
+ } else
+ word->wordImgRenderer = NULL;
+}
+
+void Textblock::removeSpaceImgRenderer (int wordNo)
+{
+ Word *word = words->getRef (wordNo);
+
+ if (word->spaceStyle && word->spaceImgRenderer) {
+ word->spaceStyle->backgroundImage->removeExternalImgRenderer
+ (word->spaceImgRenderer);
+ delete word->spaceImgRenderer;
+ word->spaceImgRenderer = NULL;
+ }
+}
+
+void Textblock::setSpaceImgRenderer (int wordNo)
+{
+ Word *word = words->getRef (wordNo);
+
+ if (word->spaceStyle->backgroundImage) {
+ word->spaceImgRenderer = new SpaceImgRenderer (this, wordNo);
+ word->spaceStyle->backgroundImage->putExternalImgRenderer
+ (word->spaceImgRenderer);
+ } else
+ word->spaceImgRenderer = NULL;
+}
+
+void Textblock::fillWord (int wordNo, int width, int ascent, int descent,
short flags, core::style::Style *style)
{
+ Word *word = words->getRef (wordNo);
+
word->size.width = width;
word->size.ascent = ascent;
word->size.descent = descent;
@@ -1370,8 +1536,15 @@ void Textblock::fillWord (Word *word, int width, int ascent, int descent,
word->content.space = false;
word->flags = flags;
+ removeWordImgRenderer (wordNo);
+ removeSpaceImgRenderer (wordNo);
+
word->style = style;
word->spaceStyle = style;
+
+ setWordImgRenderer (wordNo);
+ setSpaceImgRenderer (wordNo);
+
style->ref ();
style->ref ();
}
@@ -1473,9 +1646,9 @@ void Textblock::calcTextSize (const char *text, size_t len,
if (core::style::isAbsLength (style->lineHeight))
height = core::style::absLengthVal(style->lineHeight);
else
- height = lout::misc::roundInt (
- core::style::perLengthVal(style->lineHeight) *
- style->font->size);
+ height =
+ core::style::multiplyWithPerLengthRounded (style->font->size,
+ style->lineHeight);
leading = height - style->font->size;
size->ascent += leading / 2;
@@ -1849,7 +2022,7 @@ void Textblock::addSpace (core::style::Style *style)
{
int wordIndex = words->size () - 1;
if (wordIndex >= 0) {
- fillSpace (words->getRef(wordIndex), style);
+ fillSpace (wordIndex, style);
accumulateWordData (wordIndex);
correctLastWordExtremes ();
}
@@ -1871,7 +2044,7 @@ void Textblock::addBreakOption (core::style::Style *style, bool forceBreak)
}
}
-void Textblock::fillSpace (Word *word, core::style::Style *style)
+void Textblock::fillSpace (int wordNo, core::style::Style *style)
{
// Old comment:
//
@@ -1887,6 +2060,8 @@ void Textblock::fillSpace (Word *word, core::style::Style *style)
//
// TODO: Re-evaluate again.
+ Word *word = words->getRef (wordNo);
+
// TODO: This line does not work: addBreakOption (word, style);
// Do not override a previously set break penalty.
@@ -1904,9 +2079,14 @@ void Textblock::fillSpace (Word *word, core::style::Style *style)
//DBG_OBJ_ARRSET_NUM (this, "words.%d.content.space", wordIndex,
// word->content.space);
+
+ removeSpaceImgRenderer (wordNo);
+
word->spaceStyle->unref ();
word->spaceStyle = style;
style->ref ();
+
+ setSpaceImgRenderer (wordNo);
}
}