summaryrefslogtreecommitdiff
path: root/old/test/vertical-align.patch
diff options
context:
space:
mode:
Diffstat (limited to 'old/test/vertical-align.patch')
-rw-r--r--old/test/vertical-align.patch435
1 files changed, 435 insertions, 0 deletions
diff --git a/old/test/vertical-align.patch b/old/test/vertical-align.patch
new file mode 100644
index 0000000..99aa39d
--- /dev/null
+++ b/old/test/vertical-align.patch
@@ -0,0 +1,435 @@
+diff -r e21306fce501 dw/textblock.cc
+--- a/dw/textblock.cc Sun Dec 20 19:02:02 2009 +0000
++++ b/dw/textblock.cc Tue Dec 22 00:59:00 2009 +0000
+@@ -329,6 +329,48 @@
+ //DBG_MSG_END (widget);
+ }
+
++/*
++ * Determine the Y offset for a word of the given style and dimensions
++ * in the line.
++ */
++int Textblock::wordYOffsetLine(Line *line, int ascent, int descent,
++ core::style::Style *style)
++{
++ int y = 0;
++
++ if (style->valign == core::style::VALIGN_TOP) {
++ MSG("valign top\n");
++ } else if (style->valign == core::style::VALIGN_TEXT_TOP) {
++ y = line->ascent - style->font->ascent;
++ MSG("valign text-top\n");
++ } else if (style->valign == core::style::VALIGN_MIDDLE) {
++ /* It is supposed to be centered at xHeight/2, i.e., something more
++ * like the "center of mass" than the midpoint of the Line.
++ */
++ y = line->ascent - (style->font->ascent - style->font->descent +
++ (ascent + descent)) / 2;
++ MSG("valign middle\n");
++ } else {
++ y = line->ascent - ascent;
++
++ if (style->valign == core::style::VALIGN_BASELINE) {
++ } else if (style->valign == core::style::VALIGN_BOTTOM) {
++ y += line->descent - descent;
++ MSG("valign bottom\n");
++ } else if (style->valign == core::style::VALIGN_TEXT_BOTTOM) {
++ y += style->font->descent - descent;
++ MSG("valign text-bottom\n");
++ } else if (style->valign == core::style::VALIGN_SUPER) {
++ y -= style->font->ascent / 2;
++ MSG("valign super\n");
++ } else if (style->valign == core::style::VALIGN_SUB) {
++ y += style->font->ascent / 3;
++ MSG("valign sub\n");
++ }
++ }
++ return y;
++}
++
+
+ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
+ {
+@@ -359,17 +401,10 @@
+ case core::Content::WIDGET:
+ /** \todo Justification within the line is done here. */
+ childAllocation.x = xCursor + allocation->x;
+- /* align=top:
+- childAllocation.y = line->top + allocation->y;
+- */
+-
+- /* align=bottom (base line) */
+- /* Commented lines break the n2 and n3 test cases at
+- * http://www.dillo.org/test/img/ */
+- childAllocation.y =
+- lineYOffsetCanvasAllocation (line, allocation)
+- + (line->ascent - word->size.ascent);
+- // - word->content.widget->getStyle()->margin.top;
++ childAllocation.y = lineYOffsetCanvasAllocation(line, allocation) +
++ wordYOffsetLine(line, word->size.ascent,
++ word->size.descent,
++ word->style);
+ childAllocation.width = word->size.width;
+ childAllocation.ascent = word->size.ascent;
+ // + word->content.widget->getStyle()->margin.top;
+@@ -861,6 +896,90 @@
+ }
+
+ /*
++ * Update the line's ascent and descent to accommodate the word.
++ */
++void Textblock::calcLineAscentDescent(const Word *word, Line *line,
++ int lineIndex)
++{
++ int wordAscent;
++ int wordDescent;
++
++ switch (word->style->valign) {
++ case core::style::VALIGN_BASELINE:
++ wordAscent = word->size.ascent;
++ wordDescent = word->size.descent;
++ break;
++ case core::style::VALIGN_SUPER:
++ wordAscent = word->size.ascent + word->style->font->ascent / 2;
++ wordDescent = word->size.descent;
++ break;
++ case core::style::VALIGN_SUB:
++ wordAscent = word->size.ascent;
++ wordDescent = word->size.descent + word->style->font->ascent / 3;
++ break;
++ case core::style::VALIGN_TOP:
++ case core::style::VALIGN_BOTTOM:
++ {
++ /* \todo This needs to be more sophisticated, since a word later in
++ * the line could provide more room, but for now let's stretch out the
++ * line if we need more room.
++ */
++ int extra = word->size.ascent + word->size.descent -
++ (line->ascent + line->descent);
++
++ wordAscent = line->ascent;
++ wordDescent = line->descent;
++
++ if (extra > 0) {
++ int extraDescent = extra * word->size.descent /
++ (word->size.ascent + word->size.descent);
++ wordDescent += extraDescent;
++ wordAscent += extra - extraDescent;
++ }
++ break;
++ }
++ case core::style::VALIGN_MIDDLE:
++ wordAscent = (word->style->font->ascent - word->style->font->descent +
++ word->size.ascent + word->size.descent) / 2;
++ wordDescent = word->size.ascent + word->size.descent - wordAscent;
++ break;
++ case core::style::VALIGN_TEXT_TOP:
++ wordAscent = word->style->font->ascent;
++ wordDescent = word->size.ascent + word->size.descent - wordAscent;
++ break;
++ case core::style::VALIGN_TEXT_BOTTOM:
++ wordDescent = word->style->font->descent;
++ wordAscent = word->size.ascent + word->size.descent - wordDescent;
++ break;
++ default:
++ misc::assertNotReached ();
++ }
++ line->ascent = misc::max (line->ascent, wordAscent);
++ line->descent = misc::max (line->descent, wordDescent);
++
++ if (word->content.type == core::Content::WIDGET) {
++ line->marginDescent =
++ misc::max (line->marginDescent,
++ wordDescent +
++ word->content.widget->getStyle()->margin.bottom);
++
++ /* If the widget is not in the first line of the paragraph, its top
++ * margin may make the line higher.
++ */
++ if (lineIndex > 0) {
++ /* Here, we know already what the break and the bottom margin
++ * contributed to the space before this line.
++ */
++ line->ascent =
++ misc::max (line->ascent,
++ wordAscent
++ + word->content.widget->getStyle()->margin.top);
++ }
++ } else
++ line->marginDescent = misc::max (line->marginDescent, line->descent);
++}
++
++/*
+ * This method is called in two cases: (i) when a word is added (by
+ * Dw_page_add_word), and (ii) when a page has to be (partially)
+ * rewrapped. It does word wrap, and adds new lines, if necessary.
+@@ -948,41 +1067,7 @@
+ }
+
+ lastLine->lastWord = wordIndex;
+- lastLine->ascent = misc::max (lastLine->ascent, (int) word->size.ascent);
+- lastLine->descent = misc::max (lastLine->descent, (int) word->size.descent);
+-
+- //DBG_OBJ_ARRSET_NUM (page, "lines.%d.ascent", page->num_lines - 1,
+- // lastLine->ascent);
+- //DBG_OBJ_ARRSET_NUM (page, "lines.%d.descent", page->num_lines - 1,
+- // lastLine->descent);
+-
+- if (word->content.type == core::Content::WIDGET) {
+- lastLine->marginDescent =
+- misc::max (lastLine->marginDescent,
+- word->size.descent +
+- word->content.widget->getStyle()->margin.bottom);
+-
+- //DBG_OBJ_ARRSET_NUM (page, "lines.%d.descent", page->num_lines - 1,
+- // lastLine->descent);
+-
+- /* If the widget is not in the first line of the paragraph, its top
+- * margin may make the line higher.
+- */
+- if (lines->size () > 1) {
+- /* Here, we know already what the break and the bottom margin
+- * contributed to the space before this line.
+- */
+- lastLine->ascent =
+- misc::max (lastLine->ascent,
+- word->size.ascent
+- + word->content.widget->getStyle()->margin.top);
+-
+- //DBG_OBJ_ARRSET_NUM (page, "lines.%d.ascent", page->num_lines - 1,
+- // lastLine->ascent);
+- }
+- } else
+- lastLine->marginDescent =
+- misc::max (lastLine->marginDescent, lastLine->descent);
++ calcLineAscentDescent(word, lastLine, lines->size() - 1);
+
+ getWordExtremes (word, &wordExtremes);
+ lastSpace = (wordIndex > 0) ? words->getRef(wordIndex - 1)->origSpace : 0;
+@@ -1216,23 +1301,23 @@
+ */
+ void Textblock::decorateText(core::View *view, core::style::Style *style,
+ core::style::Color::Shading shading,
+- int x, int yBase, int width)
++ int x, int y, int width)
+ {
+- int y;
++ int y2;
+
+- if (style->textDecoration & core::style::TEXT_DECORATION_UNDERLINE) {
+- y = yBase + 1;
+- view->drawLine (style->color, shading, x, y, x + width - 1, y);
+- }
+ if (style->textDecoration & core::style::TEXT_DECORATION_OVERLINE) {
+- y = yBase - style->font->ascent + 1;
+- view->drawLine (style->color, shading, x, y, x + width - 1, y);
++ y2 = y + 1;
++ view->drawLine (style->color, shading, x, y2, x + width - 1, y2);
+ }
+ if (style->textDecoration & core::style::TEXT_DECORATION_LINE_THROUGH) {
+ int height = 1 + style->font->xHeight / 10;
+
+- y = yBase + (style->font->descent - style->font->ascent) / 2;
+- view->drawRectangle (style->color, shading, true, x, y, width, height);
++ y2 = y + (style->font->ascent + style->font->descent) / 2;
++ view->drawRectangle (style->color, shading, true, x, y2, width, height);
++ }
++ if (style->textDecoration & core::style::TEXT_DECORATION_UNDERLINE) {
++ y2 = y + style->font->ascent + 1;
++ view->drawLine (style->color, shading, x, y2, x + width - 1, y2);
+ }
+ }
+
+@@ -1240,34 +1325,27 @@
+ * Draw a word of text.
+ */
+ void Textblock::drawText(int wordIndex, core::View *view,core::Rectangle *area,
+- int xWidget, int yWidgetBase)
++ int xWidget, int yWidget)
+ {
+ Word *word = words->getRef(wordIndex);
+ int xWorld = allocation.x + xWidget;
+ core::style::Style *style = word->style;
+- int yWorldBase;
+-
+- /* Adjust the text baseline if the word is <SUP>-ed or <SUB>-ed. */
+- if (style->valign == core::style::VALIGN_SUB)
+- yWidgetBase += style->font->ascent / 3;
+- else if (style->valign == core::style::VALIGN_SUPER) {
+- yWidgetBase -= style->font->ascent / 2;
+- }
+- yWorldBase = yWidgetBase + allocation.y;
++ int yWorld = yWidget + allocation.y;
+
+ /* Draw background (color, image), when given. */
+ if (style->hasBackground ())
+ drawBox (
+- view, style, area, xWidget, yWidgetBase - style->font->ascent,
++ view, style, area, xWidget, yWidget,
+ word->size.width, style->font->ascent + style->font->descent, false);
+
+ view->drawText (style->font, style->color,
+- core::style::Color::SHADING_NORMAL, xWorld, yWorldBase,
+- word->content.text, strlen (word->content.text));
++ core::style::Color::SHADING_NORMAL, xWorld,
++ yWorld + style->font->ascent, word->content.text,
++ strlen (word->content.text));
+
+ if (style->textDecoration)
+ decorateText(view, style, core::style::Color::SHADING_NORMAL, xWorld,
+- yWorldBase, word->size.width);
++ yWorld, word->size.width);
+
+ for (int layer = 0; layer < core::HIGHLIGHT_NUM_LAYERS; layer++) {
+ if (hlStart[layer].index <= wordIndex &&
+@@ -1303,18 +1381,18 @@
+ /* Draw background for highlighted text. */
+ view->drawRectangle (
+ wordBgColor, core::style::Color::SHADING_INVERSE, true, xStart,
+- yWorldBase - style->font->ascent, width,
+- style->font->ascent + style->font->descent);
++ yWorld, width, style->font->ascent + style->font->descent);
+
+ /* Highlight the text. */
+ view->drawText (style->font, style->color,
+ core::style::Color::SHADING_INVERSE, xStart,
+- yWorldBase, word->content.text + firstCharIdx,
++ yWorld + style->font->ascent,
++ word->content.text + firstCharIdx,
+ lastCharIdx - firstCharIdx);
+
+ if (style->textDecoration)
+ decorateText(view, style, core::style::Color::SHADING_INVERSE,
+- xStart, yWorldBase, width);
++ xStart, yWorld, width);
+ }
+ }
+ }
+@@ -1324,22 +1402,14 @@
+ * Draw a space.
+ */
+ void Textblock::drawSpace(int wordIndex, core::View *view,
+- core::Rectangle *area, int xWidget, int yWidgetBase)
++ core::Rectangle *area, int xWidget, int yWidget)
+ {
+ Word *word = words->getRef(wordIndex);
+ int xWorld = allocation.x + xWidget;
+- int yWorldBase;
++ int yWorld = allocation.y + yWidget;
+ core::style::Style *style = word->spaceStyle;
+ bool highlight = false;
+
+- /* Adjust the space baseline if it is <SUP>-ed or <SUB>-ed */
+- if (style->valign == core::style::VALIGN_SUB)
+- yWidgetBase += style->font->ascent / 3;
+- else if (style->valign == core::style::VALIGN_SUPER) {
+- yWidgetBase -= style->font->ascent / 2;
+- }
+- yWorldBase = allocation.y + yWidgetBase;
+-
+ for (int layer = 0; layer < core::HIGHLIGHT_NUM_LAYERS; layer++) {
+ if (hlStart[layer].index <= wordIndex &&
+ hlEnd[layer].index > wordIndex) {
+@@ -1355,13 +1425,13 @@
+
+ view->drawRectangle (
+ spaceBgColor, core::style::Color::SHADING_INVERSE, true, xWorld,
+- yWorldBase - style->font->ascent, word->effSpace,
++ yWorld, word->effSpace,
+ style->font->ascent + style->font->descent);
+ } else {
+ /* Draw space background (color, image), when given. */
+ if (style->hasBackground ())
+ drawBox (
+- view, style, area, xWidget, yWidgetBase - style->font->ascent,
++ view, style, area, xWidget, yWidget,
+ word->effSpace, style->font->ascent + style->font->descent, false);
+ }
+ if (style->textDecoration) {
+@@ -1369,7 +1439,7 @@
+ core::style::Color::SHADING_INVERSE :
+ core::style::Color::SHADING_NORMAL;
+
+- decorateText(view, style, shading, xWorld, yWorldBase, word->effSpace);
++ decorateText(view, style, shading, xWorld, yWorld, word->effSpace);
+ }
+ }
+
+@@ -1382,7 +1452,7 @@
+ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area)
+ {
+ int xWidget = lineXOffsetWidget(line);
+- int yWidgetBase = lineYOffsetWidget (line) + line->ascent;
++ int yWidget = lineYOffsetWidget (line);
+
+ /* Here's an idea on how to optimize this routine to minimize the number
+ * of drawing calls:
+@@ -1400,6 +1470,7 @@
+ if (xWidget + word->size.width + word->effSpace >= area->x) {
+ if (word->content.type == core::Content::TEXT ||
+ word->content.type == core::Content::WIDGET) {
++ int yOffset;
+
+ if (word->size.width > 0) {
+ if (word->content.type == core::Content::WIDGET) {
+@@ -1409,14 +1480,20 @@
+ if (child->intersects (area, &childArea))
+ child->draw (view, &childArea);
+ } else {
+- drawText(wordIndex, view, area, xWidget, yWidgetBase);
++ yOffset = wordYOffsetLine(line, word->style->font->ascent,
++ word->style->font->descent,
++ word->style);
++ drawText(wordIndex, view, area, xWidget, yWidget + yOffset);
+ }
+ }
+ if (word->effSpace > 0 && wordIndex < line->lastWord &&
+ words->getRef(wordIndex + 1)->content.type !=
+ core::Content::BREAK) {
++ yOffset = wordYOffsetLine(line, word->spaceStyle->font->ascent,
++ word->spaceStyle->font->descent,
++ word->spaceStyle);
+ drawSpace(wordIndex, view, area, xWidget + word->size.width,
+- yWidgetBase);
++ yWidget + yOffset);
+ }
+
+ }
+@@ -1582,17 +1659,8 @@
+ size->width = layout->textWidth (style->font, text, len);
+ size->ascent = style->font->ascent;
+ size->descent = style->font->descent;
+-
+- /* In case of a sub or super script we increase the word's height and
+- * potentially the line's height.
+- */
+- if (style->valign == core::style::VALIGN_SUB)
+- size->descent += (size->ascent / 3);
+- else if (style->valign == core::style::VALIGN_SUPER)
+- size->ascent += (size->ascent / 2);
+ }
+
+-
+ /**
+ * Add a word to the page structure. Stashes the argument pointer in
+ * the page data structure so that it will be deallocated on destroy.
+diff -r e21306fce501 dw/textblock.hh
+--- a/dw/textblock.hh Sun Dec 20 19:02:02 2009 +0000
++++ b/dw/textblock.hh Tue Dec 22 00:59:00 2009 +0000
+@@ -260,6 +260,7 @@
+ void markChange (int ref);
+ void justifyLine (Line *line, int availWidth);
+ void addLine (int wordInd, bool newPar);
++ void calcLineAscentDescent (const Word *word, Line *line, int lineIndex);
+ void calcWidgetSize (core::Widget *widget, core::Requisition *size);
+ void rewrap ();
+ void decorateText(core::View *view, core::style::Style *style,
+@@ -339,6 +340,8 @@
+ {
+ return lineYOffsetCanvas (lines->getRef (lineIndex));
+ }
++ int wordYOffsetLine(Line *line, int ascent, int descent,
++ core::style::Style *style);
+
+ bool sendSelectionEvent (core::SelectionState::EventType eventType,
+ core::MousePositionEvent *event);