[sword-svn] r158 - trunk/src/SwordReader_GUI
dtrotzjr at www.crosswire.org
dtrotzjr at www.crosswire.org
Sat Jul 26 21:58:40 MST 2008
Author: dtrotzjr
Date: 2008-07-26 21:58:40 -0700 (Sat, 26 Jul 2008)
New Revision: 158
Modified:
trunk/src/SwordReader_GUI/SRTextView.cpp
trunk/src/SwordReader_GUI/SRTextView.h
Log:
First stages of demand loading in place. This is not a very usable commit, I just want to ensure my changes are documented and backed up. This current iteration loads only enough text to fill the window then stops. This gives a clearer picture of how fast things can be with demand loading. Once again highly marked up texts do take time, but never more than ~1 second.
Modified: trunk/src/SwordReader_GUI/SRTextView.cpp
===================================================================
--- trunk/src/SwordReader_GUI/SRTextView.cpp 2008-07-27 00:42:57 UTC (rev 157)
+++ trunk/src/SwordReader_GUI/SRTextView.cpp 2008-07-27 04:58:40 UTC (rev 158)
@@ -51,11 +51,16 @@
, m_hCurFont(NULL)
, m_dwWordIndex(0)
, m_fAppended(FALSE)
+, m_nLineX(0)
+, m_nLineY(0)
+, m_dwLineNum(0)
{
m_wcsClassName = "SRTextView";
m_wcsWindowName = "SwordReader";
m_hInstance = SRFramework::SRApp::GetInstanceHandle();
+ memset(&m_rsState, 0, sizeof(m_rsState));
+
m_ptLastClick.x = 0; m_ptLastClick.y = 0;
// Init the current font
@@ -425,22 +430,18 @@
m_dwBuffSize = 0;
m_nTop = 0;
m_fPreRendered = FALSE;
+ m_fAppended = FALSE;
+ m_dwWordIndex = 0;
}
VOID SRTextView::PreRenderBuff(HDC hdc)
{
SRTextWord thisWord;
- RenderState rsState;
- memset(&rsState, 0, sizeof(rsState));
RECT rectDims;
- INT nLineX = BTEXT_MARGIN;
- INT nLineY = BTEXT_MARGIN;
- DWORD dwLineNum = 0;
rectDims.top = 0;
rectDims.left = 0;
rectDims.right = 0;
rectDims.bottom = 0;
INT nLineH = (INT)(BTEXT_LINE_SPACING*(FLOAT)DrawText(hdc, L" ", 1, &rectDims, DT_CALCRECT | DT_LEFT | DT_BOTTOM | DT_SINGLELINE));
- DWORD dwWordIndex = m_fAppended ? m_dwWordIndex : 0;
DWORD dwWordEnd = 0;
INT nSpaceWidth = rectDims.right - rectDims.left;
INT nScreenWidth= (m_rect.right - m_rect.left) - BTEXT_MARGIN;
@@ -453,39 +454,46 @@
if(m_dwBuffEnd == 0)
return;
- m_BTLines.ClearLines();
- m_BTLines.InitLines(nLineH);
+ if(!m_fAppended){
+ memset(&m_rsState, 0, sizeof(m_rsState));
+ m_nLineX = BTEXT_MARGIN;
+ m_nLineY = BTEXT_MARGIN;
+ m_dwLineNum = 0;
+ m_dwWordIndex = 0;
+ m_BTLines.ClearLines();
+ m_BTLines.InitLines(nLineH);
+ }
+
int tmpI = 0;
while(TRUE){
thisWord.Clear();
- rsState.m_space_encountered = FALSE;
+ m_rsState.m_space_encountered = FALSE;
- GetSpaces(rsState, dwWordIndex);
- nAddLines = GetHTMLTags(rsState, dwWordIndex);
+ GetSpaces(m_rsState, m_dwWordIndex);
+ nAddLines = GetHTMLTags(m_rsState, m_dwWordIndex);
if(nAddLines){
- dwLineNum += nAddLines;
- nLineX = BTEXT_MARGIN;
- nLineY += nAddLines * nLineH;
- rsState.m_space_encountered = FALSE;
+ m_dwLineNum += nAddLines;
+ m_nLineX = BTEXT_MARGIN;
+ m_nLineY += nAddLines * nLineH;
+ m_rsState.m_space_encountered = FALSE;
}
- GetSpaces(rsState, dwWordIndex);
- if(rsState.m_space_encountered){
- nLineX += nSpaceWidth;
- rsState.m_space_encountered = FALSE;
- rsState.m_dwlWordNum++;
- rsState.m_dwSubWordNum = 0;
+ GetSpaces(m_rsState, m_dwWordIndex);
+ if(m_rsState.m_space_encountered){
+ m_nLineX += nSpaceWidth;
+ m_rsState.m_space_encountered = FALSE;
+ m_rsState.m_dwlWordNum++;
+ m_rsState.m_dwSubWordNum = 0;
}else
- rsState.m_dwSubWordNum++;
- if(tmpI++ == 380)
- tmpI = tmpI + 1;
- dwResult = NextWord(rsState, dwWordIndex, dwWordEnd);
+ m_rsState.m_dwSubWordNum++;
+
+ dwResult = NextWord(m_rsState, m_dwWordIndex, dwWordEnd);
if(dwResult == BTEXT_BUFFER_END || dwWordEnd == 0){
break;
}
- rectDims.left = nLineX;
+ rectDims.left = m_nLineX;
// Font...
- SRFontTagItem *tag = rsState.m_lpftFontTagHead;
+ SRFontTagItem *tag = m_rsState.m_lpftFontTagHead;
dwlFontColor = BTEXT_DEFAULT_FONT_COLOR;
dwlFontHeight = abs(BTEXT_DEFAULT_FONT_HEIGHT);
while(tag){
@@ -494,41 +502,41 @@
dwlFontHeight += tag->m_siRelFontSize;
tag = tag->m_lpftNext;
}
- if(rsState.m_wSubState || rsState.m_wSuperState)
+ if(m_rsState.m_wSubState || m_rsState.m_wSuperState)
dwlFontHeight -= 3;
dwlFontState =
((DWORDLONG)(dwlFontColor << 40) & 0xFFFFFF0000000000) |
((DWORDLONG)(dwlFontHeight << 32) & 0x000000FF00000000) |
- (rsState.m_wAState > 0 ? BTEXT_HTML_A_BEG : 0) |
- (rsState.m_wBoldState > 0 ? BTEXT_HTML_B_BEG : 0) |
- (rsState.m_wItalicState > 0 ? BTEXT_HTML_I_BEG : 0);
+ (m_rsState.m_wAState > 0 ? BTEXT_HTML_A_BEG : 0) |
+ (m_rsState.m_wBoldState > 0 ? BTEXT_HTML_B_BEG : 0) |
+ (m_rsState.m_wItalicState > 0 ? BTEXT_HTML_I_BEG : 0);
SetFont(hdc, dwlFontState);
- rectDims.top = nLineY;
+ rectDims.top = m_nLineY;
// Set the properties for this word.
thisWord.m_rect = rectDims;
thisWord.m_dwlfFontState = dwlFontState;
- thisWord.m_lpszHref = rsState.m_lpszHref;
- thisWord.m_dwHrefLen = rsState.m_dwHrefLen;
- thisWord.m_dwlWordNum = rsState.m_dwlWordNum;
- thisWord.m_dwSubWordNum = rsState.m_dwSubWordNum;
- thisWord.m_wVerseNum = rsState.m_wVerseNum;
+ thisWord.m_lpszHref = m_rsState.m_lpszHref;
+ thisWord.m_dwHrefLen = m_rsState.m_dwHrefLen;
+ thisWord.m_dwlWordNum = m_rsState.m_dwlWordNum;
+ thisWord.m_dwSubWordNum = m_rsState.m_dwSubWordNum;
+ thisWord.m_wVerseNum = m_rsState.m_wVerseNum;
// Determine if we encountered any special entities...
- if(rsState.m_wTotalSpclEnt > 0){
- InterpretSpecialEntities(dwWordIndex, dwWordEnd, &thisWord);
+ if(m_rsState.m_wTotalSpclEnt > 0){
+ InterpretSpecialEntities(m_dwWordIndex, dwWordEnd, &thisWord);
}else{
thisWord.m_fOwner = FALSE;
- thisWord.m_lpszWord = &m_lpszBuff[dwWordIndex];
+ thisWord.m_lpszWord = (TCHAR*)((DWORD)&m_lpszBuff[m_dwWordIndex] - (DWORD)&m_lpszBuff[0]);
thisWord.m_dwWordLen = dwWordEnd;
}
// Calc the text rect
- DrawText(hdc, thisWord.m_lpszWord, thisWord.m_dwWordLen, &thisWord.m_rect,
+ DrawText(hdc, (TCHAR*)((DWORD)thisWord.m_lpszWord + (thisWord.m_fOwner ? 0 : (DWORD)&m_lpszBuff[0])), thisWord.m_dwWordLen, &thisWord.m_rect,
DT_CALCRECT | DT_LEFT | DT_BOTTOM | DT_SINGLELINE);
- if(rsState.m_wSuperState)
+ if(m_rsState.m_wSuperState)
thisWord.m_rect.top -= 1; // TODO: Determine the '1' value based upon the font size
- else if(rsState.m_wSubState)
+ else if(m_rsState.m_wSubState)
thisWord.m_rect.top = 2*thisWord.m_rect.top + nLineH - thisWord.m_rect.bottom + 1; // TODO: Same as above...
else
thisWord.m_rect.top = 2*thisWord.m_rect.top + nLineH - thisWord.m_rect.bottom; // Baseline justify
@@ -541,31 +549,31 @@
if(thisWord.m_dwSubWordNum > 0)
adjustedMargin = m_BTLines.ValidateNewLineWord(thisWord.m_dwlWordNum,nLineH, BTEXT_MARGIN);
- dwLineNum++;
+ m_dwLineNum++;
thisWord.m_rect.right = thisWord.m_rect.right - thisWord.m_rect.left + adjustedMargin;
thisWord.m_rect.left = adjustedMargin;
thisWord.m_rect.top += nLineH;
thisWord.m_rect.bottom += nLineH;
- nLineY += nLineH;
+ m_nLineY += nLineH;
}
// Store the line to be rendered later.
- m_BTLines.AddWordToLine(dwLineNum, thisWord);
+ m_BTLines.AddWordToLine(m_dwLineNum, thisWord);
// Prep for next iteration
- if(rsState.m_space_encountered)
- nLineX = thisWord.m_rect.right + nSpaceWidth;
+ if(m_rsState.m_space_encountered)
+ m_nLineX = thisWord.m_rect.right + nSpaceWidth;
else
- nLineX = thisWord.m_rect.right;
+ m_nLineX = thisWord.m_rect.right;
//curWord++;
- dwWordIndex += dwWordEnd;
+ m_dwWordIndex += dwWordEnd;
}
- if(rsState.m_lpftFontTagHead) // Properly formatted text would never need this, but that cannot be assumed.
- delete rsState.m_lpftFontTagHead; // Do not delete Tail it is a convenience pointer...
+ if(m_rsState.m_lpftFontTagHead) // Properly formatted text would never need this, but that cannot be assumed.
+ delete m_rsState.m_lpftFontTagHead; // Do not delete Tail it is a convenience pointer...
- m_dwWordIndex = dwWordIndex;
+ m_dwWordIndex = m_dwWordIndex;
m_fAppended = FALSE;
m_fPreRendered = TRUE;
}
@@ -700,7 +708,7 @@
SetFont(hdc, pTWord->m_dwlfFontState);
}
- ExtTextOut(hdc,pTWord->m_rect.left, pTWord->m_rect.top + m_nTop, NULL, NULL, pTWord->m_lpszWord, pTWord->m_dwWordLen, NULL);
+ ExtTextOut(hdc,pTWord->m_rect.left, pTWord->m_rect.top + m_nTop, NULL, NULL, (TCHAR*)((DWORD)pTWord->m_lpszWord + (pTWord->m_fOwner ? 0 : (DWORD)&m_lpszBuff[0])), pTWord->m_dwWordLen, NULL);
pTWord = pTWord->m_lpNextWord;
}
}
@@ -790,7 +798,7 @@
if(pbtWord->m_dwlfFontState & BTEXT_HTML_A_BEG && pbtWord->m_lpszHref){
wcsncpy(szWordFound, pbtWord->m_lpszHref, pbtWord->m_dwHrefLen);
}else{
- wcsncpy(szWordFound, pbtWord->m_lpszWord, pbtWord->m_dwWordLen);
+ wcsncpy(szWordFound, (TCHAR*)((DWORD)pbtWord->m_lpszWord + (DWORD)(pbtWord->m_fOwner ? 0 : &m_lpszBuff[0])), pbtWord->m_dwWordLen);
}
MessageBox(m_hWnd, szWordFound, L"Found...", MB_OK);
}
@@ -937,6 +945,10 @@
DWORD i = 0;
INT tag_pairs = 0;
DWORD dwOldEnd = m_dwBuffEnd;
+
+ if(m_dwBuffEnd != 0 && m_fPreRendered) // not a new buffer...
+ m_fAppended = TRUE;
+
if(!m_dwBuffSize){
m_dwBuffSize = BTEXT_BUFF_INC > dwSize ? BTEXT_BUFF_INC : dwSize;
m_lpszBuff = new TCHAR[m_dwBuffSize];
@@ -1002,6 +1014,13 @@
InvalidateRect(m_hWnd, NULL, TRUE);
return ::UpdateWindow(m_hWnd);
}
+BOOL SRTextView::CurrentPageFilled()
+{
+ HDC hdc = GetDC(m_hWnd);
+ PreRenderBuff(hdc);
+ ReleaseDC(m_hWnd, hdc);
+ return (m_BTLines.m_lppLinesLastWord[m_BTLines.m_dwLastLine]->m_lpPrevWord->m_rect.bottom - m_nTop) > (m_rect.bottom - m_rect.top);
+}
/*****************************************************************************
* SRTextWord *
*****************************************************************************/
Modified: trunk/src/SwordReader_GUI/SRTextView.h
===================================================================
--- trunk/src/SwordReader_GUI/SRTextView.h 2008-07-27 00:42:57 UTC (rev 157)
+++ trunk/src/SwordReader_GUI/SRTextView.h 2008-07-27 04:58:40 UTC (rev 158)
@@ -470,6 +470,13 @@
visible in the window.
*/
INT GetVerseNum();
+ //! Determines if the current buffer has filled the screen.
+ /*! This function is useful for knowing when there is enough text pre-rendered such
+ that it fills the screen. If the screen has been filled, we can load the rest of
+ our text in the background.
+ @return true if the current buffer has filled the viewable screen space.
+ */
+ BOOL CurrentPageFilled();
// Friend classes, not needed in Visual Studio 2005
// but needed in eVC 3
@@ -729,11 +736,19 @@
// If false then the entire buffer is pre-rendered, otherwise only
// the portion starting at m_dwWordIndex
BOOL m_fAppended;
- //! Where to start pre-rendering at if the flag m_fAppended is true.
- INT m_dwWordIndex;
static BOOL s_fRegistered;
+ // TODO : This takes a large amount of memory, but lookups are fast.
+ // make this into a hash table instead.
+ HFONT m_hFontCache[BTEXT_FONT_CACHE_MAX];
- HFONT m_hFontCache[BTEXT_FONT_CACHE_MAX];
+ // The following are used to remember pre-rendering status.
+ RenderState m_rsState;
+ INT m_nLineX;
+ INT m_nLineY;
+ DWORD m_dwLineNum;
+ //! Where to start pre-rendering at if the flag m_fAppended is true.
+ DWORD m_dwWordIndex;
+
};
More information about the sword-cvs
mailing list