3gppttstructs.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,345 行 · 第 1/3 页
CPP
1,345 行
if(FAILED(hr))
{
HX_ASSERT(false);
break;
}
// we should consume the box data size exactly
HX_ASSERT( UINT32(pData - box.GetData()) == box.GetDataSize());
// /If we found one, then use it if it's lowest so far:
if (curEndCharOffset <
uiLowestPotentialNextTCStartOffsetFound &&
// /Ignore if end is prior to our start:
// /(Changed '>=' to '>' to prevent infinite loop)
curEndCharOffset > m_uiUnpackedStartCharOffset)
{
uiLowestPotentialNextTCStartOffsetFound =
curEndCharOffset;
}
}
if(SUCCEEDED(hr))
{
// we should always end up exactly at end of data
HX_ASSERT(pData == pDataEnd);
// /OK, our end char offset is one less than the lowest start
// of the next T.C. found, above, (& not less than our start):
HX_ASSERT(uiLowestPotentialNextTCStartOffsetFound > 0);
if (HX_3GPPTT_MAX_CHAR_OFFSET !=
uiLowestPotentialNextTCStartOffsetFound)
{
// /Don't add 1 here; it's end-point exclusive:
m_uiUnpackedEndCharOffset = uiLowestPotentialNextTCStartOffsetFound;
}
else
{
m_uiUnpackedEndCharOffset = HX_3GPPTT_MAX_CHAR_OFFSET;
}
}
return hr;
}
HX_RESULT C3GPPTextContainer::Init
(
IHXPacket* pPacket,
UINT32 ulPacketContentsBeginTime,
UINT32 ulMaxEndTime,
UINT16 uiStartCharOffset,
/*OUT*/ UINT16& uiREFIndexOfLastChar)
{
HX_RESULT hxr = HXR_OK;
HX_ASSERT(pPacket);
m_pPacket = pPacket;
m_pPacket->AddRef();
m_ulEndTime = ulMaxEndTime; // /Initialize for now to this
m_ulBeginTime = ulPacketContentsBeginTime;
m_uiUnpackedStartCharOffset = uiStartCharOffset;
uiREFIndexOfLastChar = HX_3GPPTT_INVALID_INDEX;
BOOL bNeedToBreakTCsUpAtNewlines = FALSE;
// /Go through the textModifiers of the packet and figure out what our
// end index is in the text buffer based on where the end of same-
// attributed continguous text ends. Return the end index in
// uiREFIndexOfLastChar so, if there's any text remaining, another
// C3GPPTextContainer can be created knowing where to start:
//-----------------------------------------------------------------------------
IHXBuffer* pBuff = m_pPacket->GetBuffer();
if (pBuff)
{
BOOL bTextIsUTF16ReverseEncoded = FALSE;
BOOL bTextIsUTF16Encoded = FALSE;
m_pTextSample = new C3GPPTextSample(pBuff);
HX_ASSERT(m_pTextSample);
if (!m_pTextSample)
{
hxr = HXR_OUTOFMEMORY;
goto cleanup;
}
bTextIsUTF16Encoded = IsUTF16Encoded(
(UCHAR*)(m_pTextSample->GetText()),
m_pTextSample->GetTextLenInBytes(),
bTextIsUTF16ReverseEncoded);
hxr = BuildSampleModifiers(bNeedToBreakTCsUpAtNewlines);
if(FAILED(hxr))
{
goto cleanup;
}
// /XXXEH- TODO: this is not UTF-8 friendly code (when 2-byte
// \000r or \000n chars are present)! Also, \r or \n may be 2nd
// byte of a 2-byte value and not meant as a newline (CR or LF,
// respectively) char!
// /Before patting ourselves on the back for finding the start &
// end offsets of this text container, we need to look for
// newline characters and break up TC's at each new-line
// character, but only if m_pTextSample->m_pTextModifiers exists
// and modified individual parts of the text and not just the
// entire thing, e.g., as 'tbox' does. Otherwise it's OK to
// leave entire packet's text as one TextContainer even if it
// has newline chars:
// /Note: these are the supported UNICODE text wrap controls:
// \u000a (LF)
// \u000d (CR)
// \u000d\u000a (CRLF)
// \u0085 (NEXT LINE)
// \u2028 (LINE SEP)
// \u2029 (PARA SEP)
#if defined(_SYMBIAN) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
// /Convert to UTF-16 then go through and start a new
// TextContainer wherever a newline char is found that
// does not immediately follow another newline:
HX_RESULT hxrsltCnvrtChars = HXR_OK;
HBufC16* pHBufUTF16Text = NULL;
HBufC8* pHBufUTF8Text = NULL;
const char* pUnconvertedText = m_pTextSample->GetText() + m_uiUnpackedStartCharOffset;
INT32 lUnconvertedTextLen = (INT32)
((UINT32)GetTextByteLength());
HX_ASSERT(m_uiUnpackedEndCharOffset >= (UINT32)lUnconvertedTextLen);
BOOL bDummyVar = FALSE;
BOOL bTextContainerTextStartsWithUTF16EncodeFlag =
IsUTF16Encoded((UCHAR*)pUnconvertedText,
lUnconvertedTextLen,
bDummyVar);
INT32 lTextLenInChars = lUnconvertedTextLen;
if (bTextIsUTF16Encoded)
{
HX_ASSERT(!(lTextLenInChars & 0x1)); // /Shouldn't be odd
lTextLenInChars >>= 1; // /Divide by 2: 2 bytes/char
if (bTextContainerTextStartsWithUTF16EncodeFlag)
{
// /Skip past 0xfffe UTF-16 flag at start:
pUnconvertedText += 2;
lTextLenInChars--;
}
}
if (hxrsltCnvrtChars==HXR_OK && pUnconvertedText &&
lUnconvertedTextLen > 0)
{
pHBufUTF16Text = HBufC16::NewMax((TInt)lTextLenInChars);
if (pHBufUTF16Text)
{
TInt tiNumLinesOfText = 1;
// /UTF-8 to UTF-16 translation:
if (bTextIsUTF16Encoded)
{
TInt leadByteOffset = 0;
TInt trailingByteOffset = 1;
if (bTextIsUTF16ReverseEncoded)
{
leadByteOffset = 1;
trailingByteOffset = 0;
}
for (TInt i = 0; i < (TInt)lTextLenInChars ; i++)
{
pHBufUTF16Text->Des()[i] =
((UINT16)(pUnconvertedText[
(i*2)+leadByteOffset])) <<8 |
pUnconvertedText[
(i*2)+trailingByteOffset];
}
}
else
{
pHBufUTF8Text = HBufC8::NewMax((TInt)lTextLenInChars);
for (TInt i = 0; i < (TInt)lTextLenInChars ; i++)
{
pHBufUTF8Text->Des()[i] =
(UINT8)(pUnconvertedText[i]);
}
TInt kErr =
CnvUtfConverter::ConvertToUnicodeFromUtf8(
pHBufUTF16Text->Des(),
pHBufUTF8Text->Des() );
delete pHBufUTF8Text;
}
// /Now step through UTF-16 chars in pHBufUTF16Text:
const TInt iStrLen16 = pHBufUTF16Text->Length();
HX_ASSERT(iStrLen16);
if (iStrLen16)
{
TInt tiChars = 0;
TInt tiNewlines = 0;
UINT16 ch16 =
pHBufUTF16Text->Des()[tiChars];
BOOL bPriorCharWasCarriageReturn = FALSE;
BOOL bCurCharIsCarriageReturn = FALSE;
BOOL bCurCharIsAtomicNewline = FALSE;
// /First, skip newline chars at the start:
while (tiChars < iStrLen16 &&
isUTF16NewlineChar(ch16,
bPriorCharWasCarriageReturn,
/*REF*/ bCurCharIsCarriageReturn,
/*REF*/ bCurCharIsAtomicNewline) )
{
tiChars++;
// /If it's not LF of CRLF, then ++ newlines:
if (bCurCharIsAtomicNewline)
{
tiNewlines++;
}
if (tiChars >= iStrLen16)
{
break;
}
ch16 = pHBufUTF16Text->Des()[tiChars];
bPriorCharWasCarriageReturn =
bCurCharIsCarriageReturn;
}
m_lNumUTF16NewlinesAtStart = (INT16)tiNewlines;
m_lNumUTF16NewlineCharsAtStart = (INT16)tiChars;
// /Next, find any newline chars in the middle:
bPriorCharWasCarriageReturn = FALSE;
while (tiChars < iStrLen16)
{
ch16 = pHBufUTF16Text->Des()[tiChars];
if (isUTF16NewlineChar(ch16,
bPriorCharWasCarriageReturn,
/*REF*/ bCurCharIsCarriageReturn,
/*REF*/ bCurCharIsAtomicNewline))
{
// /Start a new TextContainer at this
// newline char:
m_uiUnpackedEndCharOffset = tiChars +
// /Add offset to get it back into
// proper coords:
m_uiUnpackedStartCharOffset;
break;
}
bPriorCharWasCarriageReturn =
bCurCharIsCarriageReturn;
tiChars++;
}
}
}
}
#else // / else not _SYMBIAN ------------------------------------
if (bNeedToBreakTCsUpAtNewlines)
{
const char* pTextOfThis = m_pTextSample->GetText() + m_uiUnpackedStartCharOffset;
HX_ASSERT(pTextOfThis); // /Asserted? notify ehodge@real.com w/.3gp content
if (pTextOfThis)
{
UINT16 uiLen = GetTextByteLength();
#pragma message("&&&& XXXEH- 20031027- check for UTF8 or UTF16; if 16, step by 2's. If 8... &&&&")
BOOL bIsReverseUTF16 = FALSE;
BOOL bIsUTF16 = IsUTF16Encoded(pTextOfThis,
(INT32)uiLen, bIsReverseUTF16);
const UCHAR* pStepper = pTextOfThis;
// /First, skip newline chars at the start:
while (('\r' == *pStepper || '\n' == *pStepper) &&
pStepper < pTextOfThis + uiLen)
{
pStepper++;
}
// /Next, find any newline chars in the middle:
do
{
if ('\r' == *pStepper || '\n' == *pStepper)
{
// /Start a new TextContainer at this newline char:
m_uiUnpackedEndCharOffset = pStepper - pTextOfThis +
// /Need offset to get back into proper coords:
m_uiUnpackedStartCharOffset;
break;
}
} while (++pStepper < pTextOfThis + uiLen);
}
}
#endif // /if _SYMBIAN else... _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
}
//-----------------------------------------------------------------------------
cleanup:
uiREFIndexOfLastChar = m_uiUnpackedEndCharOffset;
return hxr;
}
C3GPPTextContainer::C3GPPTextContainer()
: m_pPacket(NULL)
, m_pTextSample(NULL)
, m_uiUnpackedStartCharOffset(HX_3GPPTT_INVALID_INDEX)
, m_uiUnpackedEndCharOffset(HX_3GPPTT_INVALID_INDEX)
, m_uiTextStyleBoxIndex(HX_3GPPTT_INVALID_INDEX)
, m_uiTextKaraokeBoxIndex(HX_3GPPTT_INVALID_INDEX)
, m_pTextStyleBox(NULL)
, m_pTextHighlightBox(NULL)
, m_pTextHilightColorBox(NULL)
, m_pTextKaraokeBox(NULL)
, m_pTextScrollDelayBox(NULL)
, m_pTextHyperTextBox(NULL)
, m_pTextboxBox(NULL)
, m_pTextBlinkBox(NULL)
, m_ulBeginTime(HX_3GPPTT_INVALID_TIME)
, m_ulEndTime(HX_3GPPTT_INVALID_TIME)
, m_ulNextDrawUpdateTimeOffset(0)
, m_ulPrevDrawUpdateTimeOffset(HX_3GPPTT_INVALID_TIME)
, m_lNumUTF16NewlineCharsAtStart(HX_3GPPTT_INVALID_INT16)
, m_lNumUTF16NewlinesAtStart(HX_3GPPTT_INVALID_INT16)
{
m_BoundingRectOfInitialDraw.left = m_BoundingRectOfInitialDraw.right = 0;
m_BoundingRectOfInitialDraw.top = m_BoundingRectOfInitialDraw.bottom = 0;
}
C3GPPTextContainer::~C3GPPTextContainer()
{
HX_RELEASE(m_pPacket);
HX_DELETE(m_pTextSample);
HX_DELETE(m_pTextStyleBox);
HX_DELETE(m_pTextHighlightBox);
HX_DELETE(m_pTextHilightColorBox);
HX_DELETE(m_pTextKaraokeBox);
HX_DELETE(m_pTextScrollDelayBox);
HX_DELETE(m_pTextHyperTextBox);
HX_DELETE(m_pTextboxBox);
HX_DELETE(m_pTextBlinkBox);
}
BOOL
C3GPPTextContainer::ContainsPoint(INT16 iX, INT16 iY) const
{
return ( iX >= m_BoundingRectOfInitialDraw.left &&
iX <= m_BoundingRectOfInitialDraw.right &&
iY >= m_BoundingRectOfInitialDraw.top &&
iY <= m_BoundingRectOfInitialDraw.bottom);
}
HX_RESULT
C3GPPTextContainer::UpdateLowestPotentialNextTCStartOffset(
UINT16 uiCurStartCharOffset, UINT16 uiCurEndCharOffset,
UINT16& /*REF IN-&-OUT*/ uiLowestPotentialNextTCStartOffsetFound,
BOOL& /*REF OUT*/ bAssignBoxToCurrent)
{
bAssignBoxToCurrent = FALSE; // /Initialize.
// /Error if start is after end or even if they are equal since indices
// are end-point exclusive:
if (uiCurStartCharOffset >= uiCurEndCharOffset)
{
// /Don't bother asserting; it's a bad test file (3GPPtext-e-06-00.3gp)
return HXR_UNEXPECTED; // /BAD DATA!
}
// /To avoid crash @ draw time w/corrupt data, make sure these don't
// exceed the complete buffer's size:
if (uiCurStartCharOffset > m_pTextSample->GetTextLenInBytes() ||
uiCurEndCharOffset > m_pTextSample->GetTextLenInBytes())
{
HX_ASSERT(uiCurStartCharOffset > m_pTextSample->GetTextLenInBytes());
HX_ASSERT(uiCurEndCharOffset > m_pTextSample->GetTextLenInBytes());
return HXR_UNEXPECTED; // /Ignore this entry.
}
if (m_uiUnpackedStartCharOffset >= uiCurStartCharOffset &&
uiCurEndCharOffset > // /(end-pt exclusive)
m_uiUnpackedStartCharOffset)
{
bAssignBoxToCurrent = TRUE; // /this's begin is within current range
HX_ASSERT(uiLowestPotentialNextTCStartOffsetFound >= uiCurEndCharOffset);
if (uiLowestPotentialNextTCStartOffsetFound > uiCurEndCharOffset)
{
// /Don't add 1 here; it's end-point exclusive:
uiLowestPotentialNextTCStartOffsetFound = uiCurEndCharOffset;
}
}
// /Use start as potential end if lowest so far:
else if (uiCurStartCharOffset < uiLowestPotentialNextTCStartOffsetFound &&
// /Ignore if prior to our start:
uiCurStartCharOffset >= m_uiUnpackedStartCharOffset)
{
uiLowestPotentialNextTCStartOffsetFound = uiCurStartCharOffset;
// /I think the logic of the if(), above,
// handles this but I'm too lazy to check:
HX_ASSERT(0 != uiLowestPotentialNextTCStartOffsetFound);
}
return HXR_OK;
}
UINT32
C3GPPTextContainer::GetNextActivityTime() const
{
UINT32 ulBegin = GetBeginTime();
if (HX_3GPPTT_INVALID_TIME == ulBegin)
{
return ulBegin;
}
return (m_ulNextDrawUpdateTimeOffset + ulBegin);
}
UINT32
C3GPPTextContainer::GetPrevActivityTime() const
{
UINT32 ulBegin = GetBeginTime();
if (HX_3GPPTT_INVALID_TIME == ulBegin ||
HX_3GPPTT_INVALID_TIME == m_ulPrevDrawUpdateTimeOffset)
{
return HX_3GPPTT_INVALID_TIME;
}
return (m_ulPrevDrawUpdateTimeOffset + ulBegin);
}
void
C3GPPTextContainer::SetPrevActivityTime(UINT32 ulAbsoluteTime)
{
UINT32 ulBegin = GetBeginTime();
if (HX_3GPPTT_INVALID_TIME == ulBegin || ulBegin > ulAbsoluteTime)
{
m_ulPrevDrawUpdateTimeOffset = HX_3GPPTT_INVALID_TIME;
}
else
{
m_ulPrevDrawUpdateTimeOffset = ulAbsoluteTime - ulBegin;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?