1
0
Fork 0

(svn r25768) -Fix [FS#5617] (r25344): Story Book text elements that use font size modifiers (eg {BIG_FONT}) caused problem with content height calculation. Solution: switch to pixel based content height instead of computing all heights as multiples of line heights.

release/1.4
zuu 2013-09-13 21:01:19 +00:00
parent 9e30dda720
commit e2c618eaba
1 changed files with 37 additions and 38 deletions

View File

@ -177,7 +177,7 @@ protected:
this->story_page_elements.ForceRebuild(); this->story_page_elements.ForceRebuild();
this->BuildStoryPageElementList(); this->BuildStoryPageElementList();
this->vscroll->SetCount(this->CountLines()); this->vscroll->SetCount(this->GetContentHeight());
this->SetWidgetDirty(WID_SB_SCROLLBAR); this->SetWidgetDirty(WID_SB_SCROLLBAR);
this->SetWidgetDirty(WID_SB_SEL_PAGE); this->SetWidgetDirty(WID_SB_SEL_PAGE);
this->SetWidgetDirty(WID_SB_PAGE_PANEL); this->SetWidgetDirty(WID_SB_PAGE_PANEL);
@ -268,24 +268,24 @@ protected:
} }
/** /**
* Counts how many lines that are used by Date and Title * Counts how many pixels of height that are used by Date and Title
* (excluding marginal after Title, as each body element has * (excluding marginal after Title, as each body element has
* an empty row before the elment). * an empty row before the elment).
* @param max_width Available width to display content. * @param max_width Available width to display content.
* @return the number of lines. * @return the height in pixels.
*/ */
uint CountHeadLines(int max_width) uint GetHeadHeight(int max_width) const
{ {
StoryPage *page = this->GetSelPage(); StoryPage *page = this->GetSelPage();
if (page == NULL) return 0; if (page == NULL) return 0;
int num_lines = 0; int height = 0;
/* Title lines */ /* Title lines */
num_lines += 1; // Date always use exactly one line. height += FONT_HEIGHT_NORMAL; // Date always use exactly one line.
SetDParamStr(0, page->title != NULL ? page->title : this->selected_generic_title); SetDParamStr(0, page->title != NULL ? page->title : this->selected_generic_title);
num_lines += GetStringLineCount(STR_STORY_BOOK_TITLE, max_width); height += GetStringHeight(STR_STORY_BOOK_TITLE, max_width);
return num_lines; return height;
} }
/** /**
@ -310,25 +310,23 @@ protected:
} }
/** /**
* Count the number of lines used by a given page element. * Get the height in pixels used by a page element.
* @param pe The story page element. * @param pe The story page element.
* @param max_width Available width to display content. * @param max_width Available width to display content.
* @return the number of lines. * @return the height in pixels.
*/ */
uint CountPageElementLines(const StoryPageElement &pe, int max_width) uint GetPageElementHeight(const StoryPageElement &pe, int max_width)
{ {
switch (pe.type) { switch (pe.type) {
case SPET_TEXT: case SPET_TEXT:
SetDParamStr(0, pe.text); SetDParamStr(0, pe.text);
return GetStringLineCount(STR_BLACK_RAW_STRING, max_width); return GetStringHeight(STR_BLACK_RAW_STRING, max_width);
break; break;
case SPET_GOAL: case SPET_GOAL:
case SPET_LOCATION: { case SPET_LOCATION: {
Dimension sprite_dim = GetSpriteSize(GetPageElementSprite(pe)); Dimension sprite_dim = GetSpriteSize(GetPageElementSprite(pe));
int line_height = FONT_HEIGHT_NORMAL; return sprite_dim.height;
if (line_height == 0) return 1;
return max((uint)1, sprite_dim.height / (uint)line_height);
break; break;
} }
default: default:
@ -337,27 +335,28 @@ protected:
} }
/** /**
* Count the number of lines in this window. * Get the total height of the content displayed
* @return the number of lines. * in this window.
* @return the height in pixels
*/ */
uint CountLines() uint GetContentHeight()
{ {
StoryPage *page = this->GetSelPage(); StoryPage *page = this->GetSelPage();
if (page == NULL) return 0; if (page == NULL) return 0;
int max_width = GetAvailablePageContentWidth(); int max_width = GetAvailablePageContentWidth();
uint element_vertical_dist = FONT_HEIGHT_NORMAL;
/* Head lines */ /* Head */
int num_lines = CountHeadLines(max_width); uint height = GetHeadHeight(max_width);
/* Body lines */ /* Body */
for (const StoryPageElement **iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) { for (const StoryPageElement **iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) {
const StoryPageElement *pe = *iter; const StoryPageElement *pe = *iter;
num_lines += 1; // For the space between previous element and current element. height += element_vertical_dist;
height += GetPageElementHeight(*pe, max_width);
num_lines += CountPageElementLines(*pe, max_width);
} }
return num_lines; return height;
} }
/** /**
@ -373,7 +372,7 @@ protected:
void DrawActionElement(int &y_offset, int width, int line_height, SpriteID action_sprite) const void DrawActionElement(int &y_offset, int width, int line_height, SpriteID action_sprite) const
{ {
Dimension sprite_dim = GetSpriteSize(action_sprite); Dimension sprite_dim = GetSpriteSize(action_sprite);
uint element_height = max((uint)1, sprite_dim.height / (uint)line_height) * line_height; uint element_height = max(sprite_dim.height, (uint)line_height);
uint sprite_top = y_offset + (element_height - sprite_dim.height) / 2; uint sprite_top = y_offset + (element_height - sprite_dim.height) / 2;
uint text_top = y_offset + (element_height - line_height) / 2; uint text_top = y_offset + (element_height - line_height) / 2;
@ -417,6 +416,7 @@ public:
{ {
this->CreateNestedTree(); this->CreateNestedTree();
this->vscroll = this->GetScrollbar(WID_SB_SCROLLBAR); this->vscroll = this->GetScrollbar(WID_SB_SCROLLBAR);
this->vscroll->SetStepSize(FONT_HEIGHT_NORMAL);
/* Initalize page sort. */ /* Initalize page sort. */
this->story_pages.SetSortFuncs(StoryBookWindow::page_sorter_funcs); this->story_pages.SetSortFuncs(StoryBookWindow::page_sorter_funcs);
@ -499,7 +499,7 @@ public:
/* Draw content (now coordinates given to Draw** are local to the new clipping region). */ /* Draw content (now coordinates given to Draw** are local to the new clipping region). */
int line_height = FONT_HEIGHT_NORMAL; int line_height = FONT_HEIGHT_NORMAL;
int y_offset = - this->vscroll->GetPosition() * line_height; int y_offset = - this->vscroll->GetPosition();
/* Date */ /* Date */
SetDParam(0, page->date); SetDParam(0, page->date);
@ -579,8 +579,6 @@ public:
} }
case WID_SB_PAGE_PANEL: { case WID_SB_PAGE_PANEL: {
resize->height = d.height;
d.height *= 5; d.height *= 5;
d.height += padding.height + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM; d.height += padding.height + WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM;
*size = maxdim(*size, d); *size = maxdim(*size, d);
@ -593,7 +591,7 @@ public:
virtual void OnResize() virtual void OnResize()
{ {
this->vscroll->SetCapacityFromWidget(this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM); this->vscroll->SetCapacityFromWidget(this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM);
this->vscroll->SetCount(this->CountLines()); this->vscroll->SetCount(this->GetContentHeight());
} }
virtual void OnClick(Point pt, int widget, int click_count) virtual void OnClick(Point pt, int widget, int click_count)
@ -624,27 +622,28 @@ public:
break; break;
case WID_SB_PAGE_PANEL: { case WID_SB_PAGE_PANEL: {
uint clicked_row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP); uint clicked_y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP);
uint max_width = GetAvailablePageContentWidth(); uint max_width = GetAvailablePageContentWidth();
/* Skip head rows. */ /* Skip head rows. */
uint n_head_rows = this->CountHeadLines(max_width); uint head_height = this->GetHeadHeight(max_width);
if (clicked_row < n_head_rows) return; if (clicked_y < head_height) return;
/* Detect if a page element was clicked. */ /* Detect if a page element was clicked. */
uint row = n_head_rows; uint y = head_height;
uint element_vertical_dist = FONT_HEIGHT_NORMAL;
for (const StoryPageElement *const*iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) { for (const StoryPageElement *const*iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) {
const StoryPageElement *const pe = *iter; const StoryPageElement *const pe = *iter;
row += 1; // margin row y += element_vertical_dist; // margin row
uint content_rows = CountPageElementLines(*pe, max_width); uint content_height = GetPageElementHeight(*pe, max_width);
if (clicked_row >= row && clicked_row < row + content_rows) { if (clicked_y >= y && clicked_y < y + content_height) {
this->OnPageElementClick(*pe); this->OnPageElementClick(*pe);
return; return;
} }
row += content_rows; y += content_height;
} }
} }
} }