[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