📄 textprsr.cpp
字号:
lTmpTextLen++; pTmpText--; break; } pTmpText++; lTmpTextLen--; }while(lTmpTextLen); if(lTmpTextLen) { //then we encountered a double-byte char or a // space, tab, or newline char, so ok to wordwrap // here: theFollowingSpaceCharIndex = tempLen-lTmpTextLen; savedChar=pCurText[theFollowingSpaceCharIndex+1]; pCurText[theFollowingSpaceCharIndex+1] = '\0'; } } } else //This is SBCS: { ULONG32 firstNonSpaceCharIndex = skipSpacesTabsAndNewlineChars( pCurText, tempLen, 0); ULONG32 dummyVar; if(firstNonSpaceCharIndex < (ULONG32)tempLen) { theFollowingSpaceCharIndex = findNextSpaceTabOrNewLineChar( pCurText, tempLen, firstNonSpaceCharIndex, dummyVar, ulCurCharset); if(theFollowingSpaceCharIndex+1 < (ULONG32)tempLen) { savedChar = pCurText[theFollowingSpaceCharIndex+1]; pCurText[theFollowingSpaceCharIndex+1] = '\0'; } } } } //C_RTRNDRDIFF >>: //Added the following to keep track of where // in the buffer the TextContainer's data starts: ULONG32 ulTextContainerBufStartIndex = tmpStartIndex; //<< END C_RTRNDRDIFF. if(!bPreTabOrNewlineCharOnly) { //Now, look for "<" or ">" and, if found, end the // TextContainer at the end of the "<" or ">" & replace // it with '<' or '>'; also, look for "&#n;" // (where n>8 && n<=255) and translate into the ASCII char // with that value, and look for " " for ' ' and "&" // for '&': ULONG32 ulIndexOfAmpersand = findNextChar('&', pCurText, theFollowingSpaceCharIndex, 0L, ulCurCharset); ULONG32 ulIndexOfLastCharInTCsBuf=theFollowingSpaceCharIndex; ULONG32 theOriginalFollowingSpaceCharIndex = theFollowingSpaceCharIndex; if(theFollowingSpaceCharIndex > ulIndexOfAmpersand && theFollowingSpaceCharIndex - ulIndexOfAmpersand >= 4) { FindEscapeSequenceChar(pCurText, ulIndexOfLastCharInTCsBuf, theFollowingSpaceCharIndex, ulIndexOfAmpersand, ulCurCharset); } //Create a new one and add it to the list: pTC = new TextContainer(pCurText, ulIndexOfLastCharInTCsBuf+1>(ULONG32)tempLen? (ULONG32)tempLen:ulIndexOfLastCharInTCsBuf+1); //First, restore pData_CHAR: if(theOriginalFollowingSpaceCharIndex+1 < (ULONG32)tempLen) { pCurText[theOriginalFollowingSpaceCharIndex+1] = savedChar; } //then, reset tempLen and tmpStartIndex: { tempLen -= theFollowingSpaceCharIndex+1; tmpStartIndex += theFollowingSpaceCharIndex+1; } } else //is a tab char inside PRE so send a space char: { //Create a new one and add it to the list: pTC = new TextContainer(" ", 1); bPreTabOrNewlineCharOnly = FALSE; //so while loop will quit. } HX_ASSERT(pTC); if(!pTC) { //C_RTRNDRDIFF: (different due to return type) return HXR_OUTOFMEMORY;//mem alloc error, so quit } pTC->setNumNewlinesAtStart( m_pTextWindow->getNumBreakTagsEncountered()); m_pTextWindow->clearNumBreakTagsEncountered(); //This has to be kept track of because insertAtEndOfList(), // below, resets m_bClearWasJustSent to FALSE: BOOL bClearWasJustSent = m_pTextWindow->m_bClearWasJustSent; BOOL bStopRenderingTimeIsMoreRecent = IsTimeAMoreRecentThanTimeB( m_pTextWindow->GetLatestSentTimeToStopRendering(), m_pTextWindow->GetLatestSentTimeToRender(), bIsLiveSource); //Reset the current endtime so all text // that follows a <CLEAR> has an endtime equal to that of // the end of the stream: if(bClearWasJustSent //This fixes a bug where the author wanted something // to end at a certain time after the <CLEAR> but // couldn't without a <time> tag after the <CLEAR>, // e.g., "<time start=10 end=20><CLEAR>foo" should // behave as follows: foo appears at 10 seconds and // goes away at 20; however: // "<time end=10>blah <time start=10><CLEAR>foo" should // have blah appear up to 10 seconds and foo appear from // 10 seconds until the end of the stream (or until the // next CLEAR tag's start time). && !bStopRenderingTimeIsMoreRecent) { //If liveSource, start time of stream may not be at time 0 // and ULONG_MAX may be *earlier* than cur time (since time // val is ULONG32 and may wrap); we want to set this to // "infinity" (which is 0xfffffffe): m_pTextWindow->SetLatestSentTimeToStopRendering( (ULONG32)ULONG_MAX); if(bIsLiveSource) { m_pTextWindow->SetLatestSentTimeToStopRendering( TIME_INFINITY); if(TIME_INVALID == m_pTextWindow-> GetLatestSentTimeToStopRendering()) { m_pTextWindow->SetLatestSentTimeToStopRendering(1L); } } } //Set begin and end render times of this new TextContainer // to the begin/end values of the most recent <TIME ..> tag: pTC->setBeginTime( m_pTextWindow->GetLatestSentTimeToRender() - lTimeOffset); //cz pTC->setEndTime( m_pTextWindow->GetLatestSentTimeToStopRendering() - lTimeOffset); //cz //C_RTRNDRDIFF >> //This is needed at the file format end because we need to keep // track of when the last <TIME ... end=t> was seen so we can // send it in the packet's opaque-data header: pTC->setMostRecentTimeTagEndTime(pTC->getEndTime()); //<< END C_RTRNDRDIFF. if(m_pTextWindow->hasValidURL()) { pTC->copyIntoHrefBuf(m_pTextWindow->getURL(), m_pTextWindow->getLenURLbuf(), m_pTextWindow->getTargetOfURL() ); //C_RTRNDRDIFF >> ULONG32 ulNumOverrides = m_pTextWindow-> getNumberOfFontColorPushesInsideLinkText(); if(ulNumOverrides > 0) { pTC->setNumLinkColorOverrides(ulNumOverrides); } //<< END C_RTRNDRDIFF. } m_pTextWindow->setTextAttributesToTopsOfStacksVals(*pTC); if(bDealingWithTabCharWithPre && !bSomeCharsFoundSinceLastBreakTag) { //If all we've got is a tab char in the TC, don't // paint any bg color: pTC->setTextBackgroundColor(DEFAULT_TEXT_BGCOLOR); } bUserPosTagFoundSinceLastTextContainer = FALSE; if(!m_pTextWindow->insertAtEndOfList(pTC, //C_RTRNDRDIFF: !bFileFormatIsCallingThis, bDealingWithTabCharWithPre)) { delete pTC; } else { //C_RTRNDRDIFF >> if(pTC->isRequired()) { bRef_DataHasREQUIREDContents = bCurLineHasREQUIREDContents = TRUE; } //<< END C_RTRNDRDIFF. //Added this to adjust start & end times // based on visibility in window, e.g., the start time of // pTC might be 0 but it doesn't scroll into the window // until 4300msec, so this calculates and adjusts to that: BOOL bShouldNeverBeFalse = pTC->adjustStartAndEndTimes(m_pTextWindow); HX_ASSERT(bShouldNeverBeFalse); if(m_pTextWindow->isLooping()) { //We don't want to use the end time calculated in // adjustStartAndEndTimes() above because looping means // the end time may be "infinite" since it could loop // "forever"; however, if there is an active <TIME end=t> // tag, use t instead of "infinity". // NOTE: as soon as another CLEAR tag is seen, this // T.C.'s endTime will be reset to time of the CLEAR: pTC->setEndTime(m_pTextWindow-> GetLatestSentTimeToStopRendering()); } //C_RTRNDRDIFF >> if(TYPE_TELEPROMPTER == m_pTextWindow->getType()) { //XXXEH-* need a better fix for this!: //We want to give each line a maximum lifetime of 90sec // so that, when a T.C. moves up and out of the window, // it doesn't persist as time-valid (and consequently // persist in the live packet-resend queue or in the // file format's list of what to send after a seek). // Setting its end time to the time this T.C. is "bumped" // out of the window is tricky and this 90second-duration // hack "solves" the problem for now but this needs to // be rivisited: if(pTC->getEndTime() - pTC->getStartTime() > 90000) { pTC->setEndTime(pTC->getStartTime() + 90000); } } //<< END C_RTRNDRDIFF. if(bIsLiveSource && TIME_INVALID == pTC->getEndTime()) { //Make end time be "infinity": pTC->setEndTime(TIME_INFINITY); } //Moved this from below "CLEAR" parsing // code so that the adjustment would be made after the pTC's // official start time is known: if(bClearWasJustSent) { ULONG32 ulTmpStartTime = pTC->getStartTime(); ULONG32 ulTmpEndTime = pTC->getEndTime(); m_pTextWindow->SetLatestSentTimeToRender(ulTmpStartTime); // is just after a <CLEAR> tag, so clear everything in // TextContainerList whose m_endTime is greater // than the latestSentTimeToRender: m_pTextWindow->MarkAllForClear( //(the T.C.List version) bIsLiveSource); //Now, since pTC is already inserted in the T.C.List, its // endTime may have been adjusted in MarkAllForClear(), // so let's restore it: pTC->setStartTime(ulTmpStartTime); pTC->setEndTime(ulTmpEndTime); //C_RTRNDRDIFF >>: //Now call the T.L.List version of MarkAllForClear() and // make sure the TextLines all have the correct end times // otherwise a player Seek() may result in time-dead data // being sent over the wire and immediately discarded by // the renderer://#error:XXXXXEH- put bp here & see why not for renderer: m_pTextWindow->m_pTLList->MarkAllForClear( m_pTextWindow->GetLatestSentTimeToRender(), bIsLiveSource); //<< END C_RTRNDRDIFF. m_pTextWindow->setTimeOfLastClearTag(); //follows a CLEAR tag but has no "newlines" before it, // so we can't set num newlines to non-zero, so this // tells us we've started a newline with no prior spacing pTC->isFakeNewLine(TRUE); } //C_RTRNDRDIFF >>: TextLine* pTL_prev = m_pTextWindow->m_pTLList->end(); // Added the following code to create a new TextLine if pTC // is start of new line, or to update the latest TextLine in // the list if pTC is not the start of a new line: if(pTC->isStartOfNewLine() || pTC->isFakeNewLine() || //Added this because sometimes a TextLine gets split // into two based on where the read() into the file // ends and the next read() begins, so, if we haven't // found a TL yet, make this the first one in the // next packet (and don't append it to the existing // pTL_prev even though it may be part of the same // line): !bFirstTLwasFound || !pTL_prev) //Bug #708 killer; the // very first TextLine was not being // created if it didn't start a newline. { ulCurLineStartByteNumOfFile = ulByteOffsetIntoFile + ulTextContainerBufStartIndex; //if prev exsits, end it just before the new one starts: if(pTL_prev) { pTL_prev->setEndByteInFile( ulCurLineStartByteNumOfFile-1); } pTL = new TextLine((TextLine&)(*pTC)); HX_ASSERT_VALID_PTR(pTL); if(NULL == pTL) { break; //Houston, We've had a problem. } //Do this so that the memcopied // TextAttributes part of pTC did not copy the ptr to the // href buffer into pTL's TextAttributes part: pTL->clearWithoutDeletingHrefBuf(); if(pTC->getHrefBuf() && pTC->getHrefBufLen()) { pTL->copyIntoHrefBuf(pTC->getHrefBuf(), pTC->getHrefBufLen(), pTC->getTargetOfURL()); } pTL->setLineNumOfFile( m_pTextWindow->m_pTLList->nodeCount()+1); pTL->setStartByteInFile(ulCurLineStartByteNumOfFile); pTL->setEndByteInFile(0L); pTL->setTimeOfLastClear( m_pTextWindow->getTimeOfLastClearTag()); if(!m_pTextWindow->m_pTLList->insertAtEndOfList(pTL)) { delete pTL; //insert failed so kill it. } else //posible core dump without this else!!! if(pTL->getStartByteInFile() < ulStartByteOfFirstTL || !bFirstTLwasFound) { *ppFirstTextLineInPkt = pTL; ulStartByteOfFirstTL = pTL->getStartByteInFile(); bFirstTLwasFound = TRUE; } //Make sure the current TextLine is considered // <REQUIRED> to be sent if any of it's text is // set as <REQUIRED>: if(bCurLineHasREQUIREDContents) { pTL->isRequired(TRUE); } } else { //update the (current) TextLine's times because this // new pTC is part of the current TextLine (pTL_prev): if(pTL_prev) { pTL_prev->updateStartAndEndTimes(pTC, bIsLiveSource); //Make sure the current TextLine is considered // <REQUIRED> to be sent if any of it's text is // set as <REQUIRED>: if(bCurLineHasREQUIREDContents) { pTL_prev->isRequired(TRUE); } } } BOOL bEarliestTimeOfNewDataIsMoreRecent = IsTimeAMoreRecentThanTimeB( ulEarliestTimeOfNewData, pTC->getStartTime(), bIsLiveSource); //So ff can know next packet's time: if(bEarliestTimeOfNewDataIsMoreRecent || !bEarliestTimeOfNewDataIsValid) { ulEarliestTimeOfNewData = pTC->getStartTime(); bEarliestTimeOfNewDataIsValid = TRUE; } BOOL bGetEndTimeIsMoreRecent = IsTimeAMoreRecentThanTimeB( pTC->getEndTime(), ulEndTimeOfPacket, bIsLiveSource); if(TIME_INVALID == ulEndTimeOfPacket) { //(in)sanity check: Is the first time it's been used: HX_ASSERT(!bGetEndTimeIsMoreRecent); } //So ff can know next packet's end time // so it can decide whether it's too late to send the packet: if(bGetEndTimeIsMoreRecent || (ULONG32)TIME_INVALID==ulEndTimeOfPacket) { ulEndTimeOfPacket = pTC->getEndTime(); } } //<< END C_RTRNDRDIFF.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -