Mercurial > dillo_port1.3
changeset 943:3fd525f8db45
Cleaned up Textblock::drawLine()
author | corvid <corvid@lavabit.com> |
---|---|
date | Fri, 13 Feb 2009 09:55:20 -0300 |
parents | 0dd5f290caa4 |
children | ff7476f5317b |
files | dw/textblock.cc dw/textblock.hh |
diffstat | 2 files changed, 134 insertions(+), 130 deletions(-) [+] |
line wrap: on
line diff
--- a/dw/textblock.cc Thu Feb 12 10:38:09 2009 -0300 +++ b/dw/textblock.cc Fri Feb 13 09:55:20 2009 -0300 @@ -1205,8 +1205,7 @@ /* * Draw the decorations on a word. */ -void Textblock::decorateText(core::View *view, Word *word, - core::style::Style *style, +void Textblock::decorateText(core::View *view, core::style::Style *style, core::style::Color::Shading shading, int x, int yBase, int width) { @@ -1236,182 +1235,189 @@ */ void Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area) { - Word *word; - int wordIndex; - int xWidget, yWidget, xWorld, yWorld, yWorldBase; - int startHL, widthHL; - int wordLen; - int diff, spaceDiff, effHLStart, effHLEnd, layer; - core::Widget *child; - core::Rectangle childArea; - core::style::Color *color, *thisBgColor, *wordBgColor; + int xWidget = lineXOffsetWidget(line); + int yWidgetBase = lineYOffsetWidget (line) + line->ascent; + int yWorldBase = allocation.y + yWidgetBase; /* Here's an idea on how to optimize this routine to minimize the number - * of calls to gdk_draw_string: + * of drawing calls: * * Copy the text from the words into a buffer, adding a new word * only if: the attributes match, and the spacing is either zero or * equal to the width of ' '. In the latter case, copy a " " into * the buffer. Then draw the buffer. */ - thisBgColor = getBgColor (); + core::style::Color *thisBgColor = getBgColor (); - xWidget = lineXOffsetWidget(line); - xWorld = allocation.x + xWidget; - yWidget = lineYOffsetWidget (line); - yWorld = allocation.y + yWidget; - yWorldBase = yWorld + line->ascent; - - for (wordIndex = line->firstWord; wordIndex < line->lastWord; + for (int wordIndex = line->firstWord; wordIndex < line->lastWord; wordIndex++) { - word = words->getRef(wordIndex); - diff = spaceDiff = 0; - color = word->style->color; + int xWorld = allocation.x + xWidget; + Word *word = words->getRef(wordIndex); //DBG_OBJ_ARRSET_NUM (page, "words.%d.<i>drawn at</i>.x", wordIndex, // xWidget); //DBG_OBJ_ARRSET_NUM (page, "words.%d.<i>drawn at</i>.y", wordIndex, - // yWidget); + // yWidgetBase - line->ascent); switch (word->content.type) { case core::Content::TEXT: - if (word->style->backgroundColor) - wordBgColor = word->style->backgroundColor; - else - wordBgColor = thisBgColor; - - /* Adjust the text baseline if the word is <SUP>-ed or <SUB>-ed. */ - if (word->style->valign == core::style::VALIGN_SUB) - diff = word->style->font->ascent / 3; - else if (word->style->valign == core::style::VALIGN_SUPER) { - diff -= word->style->font->ascent / 2; - } - if (word->spaceStyle->valign == core::style::VALIGN_SUB) - spaceDiff = word->spaceStyle->font->ascent / 3; - else if (word->spaceStyle->valign == core::style::VALIGN_SUPER) { - spaceDiff -= word->spaceStyle->font->ascent / 2; - } - /* Draw background (color, image), when given. */ - if (word->style->hasBackground () && word->size.width > 0) - drawBox ( - view, word->style, area, - xWidget, - yWidget + line->ascent + diff - word->style->font->ascent, - word->size.width, - word->style->font->ascent + word->style->font->descent, - false); + { + int yWordShift = 0, ySpaceShift = 0; - /* Draw space background (color, image), when given. */ - if (word->spaceStyle->hasBackground () && word->effSpace > 0) - drawBox ( - view, word->spaceStyle, area, - xWidget + word->size.width, - yWidget + line->ascent + diff - word->spaceStyle->font->ascent, - word->effSpace, - word->spaceStyle->font->ascent +word->spaceStyle->font->descent, - false); - view->drawText (word->style->font, color, - core::style::Color::SHADING_NORMAL, - xWorld, yWorldBase + diff, - word->content.text, strlen (word->content.text)); + if (word->size.width > 0) { + /* Draw word */ - if (word->style->textDecoration) - decorateText(view, word, word->style, - core::style::Color::SHADING_NORMAL, xWorld, - yWorldBase + diff, word->size.width); + /* Adjust the text baseline if the word is <SUP>-ed or <SUB>-ed. */ + if (word->style->valign == core::style::VALIGN_SUB) + yWordShift = word->style->font->ascent / 3; + else if (word->style->valign == core::style::VALIGN_SUPER) { + yWordShift -= word->style->font->ascent / 2; + } + /* Draw background (color, image), when given. */ + if (word->style->hasBackground ()) + drawBox ( + view, word->style, area, + xWidget, + yWidgetBase + yWordShift - word->style->font->ascent, + word->size.width, + word->style->font->ascent + word->style->font->descent, + false); - if (word->spaceStyle->textDecoration && word->effSpace) - decorateText(view, word, word->spaceStyle, - core::style::Color::SHADING_NORMAL, - xWorld + word->size.width, yWorldBase + spaceDiff, - word->effSpace); + view->drawText (word->style->font, word->style->color, + core::style::Color::SHADING_NORMAL, + xWorld, yWorldBase + yWordShift, + word->content.text, strlen (word->content.text)); - for (layer = 0; layer < core::HIGHLIGHT_NUM_LAYERS; layer++) { + if (word->style->textDecoration) + decorateText(view, word->style, + core::style::Color::SHADING_NORMAL, xWorld, + yWorldBase + yWordShift, word->size.width); + } + + if (word->effSpace > 0 && (wordIndex < line->lastWord - 1)) { + /* Draw space unless at end of line */ + + /* Adjust the space baseline if the word is <SUP>-ed or <SUB>-ed */ + if (word->spaceStyle->valign == core::style::VALIGN_SUB) + ySpaceShift = word->spaceStyle->font->ascent / 3; + else if (word->spaceStyle->valign == core::style::VALIGN_SUPER) { + ySpaceShift -= word->spaceStyle->font->ascent / 2; + } + + /* Draw space background (color, image), when given. */ + if (word->spaceStyle->hasBackground ()) + drawBox ( + view, word->spaceStyle, area, + xWidget + word->size.width, + yWidgetBase + ySpaceShift - word->spaceStyle->font->ascent, + word->effSpace, + word->spaceStyle->font->ascent + + word->spaceStyle->font->descent, + false); + + if (word->spaceStyle->textDecoration) + decorateText(view, word->spaceStyle, + core::style::Color::SHADING_NORMAL, + xWorld + word->size.width, yWorldBase +ySpaceShift, + word->effSpace); + } + + for (int layer = 0; layer < core::HIGHLIGHT_NUM_LAYERS; layer++) { if (hlStart[layer].index <= wordIndex && hlEnd[layer].index >= wordIndex) { - int widthHLSpace = 0; - - wordLen = strlen (word->content.text); - effHLEnd = misc::min (wordLen, hlEnd[layer].nChar); - effHLStart = 0; - if (wordIndex == hlStart[layer].index) - effHLStart = misc::min (hlStart[layer].nChar, wordLen); - - effHLEnd = wordLen; - if (wordIndex == hlEnd[layer].index) - effHLEnd = misc::min (hlEnd[layer].nChar, wordLen); + const int wordLen = strlen (word->content.text); + int xStart, width; + int firstCharIdx = 0; + int lastCharIdx = wordLen; - startHL = xWorld + layout->textWidth (word->style->font, - word->content.text, - effHLStart); - widthHL = - layout->textWidth (word->style->font, - word->content.text + effHLStart, - effHLEnd - effHLStart); + if (wordIndex == hlStart[layer].index) + firstCharIdx = misc::min (hlStart[layer].nChar, wordLen); - // If the space after this word highlighted, and this word - // is not the last one in this line, highlight also the - // space. - /** \todo This should also be done with spaces after non-text - * words, but this is not yet defined very well. */ - if (wordIndex < hlEnd[layer].index && - wordIndex < words->size () && - wordIndex != line->lastWord - 1) - widthHLSpace = word->effSpace; + if (wordIndex == hlEnd[layer].index) + lastCharIdx = misc::min (hlEnd[layer].nChar, wordLen); + xStart = xWorld + layout->textWidth (word->style->font, + word->content.text, + firstCharIdx); + width = layout->textWidth (word->style->font, + word->content.text + firstCharIdx, + lastCharIdx - firstCharIdx); - if (widthHL != 0) { + if (width > 0) { + /* Highlight text */ + core::style::Color *wordBgColor; + + if (!(wordBgColor = word->style->backgroundColor)) + wordBgColor = thisBgColor; + /* Draw background for highlighted text. */ view->drawRectangle ( wordBgColor, core::style::Color::SHADING_INVERSE, - true, startHL, - yWorldBase + diff - word->style->font->ascent, - widthHL, + true, xStart, + yWorldBase + yWordShift - word->style->font->ascent, + width, word->style->font->ascent + word->style->font->descent); + /* Highlight the text. */ - view->drawText (word->style->font, - color, core::style::Color::SHADING_INVERSE, - startHL, yWorldBase + diff, - word->content.text + effHLStart, - effHLEnd - effHLStart); + view->drawText (word->style->font, word->style->color, + core::style::Color::SHADING_INVERSE, + xStart, yWorldBase + yWordShift, + word->content.text + firstCharIdx, + lastCharIdx - firstCharIdx); if (word->style->textDecoration) - decorateText(view, word, word->style, - core::style::Color::SHADING_INVERSE, startHL, - yWorldBase + diff, widthHL); + decorateText(view, word->style, + core::style::Color::SHADING_INVERSE, xStart, + yWorldBase + yWordShift, width); } - if (widthHLSpace > 0) { + xStart += width; + + // Show highlighted space unless this is the last word on the + // line. + /** \todo This should also be done with spaces after non-text + * words, but this is not yet defined very well. */ + + width = 0; + if (wordIndex < hlEnd[layer].index && + wordIndex < line->lastWord - 1) + width = word->effSpace; + + if (width > 0) { + /* Highlight space */ core::style::Color *spaceBgColor; if (!(spaceBgColor = word->spaceStyle->backgroundColor)) spaceBgColor = thisBgColor; view->drawRectangle ( - spaceBgColor, - core::style::Color::SHADING_INVERSE, - true, startHL + widthHL, - yWorldBase + spaceDiff -word->spaceStyle->font->ascent, - widthHLSpace, + spaceBgColor, core::style::Color::SHADING_INVERSE, + true, xStart, + yWorldBase + ySpaceShift - word->spaceStyle->font->ascent, + width, word->spaceStyle->font->ascent + - word->spaceStyle->font->descent); + word->spaceStyle->font->descent); + if (word->spaceStyle->textDecoration) { - decorateText(view, word, word->spaceStyle, + decorateText(view, word->spaceStyle, core::style::Color::SHADING_INVERSE, - startHL + widthHL, yWorldBase + spaceDiff, - widthHLSpace); + xStart, yWorldBase + ySpaceShift, + width); } } } } break; + } + case core::Content::WIDGET: + { + core::Widget *child = word->content.widget; + core::Rectangle childArea; - case core::Content::WIDGET: - child = word->content.widget; if (child->intersects (area, &childArea)) child->draw (view, &childArea); break; - + } case core::Content::ANCHOR: case core::Content::BREAK: /* nothing - an anchor/break isn't seen */ /* @@ -1439,11 +1445,9 @@ break; default: - MSG_ERR("at (%d, %d).\n", xWorld, yWorldBase + diff); + MSG_ERR("at (%d, %d).\n", xWorld, yWorldBase); break; } - - xWorld += word->size.width + word->effSpace; xWidget += word->size.width + word->effSpace; } }
--- a/dw/textblock.hh Thu Feb 12 10:38:09 2009 -0300 +++ b/dw/textblock.hh Fri Feb 13 09:55:20 2009 -0300 @@ -262,9 +262,9 @@ void addLine (int wordInd, bool newPar); void calcWidgetSize (core::Widget *widget, core::Requisition *size); void rewrap (); - void decorateText(core::View *view, Word *word, core::style::Style *style, - core::style::Color::Shading shading, int x, int yBase, - int width); + void decorateText(core::View *view, core::style::Style *style, + core::style::Color::Shading shading, + int x, int yBase, int width); void drawLine (Line *line, core::View *view, core::Rectangle *area); int findLineIndex (int y); int findLineOfWord (int wordIndex);