3gppttrenderer.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:167k
- INT32 iCharsToSkipOver = 0;
- INT32 iNumLinesOfTextAtStart = 0;
- #endif
- // /To fix it so boxes aren't drawn where newlines are,
- // skip past newlines which can only exist at the start
- // of this T.C. (fixes Helix Issue 840):
- if (HX_3GPPTT_INVALID_INT16 !=
- pTextContainer->m_lNumUTF16NewlineCharsAtStart &&
- pTextContainer->m_lNumUTF16NewlineCharsAtStart > 0)
- {
- iCharsToSkipOver =
- pTextContainer->m_lNumUTF16NewlineCharsAtStart;
- iNumLinesOfTextAtStart =
- pTextContainer->m_lNumUTF16NewlinesAtStart;
- if (HX_3GPPTT_INVALID_INT16 ==
- pTextContainer->m_lNumUTF16NewlinesAtStart)
- {
- iNumLinesOfTextAtStart = iCharsToSkipOver;
- }
- if (iCharsToSkipOver > lTextLenInChars)
- {
- HX_ASSERT(0); // /Shouldn't get here.
- // /"handle" this exception:
- iCharsToSkipOver = lTextLenInChars;
- }
- // /Reduce text len to = # chars to be rendered:
- lTextLenInChars -= (INT16)iCharsToSkipOver;
- }
- #if defined(_WINDOWS) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- RECT RECTDrawRect;
- RECTDrawRect.left = drawRect.left;
- RECTDrawRect.top = drawRect.top;
- RECTDrawRect.right = drawRect.right;
- RECTDrawRect.bottom = drawRect.bottom;
- // /Call DrawText to get bounding rect. (This call
- // doesn't perform a draw):
- DrawText(hDC,
- // /XXXEH- todo: handle wide chars (UTF-8, 16):
- LPSTR(pConvertedText),
- lConvertedTextLen,
- &RECTDrawRect,
- // /XXXEH- todo: finish text format (handle r-to-l):
- // DT_NOCLIP | DT_VCENTER , DT_BOTTOM , DT_TOP v-alignment |
- // DT_WORDBREAK<--NO!!We don't want auto wordwrap!! |
- // DT_CENTER/DT_RIGHT/DT_LEFT h-alignment,
- // bidi (r-to-l) (| DT_RTLREADING):
- ulTextFormatFlags | DT_CALCRECT
- // /Note; we could use DrawTextEX with a 6th parameter,
- // DRAWTEXTPARAMS, if we want to set tab stops, ...etc:
- );
- pTextContainer->m_BoundingRectOfInitialDraw.left =
- RECTDrawRect.left;
- pTextContainer->m_BoundingRectOfInitialDraw.top =
- RECTDrawRect.top;
- pTextContainer->m_BoundingRectOfInitialDraw.right =
- RECTDrawRect.right;
- pTextContainer->m_BoundingRectOfInitialDraw.bottom =
- RECTDrawRect.bottom;
- #if defined(XXXEH_DEBUGOUT_DRAW_3GPPTT)
- pFile = fopen("c:\3gppttdrawPos.txt", ulCount?"a+":"w");
- if (pFile)
- {
- char* pContents = new char[lConvertedTextLen + 1];
- pContents[lConvertedTextLen] = ' ';
- strncpy(pContents, pConvertedText, lConvertedTextLen);
- fprintf(pFile, "Drawing {{{%s}}} at time %lu at location: (%ld,%ld), "
- "m_pTextContainerListFutureTimePos=%pn", pContents,
- m_ulTimeOfLastTimeSync, drawRect.left, drawRect.top,
- m_pTextContainerListFutureTimePos);
- fclose(pFile);
- delete [] pContents;
- }
- ulCount++;
- #endif // /XXXEH_DEBUGOUT_DRAW_3GPPTT.
- // /Reset bounding rect and do actual draw w/out DT_CALCRECT:
- RECTDrawRect.left = drawRect.left;
- RECTDrawRect.top = drawRect.top;
- RECTDrawRect.right = drawRect.right;
- RECTDrawRect.bottom = drawRect.bottom;
- #if defined(XXXEH_SCROLLING_TRY1_BUT_BUG_IN_CORE)
- #else
- RECTDrawRect.left += lXScrollOffset;
- RECTDrawRect.top += lYScrollOffset;
- if (1==ulTextContainersHandled && scrollDirNone != scrolldir)
- {
- // /XXXEH- inefficient but this is a work-around until core
- // bug is fixed:
- FillRectangle(ulBgColorARGB);
- }
- #endif // /End else of defined(XXXEH_SCROLLING_TRY1_BUT_BUG_IN_CORE)
- // /lTextLenInChars can be 0 if T.C.'s text is 100%
- // newline chars, so (obviously) don't draw in that case:
- if (lTextLenInChars > 0)
- {
- UINT32 ulHeightOfTextOutput =
- DrawText(hDC,
- // /XXXEH- todo: handle wide chars (UTF-8, 16):
- LPSTR(pConvertedText),
- lConvertedTextLen,
- &RECTDrawRect,
- // /XXXEH- finish text format (handle r-to-l):
- // DT_NOCLIP | DT_VCENTER , DT_BOTTOM , DT_TOP v-alignment |
- // DT_WORDBREAK<--NO!!We don't want auto wordwrap!! |
- // DT_CENTER/DT_RIGHT/DT_LEFT h-alignment,
- // bidi (r-to-l) (| DT_RTLREADING):
- ulTextFormatFlags
- );
- }
- SetBkMode(hDC, bkModeOld);
- HX_VECTOR_DELETE(pConvertedText);
- #elif defined(_SYMBIAN) // / ------------------------------------
- pHBufUTF16Text = HBufC16::NewMax((TInt)lTextLenInChars);
- if (lTextLenInChars <= 0 && pHBufUTF16Text)
- {
- // /Skip drawing this TextContainer if it was all newlines:
- delete pHBufUTF16Text;
- pHBufUTF16Text = NULL;
- }
- // /Convert it if needed, then draw it:
- {
- TInt cxText = 0;
- if (pHBufUTF16Text)
- {
- // /UTF-8 to UTF-16 translation:
- if (bTextContainerTextIsUTF16Encoded)
- {
- TInt leadByteOffset = 0;
- TInt trailingByteOffset = 1;
- if (bTextContainerTextIsUTF16ReverseEncoded)
- {
- leadByteOffset = 1;
- trailingByteOffset = 0;
- }
- for (TInt i = 0; i < (TInt)lTextLenInChars ; i++)
- {
- pHBufUTF16Text->Des()[i] =
- ((UINT16)(pConvertedText[
- ((i + iCharsToSkipOver) * 2) +
- leadByteOffset])) << 8 |
- pConvertedText[
- ((i + iCharsToSkipOver) * 2) +
- trailingByteOffset];
- }
- }
- else
- {
- pHBufUTF8Text = HBufC8::NewMax((TInt)
- lTextLenInChars);
- for (TInt i = 0; i < (TInt)lTextLenInChars ; i++)
- {
- pHBufUTF8Text->Des()[i] = (UINT8)
- (pConvertedText[i + iCharsToSkipOver]);
- }
- TInt kErr =
- CnvUtfConverter::ConvertToUnicodeFromUtf8(
- pHBufUTF16Text->Des(),
- pHBufUTF8Text->Des() );
- delete pHBufUTF8Text;
- }
- // /Get bounding rect (width of entire UTF-16 string):
- cxText = m_pFont->TextWidthInPixels(pHBufUTF16Text->Des());
- }
- TRect RECTDrawRect(0,0,1,1);
- RECTDrawRect.iTl.iX = drawRect.left;
- RECTDrawRect.iTl.iY = drawRect.top;
- RECTDrawRect.iBr.iX = drawRect.right;
- RECTDrawRect.iBr.iY = drawRect.bottom;
- #pragma message("----#### these will be wrong for bottom, h,v-centered, & right-aligned ####----")
- pTextContainer->m_BoundingRectOfInitialDraw.left =
- drawRect.left;
- pTextContainer->m_BoundingRectOfInitialDraw.top =
- drawRect.top;
- pTextContainer->m_BoundingRectOfInitialDraw.right =
- drawRect.left + cxText;
- #pragma message("----#### this will be wrong for text containing newline chars: ####----")
- pTextContainer->m_BoundingRectOfInitialDraw.bottom =
- drawRect.top + ulScaledHeight;
- #if defined(XXXEH_SCROLLING_TRY1_BUT_BUG_IN_CORE)
- #else
- RECTDrawRect.iTl.iX += lXScrollOffset;
- RECTDrawRect.iTl.iY += lYScrollOffset;
- // /Make sure we don't cut off bottom right:
- RECTDrawRect.iBr.iX += lXScrollOffset;
- RECTDrawRect.iBr.iY += lYScrollOffset;
- if (1==ulTextContainersHandled && scrollDirNone != scrolldir)
- {
- // /XXXEH- inefficient but this is a work-around until core
- // bug is fixed:
- FillRectangle(ulBgColorARGB);
- }
- #endif // /End else of defined(XXXEH_SCROLLING_TRY1_BUT_BUG_IN_CORE)
- CGraphicsContext::TTextAlign talignHoriz = CGraphicsContext::ELeft;
- if (HX_3GPPTT_JUSTIFY_HCENTER & ulTextFormatFlags)
- {
- talignHoriz = CGraphicsContext::ECenter;
- }
- else if (HX_3GPPTT_JUSTIFY_RIGHT & ulTextFormatFlags)
- {
- talignHoriz = CGraphicsContext::ERight;
- }
- // /Top aligned (by default):
- // /Baseline is relative to RECTDrawRect passed into
- // DrawText:
- TInt tiBaseline = m_pFont->AscentInPixels();
- if (ulTextFormatFlags & HX_3GPPTT_JUSTIFY_VCENTER)
- {
- // /Vertically centered:
- tiBaseline = ( (ulScaledHeight *
- iNumLinesOfTextAtStart) +
- RECTDrawRect.iBr.iY - RECTDrawRect.iTl.iY +
- m_pFont->AscentInPixels() ) / 2;
- }
- else if (ulTextFormatFlags & HX_3GPPTT_JUSTIFY_BOTTOM)
- {
- #pragma message("----#### need to test this with multi-line text: ####----")
- // /Justified to bottom:
- tiBaseline = RECTDrawRect.iBr.iY - ulScaledHeight +
- m_pFont->AscentInPixels();
- }
-
- // /void DrawText(const TDesC& aText,const TPoint& aPosition); // /Draws text without a surrounding box.
- // /void DrawText(const TDesC& aText,const TRect& aBox,TInt aBaselineOffset,TTextAlign aHrz=ELeft,TInt aMargin=0);
- // /void DrawText(const TDesC& aText); // /Draws text at the last print position
- m_pGCOffscreen->SetPenStyle(CGraphicsContext::ESolidPen);
- // /lTextLenInChars can be 0 if T.C.'s text is 100%
- // newline chars, so (obviously) don't draw in that case:
- if (lTextLenInChars > 0)
- {
- #define XXXEH_20031126_TESTING_HIGHLIGHTCOLORING_AREA_FIX 20031126
- #if defined(XXXEH_20031126_TESTING_HIGHLIGHTCOLORING_AREA_FIX)
- if (bHasHighlightColor)
- {
- // /XXXEH- fixes Symbian problems where highlighted
- // background area was too big. Further confine it to
- // top-left plus width,height of Text:
- if (talignHoriz == CGraphicsContext::ECenter ||
- talignHoriz == CGraphicsContext::ERight)
- {
- // /XXXEH- todo: rewrite horizontal alignment to do it
- // ourselves instead of letting OS do it:
- // /Need to rework all this code so color highlighting
- // will work. Unfortunately we have no way of knowing
- // where the OS places a phrase within a group of them
- // on the same line that are drawn in different TextOut
- // calls, so we can't know where to draw the rectangle
- // behind it (and, unlike on Windows, the API doesn't
- // highlight behind the text but rather behind the
- // bounding rectangle you specify. In order to specify
- // that, we need to know the exact location:
- // / HX_ASSERT(0);
- }
- else
- {
- RECTDrawRect.iBr.iX = drawRect.left + cxText + 1 +
- // /Adjust bounding box for horiz-scrolling:
- m_lXScrollOffset;
- }
- RECTDrawRect.iBr.iY = tiBaseline +
- // /Adjust bounding box for vertical-scrolling:
- m_lYScrollOffset +
- // /Allow for descenders:
- m_pFont->DescentInPixels();
- }
- #endif // /end XXXEH_20031126_TESTING_HIGHLIGHTCOLORING_AREA_FIX.
- m_pGCOffscreen->DrawText(
- pHBufUTF16Text->Des(),
- RECTDrawRect,
- tiBaseline,
- talignHoriz);
- }
- #if defined(_SYMBIAN) && defined(_DEBUG) // -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- //#define XXXEH_TEST_DRAWTEXT
- #if defined(XXXEH_TEST_DRAWTEXT)
- #pragma message("====##### Test code is active! Don't check it in enabled: ####----")
- // /If no text, draw a rect and see if it got drawn to the offscreen bitmap:
- {
- TSize tsz(5, 5);
- m_pGCOffscreen->SetPenSize(tsz);
- TRgb rgbBgColor = 0x7700FF;
- m_pGCOffscreen->SetBrushStyle(CGraphicsContext::ESolidBrush);
- m_pGCOffscreen->SetBrushColor(rgbBgColor);
- const TRect aRect(10,10,40,40);
- m_pGCOffscreen->DrawRect(aRect);
- }
- #endif // /XXXEH_TEST_DRAWTEXT.
- #endif // /_SYMBAIN && _DEBUG _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- delete pHBufUTF16Text;
- if (bHasHighlightColor)
- {
- // /Undo setting of brush for bgcolor:
- m_pGCOffscreen->SetBrushStyle(CGraphicsContext::ENullBrush);
- }
- }
- #else // /else of: #if defined _WINDOWS, #elif defined _SYMBIAN ------------------------------------
- #pragma message("====##### This OS needs code that draws text & sets TC bounding rect #####====")
- #endif // /end else of: _WINDOWS _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- }
- #if defined(XXXEH_DEBUGOUT_DRAW_3GPPTT)
- pFile = fopen("c:\3gppttdrawPos.txt", ulCount?"a+":"w");
- if (pFile)
- {
- char* pContents = new char[lConvertedTextLen + 1];
- pContents[lConvertedTextLen] = ' ';
- strncpy(pContents, pConvertedText, lConvertedTextLen);
- fprintf(pFile, "Drawing {{{%s}}} at time %lu at location: (%ld,%ld), "
- "m_pTextContainerListFutureTimePos=%pn", pContents,
- m_ulTimeOfLastTimeSync, drawRect.left, drawRect.top,
- m_pTextContainerListFutureTimePos);
- fclose(pFile);
- delete [] pContents;
- }
- ulCount++;
- #endif // /XXXEH_DEBUGOUT_DRAW_3GPPTT.
- liCursorX = pTextContainer->m_BoundingRectOfInitialDraw.right + 1;
- // /Note: don't update liCursorY; we'll calculate that when
- // processing the next T.C. w/its numNewlines (if any).
- pLastHandledTextSampleEntry = pCurTextSampleEntry;
- }
- // /If T.C. is not time-valid and it is from the main list and the
- // redraw list exists, we'll next go through the redraw list:
- else if (m_pTextContainerRedrawList &&
- bTextContainerIsFromMainList &&
- !bATextContainerFromMainListWasHandled)
- {
- // /None from main list so let's look in redraw list:
- bGetTextContainersFromRedrawList = TRUE;
- }
- else // /We've hit future ones, so stop:
- {
- #if defined(XXXEH_DEBUGOUT_DRAW_3GPPTT)
- pFile = fopen("c:\3gppttdrawPos.txt", ulCount?"a+":"w");
- if (pFile)
- {
- fprintf(pFile, "[step (FinishedWthTCsAtCurTime)] T.C. = %p at time %lu ("
- "text containers handled = %ld), m_pTextContainerListFutureTimePos=%pn",
- pTextContainer, m_ulTimeOfLastTimeSync, ulTextContainersHandled,
- m_pTextContainerListFutureTimePos);
- fclose(pFile);
- }
- ulCount++;
- #endif // /XXXEH_DEBUGOUT_DRAW_3GPPTT.
- bFinishedWithCurTimeTCs = TRUE;
- }
- } while (!bFinishedWithCurTimeTCs &&
- (m_pTextContainerListFutureTimePos ||
- !bTextContainerIsFromMainList) );
- //------------------- END TEXT PUT-GLYPHS-TO-cANVAS CODE. ----------
- } // /end: if (m_pDrawOutputBuffer &&...
- #if defined(XXXEH_DEBUGOUT_DRAW_3GPPTT)
- pFile = fopen("c:\3gppttdrawPos.txt", ulCount?"a+":"w");
- if (pFile)
- {
- fprintf(pFile, "[step (EXITED while loop)] T.C. = %p at time %lu, "
- "m_pTextContainerListFutureTimePos=%pn", pTextContainer,
- m_ulTimeOfLastTimeSync, m_pTextContainerListFutureTimePos);
- fclose(pFile);
- }
- ulCount++;
- #endif // /XXXEH_DEBUGOUT_DRAW_3GPPTT.
- if (m_pDrawOutputBuffer)
- {
- m_lXScrollOffset = lXScrollOffset;
- m_lYScrollOffset = lYScrollOffset;
- m_dScrollFactor = dScrollFactor;
- // /First see if we have a scroll offset:
- if ((lXScrollOffset || lYScrollOffset) && dScrollFactor > .5 &&
- pTextContainer &&
- HX_3GPPTT_INVALID_TIME == pTextContainer->GetPrevActivityTime())
- {
- m_bDrawInNonTextScrollArea = TRUE;
- }
- }
- else
- {
- hxrslt = HXR_UNEXPECTED;
- goto cleanup;
- }
- cleanup:
- return hxrslt;
- }
- /****************************************************************************
- * C3GPPTimedTextRenderer::Draw ref: 3gppttrender.h
- *
- */
- HX_RESULT
- C3GPPTimedTextRenderer::Draw(IHXVideoSurface *pVideoSurface)
- {
- HX_RESULT hxrslt = HXR_OK;
- SetDrawOutputBuffer();
- HX_ASSERT(m_pDrawOutputBuffer);
- if (m_pDrawOutputBuffer)
- {
- #if defined(USE_DIB_SECTION) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- HXBitmapInfoHeader* pBIHeader = (HXBitmapInfoHeader*)(&m_BITMAPINFOHEADER);
- #if defined(HELIX_3GPPTT_SUPPORTS_TRANSPARENCY)
- pBIHeader->biCompression = (bHasNonOpaqueAlpha ? HX_ARGB : HX_RGB);
- #endif // /HELIX_3GPPTT_SUPPORTS_TRANSPARENCY.
- #else // /_Not_ using DIB_SECTION (Dib sections are _WINDOWS-only):
- HXBitmapInfoHeader* pBIHeader = &m_BitmapInfoHeader;
- pBIHeader->biSize = 40;
- pBIHeader->biWidth = m_size.cx;
- pBIHeader->biHeight = m_size.cy;
- pBIHeader->biPlanes = 1;
- pBIHeader->biBitCount = (UINT16)m_ulBitsPerPixel;
- #if defined(HELIX_3GPPTT_SUPPORTS_TRANSPARENCY)
- pBIHeader->biCompression = (bHasNonOpaqueAlpha ? HX_ARGB : HX_RGB);
- #else // /TRANSPARENCY _not_ supported:
- pBIHeader->biCompression = HX_RGB;
- #endif /* HELIX_3GPPTT_SUPPORTS_TRANSPARENCY */
- pBIHeader->biSizeImage = m_ulDrawOutputBufferSizeInBytes;
- pBIHeader->biXPelsPerMeter = 0;
- pBIHeader->biYPelsPerMeter = 0;
- pBIHeader->biClrUsed = 0;
- pBIHeader->biClrImportant = 0;
- #endif /* (else of) USE_DIB_SECTION */ // / _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- #if defined(XXXEH_SCROLLING_TRY1_BUT_BUG_IN_CORE)
- HXxRect rDestRect = { m_lXScrollOffset, m_lYScrollOffset,
- m_size.cx, m_size.cy};
- #else // /try #2: move the drawing of the text, not the window srcRect:
- HXxRect rDestRect = {0,0, m_size.cx, m_size.cy};
- #endif // /XXXEH_SCROLLING_TRY1_BUT_BUG_IN_CORE.
-
- #if defined(XXXEH_SCROLLING_TRY1_BUT_BUG_IN_CORE)
- HXxRect rSrcRect = { 0, 0,
- m_size.cx - m_lXScrollOffset, m_size.cy - m_lYScrollOffset };
- if (bIsScrollingOut) // /Flip the rects:
- {
- rSrcRect.left = m_size.cx - m_lXScrollOffset;
- rSrcRect.top = m_size.cy - m_lYScrollOffset;
- rSrcRect.right = m_size.cx;
- rSrcRect.bottom = m_size.cy;
- rDestRect.left = 0;
- rDestRect.top = 0;
- rDestRect.right = m_lXScrollOffset;
- rDestRect.bottom = m_lYScrollOffset;
- }
- #else
- HXxRect rSrcRect = {0,0, m_size.cx, m_size.cy};
- #endif // /End else of defined(XXXEH_SCROLLING_TRY1_BUT_BUG_IN_CORE)
- BYTE* pOutBuf = m_pDrawOutputBuffer;
- // /First see if we have a scroll offset:
- if (m_bDrawInNonTextScrollArea)
- {
- // /Draw the area in the dest that has no text scrolled into it yet:
- #if defined(XXXEH_SCROLLING_TRY1_BUT_BUG_IN_CORE)
- HX_ASSERT(4 == m_ulBitsPerPixel);
- pOutBuf = (BYTE*)&ulBgColorARGB;
- rSrcRect.left = 0;
- rSrcRect.top = 0;
- rSrcRect.right = 1;
- rSrcRect.bottom = 1;
- rDestRect.left = 0;
- rDestRect.top = 0;
- rDestRect.right = m_size.cx;
- rDestRect.bottom = m_size.cy;
- #endif // /XXXEH_SCROLLING_TRY1_BUT_BUG_IN_CORE.
- m_bDrawInNonTextScrollArea = FALSE;
- }
- pVideoSurface->Blt(pOutBuf,
- pBIHeader,
- rDestRect,
- /* XXXEH- Check retval! */ rSrcRect);
- }
- else
- {
- hxrslt = HXR_UNEXPECTED;
- goto cleanup;
- }
- cleanup:
- return hxrslt;
- }
- /****************************************************************************
- * C3GPPTimedTextRenderer::SetFont ref: 3gppttrender.h
- *
- * Sets m_pFont (if it's NULL) to appropriate font by loading the closest-
- * to-given-attributes font available on the system.
- */
- HX_RESULT
- C3GPPTimedTextRenderer::SetFont(const C3GPPTextSampleEntry* pCurTextSampleEntry,
- UINT16 uiFontID_override,
- const char* pCurFontFaceString,
- BOOL bIsBolded,
- BOOL bIsItalicized,
- BOOL bIsUnderlined,
- BOOL bIsStruckThrough,
- UINT32 ulScaledHeight
- #if defined(_WINDOWS) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- , DWORD fdwCharSet
- #endif // /_WINDOWS _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- )
- {
- HX_ASSERT(pCurTextSampleEntry);
- HX_RESULT hxrslt = HXR_OK;
- #if defined(_SYMBIAN) || defined(_WINDOWS) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- #if defined(_WINDOWS) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- HDC hDC = (HDC)m_pDeviceContextMemory;
- #endif // /_WINDOWS _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- UINT16 uiFontIndx = 0;
- BYTE pitchAndFamily = HX_3GPPTT_DEFAULT_PITCH | HX_3GPPTT_FF_DONTCARE;
- const C3GPPFontTableBox& fontTable = pCurTextSampleEntry->GetFontTable();
- const char* pszFaceName = NULL;
- #if defined(_SYMBIAN) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- HX_ASSERT(m_pGCOffscreen && m_pScreenDevice);
- if (!m_pGCOffscreen || !m_pScreenDevice)
- {
- goto cleanup;
- }
- #endif // /_SYMBIAN. _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- // /Use 1st value in pCurTextSampleEntry's font table and try to
- // create a font from that. If that fails, use the next in the
- // table and so on. If none succeed, just use NULL font face:
- for (uiFontIndx = 0; uiFontIndx < fontTable.GetEntryCount(); uiFontIndx++)
- {
- // /But 1st, if uiFontID_override is not invalid (see above)
- // then use the font in the table whose ID matches it
- if (HX_3GPPTT_INVALID_INDEX != uiFontID_override)
- {
- const C3GPPFontRecord* pRec = fontTable.GetFontRecord(uiFontIndx);
- if (uiFontID_override != pRec->GetFontID())
- {
- // /Keep looking (unless there are no more, in which case we'll
- // have to just use the default one):
- if (uiFontIndx + 1 >= fontTable.GetEntryCount())
- {
- // /First, prevent infinite looping ;-)
- uiFontID_override = HX_3GPPTT_INVALID_INDEX;
- // /Then reset uiFontIndx to 0 and go through
- // the default table in order:
- uiFontIndx = 0;
- }
- else // /Look at the next in table for matching ID:
- {
- continue;
- }
- }
- }
- pCurFontFaceString = fontTable.GetFontRecord(uiFontIndx)->GetFontName();
- if (!pCurFontFaceString || 0 == strlen(pCurFontFaceString))
- {
- continue;
- }
- // /Special-case handling of "Serif", "Sans-Serif",
- // and "Monospace" which aren't font faces but families:
- if (!stricmp(FONT_FAMILY_SERIF_STR, pCurFontFaceString))
- {
- // /FF_ROMAN <== serif
- pitchAndFamily = HX_3GPPTT_FF_SERIF_PROPORTIONAL_PITCH;
- }
- else if (!stricmp(FONT_FAMILY_SANS_SERIF_STR,
- pCurFontFaceString))
- {
- // /sans serif ==> FF_SWISS, variable stroke width,
- // no serifs:
- pitchAndFamily = HX_3GPPTT_FF_SANSSERIF_PROPORTIONAL_PITCH;
- }
- else if (!stricmp(FONT_FAMILY_MONOSPACE_STR,
- pCurFontFaceString))
- {
- // /FIXED_PITCH <== monospace (constant stroke width)
- pitchAndFamily = HX_3GPPTT_FIXED_PITCH;
- }
- else // /Use the font face string as the font face:
- {
- pszFaceName = pCurFontFaceString;
- }
- #if defined(_WINDOWS) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- UINT32 ulScaledWidth = 0; // /0 means use default
- if (m_pFont) // /Fixes Helix Issue 656 and Helix Issue 657:
- {
- DeleteObject(m_pFont);
- m_pFont = NULL;
- }
- m_pFont = CreateFont(
- (INT32)ulScaledHeight, //logical ht
- (INT32)ulScaledWidth, // logical average character width
- 0, // angle of escapement
- 0, //base-line orientation angle (==escapement Win95)
- (bIsBolded?FW_BOLD:FW_NORMAL),
- bIsItalicized,
- bIsUnderlined,
- bIsStruckThrough,
- fdwCharSet,
- OUT_DEFAULT_PRECIS, // output precision
- CLIP_DEFAULT_PRECIS,// clipping precision
- DEFAULT_QUALITY,// output quality
- pitchAndFamily,
- // /if NULL or empty string, GDI uses the first font that
- // matches the other specified attributes:
- (LPCTSTR)pszFaceName
- );
- if (m_pFont)
- {
- m_pFontOld = (HFONT)SelectObject(hDC, m_pFont);
- if (!m_pFontOld)
- {
- // /XXXEH- to do: decide if we should really exit here
- #if !defined(USE_DIB_SECTION)
- SelectObject(hDC, hbmpOld);
- #endif // /USE_DIB_SECTION.
- DeleteObject(m_pFont);
- hxrslt = HXR_UNEXPECTED;
- goto cleanup;
- }
- break; // /This one succeeded in loading, so quit looking.
- }
- #elif defined(_SYMBIAN) // / ------------------------------------
- TTypeface theTypeface;
- if (pszFaceName)
- {
- TText8* pUnicodeBuf8FontFace = (TText8*)"Swiss"; //pszFaceName;
- TInt length = strlen(pszFaceName);
- HX_ASSERT(length <= KMaxTypefaceNameLength);
- if (length > KMaxTypefaceNameLength)
- {
- length = KMaxTypefaceNameLength;
- }
- TPtr8 ptr(pUnicodeBuf8FontFace, length, length);
- ((theTypeface.iName/*TBufC<0x18>*/).Des()).Copy(ptr);
- }
-
- theTypeface.SetIsProportional(!(HX_3GPPTT_FIXED_PITCH & pitchAndFamily));
- theTypeface.SetIsSerif(HX_3GPPTT_FF_SERIF_PROPORTIONAL_PITCH & pitchAndFamily);
- /*
- Alp13
- alp17
- Alb17b
- Aco21
- LatinBold12
- LatinBold13
- LatinBold17
- LatinBold19
- LatinPlain12
- */
- // /Handle NULL face name and/or family (which is an exception):
- HX_ASSERT(pCurFontFaceString);
- if (NULL == pCurFontFaceString)
- {
- HX_ASSERT(!pszFaceName);
- // /Just use existing font if it's available:
- if (!m_pFont)
- {
- HX_ASSERT(m_pScreenDevice);
- _LIT(KTxtArial,"Arial");
- TFontSpec tmpFontSpec(KTxtArial, ulScaledHeight * 20);
- m_pScreenDevice->GetNearestFontInTwips(m_pFont, tmpFontSpec);
- }
- }
- else
- {
- // /Load font if it's NULL. If it's not NULL, clean it up first:
- if (NULL != m_pFont)
- {
- HX_ASSERT(m_pScreenDevice);
- if (m_pScreenDevice)
- {
- m_pScreenDevice->ReleaseFont(m_pFont);
- }
- m_pFont = NULL;
- }
- TFontSpec theFontSpec;
- theFontSpec.iTypeface = theTypeface;
- theFontSpec.iHeight = ulScaledHeight * 20; // /points*20 = twips
-
- theFontSpec.iFontStyle.SetPosture(bIsItalicized? EPostureItalic:EPostureUpright);
- theFontSpec.iFontStyle.SetStrokeWeight(bIsBolded? EStrokeWeightBold:EStrokeWeightNormal);
- m_pGCOffscreen->SetUnderlineStyle(bIsUnderlined? EUnderlineOn:EUnderlineOff);
- m_pScreenDevice->GetNearestFontInTwips(m_pFont, theFontSpec);
- }
- if (m_pFont)
- {
- // /Success: use it in gc:
- m_pGCOffscreen->UseFont(m_pFont);
- #if defined(_DEBUG)
- // /XXXEH- remove this assert after verifying code is correct:
- TInt tiTmp = m_pFont->HeightInPixels();
- // HX_ASSERT(m_pFont->HeightInPixels() == (TInt)ulScaledHeight);
- #endif
- break; // /This one succeeded in loading, so quit looking.
- }
- #endif // /end else of ifdef _WINDOWS. _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- // /Else if we failed to load the font and we're using a
- // font override, then use the default font table, in order:
- else if (HX_3GPPTT_INVALID_INDEX != uiFontID_override)
- {
- HX_ASSERT(0); // /Should never get here, A.F.A.I.K.
- // /First, prevent infinite looping ;-)
- uiFontID_override = HX_3GPPTT_INVALID_INDEX;
- // /Then reset uiFontIndx to 0 and go through
- // the default table in order:
- // /XXXEH- note: this will skip entry 0 since uiFontIndx++
- // in the for loop will occur, but this is an exception
- // getting here, anyway, so don't devote code to that:
- uiFontIndx = 0;
- }
- // /else try to load the next author-suggested alternate font via for()
- } // /END "for (UINT16 uiFontIndx..."
- #if defined(XXXEH_DEBUGOUT_DRAW_3GPPTT)
- pFile = fopen("c:\3gppttdrawPos.txt", ulCount?"a+":"w");
- if (pFile)
- {
- fprintf(pFile, "[step 3] T.C. = %p at time %lu (text containers handled = "
- "%ld), m_pTextContainerListFutureTimePos=%pn", pTextContainer,
- m_ulTimeOfLastTimeSync, ulTextContainersHandled,
- m_pTextContainerListFutureTimePos);
- fclose(pFile);
- }
- ulCount++;
- #endif // /XXXEH_DEBUGOUT_DRAW_3GPPTT.
- // /If none in the font table could be loaded, then, uh ... quit, I guess:
- if (!m_pFont)
- {
- HX_ASSERT(m_pFont);
- #if defined(_WINDOWS) && !defined(USE_DIB_SECTION)
- SelectObject(hDC, hbmpOld);
- #endif // /USE_DIB_SECTION.
- hxrslt = HXR_UNEXPECTED;
- goto cleanup;
- }
- #if defined(XXXEH_DEBUGOUT_DRAW_3GPPTT)
- pFile = fopen("c:\3gppttdrawPos.txt", ulCount?"a+":"w");
- if (pFile)
- {
- fprintf(pFile, "[step 4] T.C. = %p at time %lu (text containers handled = "
- "%ld), m_pTextContainerListFutureTimePos=%pn", pTextContainer,
- m_ulTimeOfLastTimeSync, ulTextContainersHandled,
- m_pTextContainerListFutureTimePos);
- fclose(pFile);
- }
- ulCount++;
- #endif // /XXXEH_DEBUGOUT_DRAW_3GPPTT.
- #else // /else of: _WINDOWS || _SYMBIAN
- #pragma message("====##### This OS needs code that sets font #####====")
- #endif // /end else of: _WINDOWS || _SYMBIAN _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- cleanup:
- return hxrslt;
- }
- /****************************************************************************
- * C3GPPTimedTextRenderer::SetJustification ref: 3gppttrender.h
- *
- * Sets justification flags (to be used in each OS's version of DrawText()):
- */
- UINT32
- C3GPPTimedTextRenderer::SetJustificationFlags(
- const C3GPPTextSampleEntry* pCurTextSampleEntry)
- {
- UINT32 ulTextFormatFlags = HX_3GPPTT_INITIAL_TEXTFORMAT;
- switch (pCurTextSampleEntry->GetHorJust())
- {
- case HX_3GPPTT_JUSTIFICATION_LEFT:
- ulTextFormatFlags |= HX_3GPPTT_JUSTIFY_LEFT;
- break;
- case HX_3GPPTT_JUSTIFICATION_CENTER:
- ulTextFormatFlags |= HX_3GPPTT_JUSTIFY_HCENTER;
- break;
- case HX_3GPPTT_JUSTIFICATION_RIGHT:
- ulTextFormatFlags |= HX_3GPPTT_JUSTIFY_RIGHT;
- break;
- }
- switch (pCurTextSampleEntry->GetVerJust())
- {
- case HX_3GPPTT_JUSTIFICATION_TOP:
- ulTextFormatFlags |= HX_3GPPTT_JUSTIFY_TOP;
- break;
- case HX_3GPPTT_JUSTIFICATION_CENTER:
- #if defined(_WINDOWS) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- // /XXXEH- todo: v-align:
- // we need a different solution that allows for multi-line v-alignment,
- // which Windows doesn't do. Symbian doesn't do any vert alignment for you,
- // anyway:
- #define XXXEH_DO_HACK_FOR_WINDOWS_VALIGN
- #endif // /_WINDOWS. _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- #if defined(XXXEH_DO_HACK_FOR_WINDOWS_VALIGN)
- ulTextFormatFlags |= DT_SINGLELINE;
- #endif // /XXXEH_DO_HACK_FOR_WINDOWS_VALIGN
- ulTextFormatFlags |= HX_3GPPTT_JUSTIFY_VCENTER;
- break;
- case HX_3GPPTT_JUSTIFICATION_BOTTOM:
- #if defined(XXXEH_DO_HACK_FOR_WINDOWS_VALIGN)
- ulTextFormatFlags |= DT_SINGLELINE;
- #endif // /XXXEH_DO_HACK_FOR_WINDOWS_VALIGN
- ulTextFormatFlags |= HX_3GPPTT_JUSTIFY_BOTTOM;
- break;
- }
- return ulTextFormatFlags;
- }
- #if defined(_WINDOWS) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- /****************************************************************************
- * C3GPPTimedTextRenderer::ConvertToOSRenderableChars ref: 3gppttrender.h
- *
- * Takes a TextContainer's string and:
- * (a) decides if it's UTF-8 or UTF-16. If UTF-8, converts to UTF-16.
- * e.g., "Hello" will be converted to "H e l l o "
- * (b) On Symbian, returns NULL pszNativeString if already UTF-16 string
- * otherwise returns converted-to-UTF16 string
- * (c) On Windows, converts from UTF-16 to appropriate character set.
- * e.g., "H e l l o " will be converted "Hello" and charst returned
- * will be ISO-8859-1 (ANSI_CHARSET on Windows)
- *
- * pszNativeString must be NULL coming in. Receiver must deleted it when done.
- * NOTE: the only guaranteed NULL-terminated char buffer used in this method
- * is pszNativeString (hence the others don't have psz... variable names):
- */
- HX_RESULT
- C3GPPTimedTextRenderer::ConvertToOSRenderableChars(const C3GPPTextContainer* pTextCont,
- /*OUT*/ DWORD& fdwCharSet,
- /*OUT*/ char*& pszNativeString,
- /*OUT*/ INT32& lNativeStringLen)
- {
- HX_ASSERT(pTextCont);
- HX_RESULT hxrslt = HXR_FAIL;
- INT32 lTextNumBytes = 0;
- const char* pTextContainerText = NULL;
- BOOL bTextContainerTextIsUTF16Encoded = FALSE;
- BOOL bTextContainerTextIsUTF16ReverseEncoded = FALSE;
- if (!pTextCont || !pTextCont->m_pTextSample ||
- !pTextCont->m_pTextSample->GetText() ||
- pTextCont->m_pTextSample->GetTextLenInBytes() <
- pTextCont->GetTextByteLength() +
- pTextCont->m_uiUnpackedStartCharOffset ||
- pTextCont->m_uiUnpackedEndCharOffset <=
- pTextCont->m_uiUnpackedStartCharOffset)
- {
- hxrslt = HXR_INVALID_PARAMETER;
- HX_ASSERT(HXR_INVALID_PARAMETER != hxrslt); // /Always assert here
- goto cleanup;
- }
- lTextNumBytes = (INT32)((UINT32)pTextCont->GetTextByteLength());
- // /NOTE: this is not NULL-terminated:
- pTextContainerText = (const char*)pTextCont->m_pTextSample->GetTextAt(
- pTextCont->m_uiUnpackedStartCharOffset);
- bTextContainerTextIsUTF16Encoded =
- IsUTF16Encoded((const UCHAR*)pTextContainerText, lTextNumBytes,
- /*REF*/bTextContainerTextIsUTF16ReverseEncoded);
- HX_ASSERT(NULL == pszNativeString);
- if (pszNativeString) // /Incoming char buf must be NULL
- {
- hxrslt = HXR_UNEXPECTED;
- }
- else
- {
- UINT16* pUTF16String = NULL;
- INT32 lLenUTF16StrInWideChars = 0;
- if (bTextContainerTextIsUTF16Encoded)
- {
- if (bTextContainerTextIsUTF16ReverseEncoded)
- {
- // /We can just use the bytes (past the 0xFEFF flag) without
- // modification since Windows is little endian:
- pUTF16String = (UINT16*)(pTextContainerText+2);
- lLenUTF16StrInWideChars = (lTextNumBytes-2) / 2;
- }
- else
- {
- lLenUTF16StrInWideChars = (lTextNumBytes-2) / 2;
- // /Big-endian, so we need to swap bytes into new buffer:
- pUTF16String = new UINT16[lLenUTF16StrInWideChars+1];
- if (pUTF16String)
- {
- for (UINT32 uli16=0; uli16<lLenUTF16StrInWideChars; uli16++)
- {
- pUTF16String[uli16] =
- ((UINT16)pTextContainerText[(uli16+1)*2])<<8 |
- pTextContainerText[((uli16+1)*2) + 1];
- }
- }
- }
- }
- else
- {
- // /In Windows, we have to convert to UTF-16 and then convert
- // again to a Windows renderable DBCS charset:
- // First, find the buffer length needed for the conversion:
- lLenUTF16StrInWideChars = MultiByteToWideChar( /* Flawfinder: ignore */
- CP_UTF8, 0, pTextContainerText, lTextNumBytes, NULL, 0);
- pUTF16String = new UINT16 [lLenUTF16StrInWideChars];
- if (!pUTF16String)
- {
- hxrslt = HXR_OUTOFMEMORY;
- goto cleanup;
- }
- // convert UTF-8 to UTF-16
- memset(pUTF16String, 0, lLenUTF16StrInWideChars); /* Flawfinder: ignore */
- MultiByteToWideChar(CP_UTF8, 0, /* Flawfinder: ignore */
- pTextContainerText, lTextNumBytes, pUTF16String,
- lLenUTF16StrInWideChars);
- }
- if (pUTF16String)
- {
- UINT32 ulCodePage = 1252; // /Init to ANSI - Latin I just for kicks
- // /Now, we need to figure out what character set this is, based
- // on what UTF-16 character codes it contains:
- GetAppropriateCharset(pUTF16String, lLenUTF16StrInWideChars,
- /*REF*/fdwCharSet, /*REF*/ulCodePage);
- INT32 lLenWinStrInBytes = WideCharToMultiByte( /* Flawfinder: ignore */
- ulCodePage, 0, pUTF16String, lLenUTF16StrInWideChars, NULL, 0, NULL, NULL);
- pszNativeString = new char [lLenWinStrInBytes + 1];
- if (pszNativeString)
- {
- lNativeStringLen = lLenWinStrInBytes;
- // convert UTF-16 to Windows charset string:
- memset(pszNativeString, 0, lLenWinStrInBytes + 1); /* Flawfinder: ignore */
- BOOL bOoL = FALSE;
- WideCharToMultiByte(/* Flawfinder: ignore */
- ulCodePage,
- 0, //WC_DEFAULTCHAR, // /<= convert exceptions to default char
- pUTF16String, lLenUTF16StrInWideChars,
- pszNativeString, lLenWinStrInBytes,
- NULL, // /LPCSTR lpDefaultChar, for unmappable chars
- &bOoL // /<=gets set to TRUE when default char used
- );
- hxrslt = HXR_OK;
- }
- if (bTextContainerTextIsUTF16ReverseEncoded)
- {
- HX_VECTOR_DELETE(pUTF16String);
- }
- }
- }
- cleanup:
- return hxrslt;
- }
- #define HX_3GPPTT_UCHART_NUM_CHARTS 32
- /* Windows defined charsets:
- ANSI_CHARSET // /iso-8859-1, us-ascii
- SHIFTJIS_CHARSET // /x-sjis
- HANGEUL_CHARSET // /hangeul
- JOHAB_CHARSET // /johab
- GB2312_CHARSET // /gb2312
- CHINESEBIG5_CHARSET // /big5, x-euc-tw
- EASTEUROPE_CHARSET // /iso-8859-2
- RUSSIAN_CHARSET // /iso-8859-5, windows-1251
- ARABIC_CHARSET // /iso-8859-6
- GREEK_CHARSET // /iso-8859-7
- HEBREW_CHARSET // /iso-8859-8
- TURKISH_CHARSET // /iso-8859-9
- THAI_CHARSET // /iso-8859-11, iso-ir-166
- BALTIC_CHARSET // /iso-8859-13
- */
- static const UINT32 HX_3GPPTT_UCHART_START_INDICES[HX_3GPPTT_UCHART_NUM_CHARTS] =
- {
- 0x0041, 0x00C0, 0x1D00, 0x1E00, 0xFB00, // /Latin
- 0x0370, 0x1F00, // /Greek
- 0x0400, 0x0500, // /Cyrillic
- 0x0530, // /Armenian (EASTEUROPE_CHARSET???)
- 0x10A0, // /Georgian (EASTEUROPE_CHARSET???)
- 0x0590, 0xFB1D, // /Hebrew
- 0x0600, 0xFB50, 0xFE70, // /Arabic
- 0x0E00, // /Thai
- 0x20000, 0xF900, 0x2F800, 0x3190, 0x2E80, 0x2FF0, // /Han (CJK)
- 0x3100, // /Bopomofo (Chinese zh鵼inf鷋鄌 (still in use in Taiwan))
- 0x3040, 0x30A0, 0x31F0, 0xFF00, // /Hiragana and Katakana (Japanese)
- 0x1100, 0x3130, 0xAC00, // /Hangeul (Korean)
- 0xA000 // /Yi (???)
- };
- static const UINT32 HX_3GPPTT_UCHART_END_INDICES[HX_3GPPTT_UCHART_NUM_CHARTS] =
- {
- 0x007A, 0x02AF, 0x1D6A, 0x1EFF, 0xFB06, // /Latin
- 0x03FF, 0x1FFF, // /Greek
- 0x04FF, 0x052F, // /Cyrillic
- 0x058F, // /Armenian (EASTEUROPE_CHARSET???)
- 0x10FF, // /Georgian (EASTEUROPE_CHARSET???)
- 0x05FF, 0xFB4F, // /Hebrew
- 0x06FF, 0xFDFF, 0xFEFF, // /Arabic
- 0x0E7F, // /Thai
- 0x2A6D6, 0xFAFF, 0x2FA1D, 0x319F, 0x2FD5, 0x2FFB, // /Han (CJK)
- 0x312F, // /Bopomofo (Chinese zh鵼inf鷋鄌 (still in use in Taiwan))
- 0x309F, 0x30FF, 0x31FF, 0xFFEF, // /Hiragana and Katakana (Japanese)
- 0x11FF, 0x318F, 0xD7A3, // /Hangeul (Korean)
- 0xA4CF, // /Yi (???)
- };
- /****************************************************************************
- * C3GPPTimedTextRenderer::GetAppropriateCharset ref: 3gppttrender.h
- *
- * Windows-only method that looks at the contents of a wide-char string to
- * decide (best-guess) what Windows charset it is
- */
- HX_RESULT
- C3GPPTimedTextRenderer::GetAppropriateCharset(wchar_t* pUTF16String,
- INT32 lLenUTF16StrInWideChars,
- /*OUT*/ DWORD& fdwCharSet, /*OUT*/UINT32& ulCodePage)
- {
- HX_RESULT hxrslt = HXR_OK;
- UINT32 ulLastCharChartIndex = 0;
- UINT32 uljj = 0;
- UINT32 ulii = 0;
- UINT32 ulIndexOfMax = 0;
- UINT32 ulMaxFound = 0;
- UINT16 pCountArray[HX_3GPPTT_UCHART_NUM_CHARTS];
- memset(pCountArray, 0x0, HX_3GPPTT_UCHART_NUM_CHARTS*sizeof(UINT16));
- if (!pUTF16String || lLenUTF16StrInWideChars<1)
- {
- hxrslt = HXR_UNEXPECTED;
- goto cleanup;
- }
- // /Init to ANSI Latin 1:
- fdwCharSet = ANSI_CHARSET;
- ulCodePage = 1252; // / ANSI - Latin I
- // /Now, walk through the string and find the first non-Latin-1 char,
- // if any:
- for (ulii=0; ulii<(UINT32)lLenUTF16StrInWideChars; ulii++)
- {
- if (ulii > 0 && pUTF16String[ulii] >=
- HX_3GPPTT_UCHART_START_INDICES[ulLastCharChartIndex] &&
- pUTF16String[ulii] <=
- HX_3GPPTT_UCHART_END_INDICES[ulLastCharChartIndex])
- {
- // /Optimization in search: assume prior character is most likely
- // in same UNICODE area as this one; if not, then do for() below:
- pCountArray[ulLastCharChartIndex]++;
- continue;
- }
- for (uljj=0; uljj<HX_3GPPTT_UCHART_NUM_CHARTS; uljj++)
- {
- if (pUTF16String[ulii] >= HX_3GPPTT_UCHART_START_INDICES[uljj] &&
- pUTF16String[ulii] <= HX_3GPPTT_UCHART_END_INDICES[uljj])
- {
- ulLastCharChartIndex = uljj;
- pCountArray[uljj]++;
- break;
- }
- }
- }
- // /Now, look at the largest user and guess that we've found the charset:
- for (uljj=0; uljj<HX_3GPPTT_UCHART_NUM_CHARTS; uljj++)
- {
- if (pCountArray[uljj] > ulMaxFound)
- {
- ulMaxFound = pCountArray[uljj];
- ulIndexOfMax = uljj;
- }
- }
- if (ulIndexOfMax < 5)
- {
- fdwCharSet = ANSI_CHARSET; // /~iso-8859-1
- ulCodePage = 1252; // / ANSI - Latin I
- }
- else if (ulIndexOfMax < 7)
- {
- fdwCharSet = GREEK_CHARSET; // /~iso-8859-7
- ulCodePage = 1253; // / ANSI - Greek
- }
- else if (ulIndexOfMax < 9)
- {
- fdwCharSet = RUSSIAN_CHARSET; // /~iso-8859-5, windows-1251
- ulCodePage = 1251; // / ANSI - Cyrillic
- }
- else if (ulIndexOfMax < 10)
- {
- fdwCharSet = EASTEUROPE_CHARSET; // /~iso-8859-2
- ulCodePage = 1250; // / ANSI - Central European
- }
- else if (ulIndexOfMax < 11)
- {
- fdwCharSet = EASTEUROPE_CHARSET; // /~iso-8859-2
- ulCodePage = 1250; // / ANSI - Central European
- }
- else if (ulIndexOfMax < 13)
- {
- fdwCharSet = HEBREW_CHARSET; // /~iso-8859-8
- ulCodePage = 1255; // / ANSI - Hebrew
- }
- else if (ulIndexOfMax < 16)
- {
- fdwCharSet = ARABIC_CHARSET; // /~iso-8859-6
- ulCodePage = 1256; // / ANSI - Arabic
- }
- else if (ulIndexOfMax < 17)
- {
- fdwCharSet = THAI_CHARSET; // /~iso-8859-11, ~iso-ir-166
- ulCodePage = 874; // / ANSI/OEM - Thai (same as 28605,
- // ISO 8859-15)
- }
- else if (ulIndexOfMax < 23)
- {
- // /XXXEH- this is CJK unified, so we don't know if it's Chinese,
- // Japanese, or Korean unless we study the actual text. Assume
- // Japanese if any Hirigana or Katakana were present, Hangeul if
- // any Hangeul were present, and Chinese if Yi (???) were present
- // otherwise Japanese:
- if (pCountArray[24] || pCountArray[25] || pCountArray[26] ||
- pCountArray[27])
- {
- fdwCharSet = SHIFTJIS_CHARSET; // /~x-sjis
- ulCodePage = 932; // / ANSI/OEM - Japanese, Shift-JIS
- }
- else if (pCountArray[28] || pCountArray[29] || pCountArray[30])
- {
- fdwCharSet = HANGEUL_CHARSET; // /~hangeul
- ulCodePage = 949; // / ANSI/OEM - Korean (Unified Hangeul)
- }
- else if (pCountArray[31])
- {
- fdwCharSet = GB2312_CHARSET; // /Yi ??? XXXEH- or could be Big5
- ulCodePage = 936; // / ANSI/OEM - Simplified Chinese
- // (PRC, Singapore)
- }
- else
- {
- fdwCharSet = SHIFTJIS_CHARSET; // /~x-sjis
- ulCodePage = 932; // / ANSI/OEM - Japanese, Shift-JIS
- }
- }
- else if (ulIndexOfMax < 24)
- {
- fdwCharSet = CHINESEBIG5_CHARSET; // /Bopomofo (Taiwan: Trad'l Chinese)
- ulCodePage = 950; // / ANSI/OEM - Traditional Chinese
- // (Taiwan; Hong Kong SAR, PRC)
- }
- else if (ulIndexOfMax < 28)
- {
- fdwCharSet = SHIFTJIS_CHARSET; // /~x-sjis
- ulCodePage = 932; // / ANSI/OEM - Japanese, Shift-JIS
- }
- else if (ulIndexOfMax < 31)
- {
- fdwCharSet = HANGEUL_CHARSET; // /~hangeul
- ulCodePage = 949; // / ANSI/OEM - Korean (Unified Hangeul)
- }
- else if (ulIndexOfMax < 32)
- {
- fdwCharSet = GB2312_CHARSET; // /Yi ??? XXXEH- or could be Big5
- ulCodePage = 936; // / ANSI/OEM - Simplified Chinese
- // (PRC, Singapore)
- }
- else
- {
- HX_ASSERT(ulIndexOfMax < HX_3GPPTT_UCHART_NUM_CHARTS);
- fdwCharSet = ANSI_CHARSET;
- ulCodePage = 1252; // / ANSI - Latin I
- }
- cleanup:
- return hxrslt;
- }
- #endif // /_WINDOWS _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- /****************************************************************************
- * C3GPPTimedTextRenderer::FillRectangle ref: 3gppttrender.h
- *
- */
- HX_RESULT
- C3GPPTimedTextRenderer::FillRectangle(UINT32 ulRectColorARGB)
- {
- HX_RESULT hxrslt = HXR_UNEXPECTED;
- if (m_pDrawOutputBuffer && m_ulDrawOutputBufferSizeInBytes)
- {
- #if (HX_3GPPTT_DEFAULT_bits_PER_PIXEL == 32)
- HX_ASSERT(m_ulBitsPerPixel >= 8);
- // /XXXEH- todo: take into account the (possibly-smaller-than-region) rect of this entry:
- UINT32 ulNumPixelsHandled = 0;
- UINT32 ulNumPixelsTotal = m_ulDrawOutputBufferSizeInBytes/(m_ulBitsPerPixel/8);
- UINT32* pCurPixel = (UINT32*)m_pDrawOutputBuffer;
- for ( ; ulNumPixelsHandled < ulNumPixelsTotal; pCurPixel++)
- {
- *pCurPixel = ulRectColorARGB;
- ulNumPixelsHandled++;
- }
- hxrslt = HXR_OK;
- #elif defined(_SYMBIAN) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- if (m_pGCOffscreen)
- {
- TRgb rgbColor;
- convertARGBtoSymbianTrgbColor(rgbColor, ulRectColorARGB);
- m_pGCOffscreen->SetPenStyle(CGraphicsContext::ENullPen);
- m_pGCOffscreen->SetBrushStyle(CGraphicsContext::ESolidBrush);
- m_pGCOffscreen->SetBrushColor(rgbColor);
- const TRect theRect(0, 0, m_size.cx, m_size.cy);
- m_pGCOffscreen->DrawRect(theRect);
- // /Set pen & brush back to what they were for text drawing:
- m_pGCOffscreen->SetPenStyle(CGraphicsContext::ESolidPen);
- m_pGCOffscreen->SetBrushStyle(CGraphicsContext::ENullBrush);
- }
- #else // / ------------------------------------
- #error: FillRectangle() not implemented for this bitdepth &/or platform
- #endif// /#if HX_3GPPTT_DEFAULT_bits_PER_PIXEL == 32, #elif _SYMBIAN, #else... _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- }
- return hxrslt;
- }
- /****************************************************************************
- * C3GPPTimedTextRenderer::HandleClick ref: 3gppttrender.h
- *
- */
- HX_RESULT
- C3GPPTimedTextRenderer::HandleClick(INT16 fwKeys, INT16 xPos, INT16 yPos)
- {
- HX_RESULT hxrslt = HXR_OK;
- m_ulNumberOfClicks++;
- if (m_pHyperNavigate)
- {
- C3GPPTextHyperTextBox* pHyperTextBox =
- findActiveHyperlinkAtXY(xPos, yPos);
-
- if (pHyperTextBox)
- {
- const char* pszURL = pHyperTextBox->GetURL();
- if( pszURL && *pszURL != ' ')
- {
- // launching URLs usually replaces the current presentation):
- m_pHyperNavigate->GoToURL(pszURL,
- NULL /* NULL= use default target (default browser) */);
-
- }
- }
- }
- return hxrslt;
- }
- /****************************************************************************
- * C3GPPTimedTextRenderer::OnMouseMove ref: 3gppttrender.h
- *
- */
- BOOL
- C3GPPTimedTextRenderer::OnMouseMove(INT16 fwKeys, INT16 xPos, INT16 yPos)
- {
- // don't do anything if the x/y coordinates have changed from the
- // last call to OnMouseMove - this is needed because the call to
- // IHXStatusMessage::SetStatus() results in a WM_MOUSEMOVE event
- if(xPos == m_nLastMouseMoveXPos &&
- yPos == m_nLastMouseMoveYPos)
- {
- return FALSE;
- }
- m_nLastMouseMoveXPos = xPos;
- m_nLastMouseMoveYPos = yPos;
- #if defined(_WINDOWS) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- HCURSOR hCurrentCursor = GetCursor();
- #endif // /_WINDOWS _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- C3GPPTextHyperTextBox* pHyperTextBox =
- findActiveHyperlinkAtXY(xPos, yPos);
- if (pHyperTextBox && pHyperTextBox->HasURL())
- {
- const char* pszURL = pHyperTextBox->GetURL();
- HX_ASSERT(pszURL && *pszURL != ' ');
-
-
- #if defined(_WINDOWS) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- if(!m_hHyperlinkCursor)
- {
- m_hHyperlinkCursor = LoadCursor(g_hInstance,
- MAKEINTRESOURCE(HANDCURSOR));
- if(!m_hHyperlinkCursor)
- {
- m_hHyperlinkCursor=LoadCursor(NULL, IDC_UPARROW);
- }
- }
- if(m_hHyperlinkCursor &&
- hCurrentCursor != m_hHyperlinkCursor)
- {
- //Change it; we just moved onto a hyperlink:
- //Handle this in WM_SETCURSOR (which should arrive
- // shortly):
- m_bNeedToSetHyperlinkHandCursor = TRUE;
- }
- //Note: if needed, Window Handle is m_pEvent->window.
- #elif defined(_MACINTOSH)
- if (m_hHyperlinkCursor)
- {
- ::SetCursor(*m_hHyperlinkCursor);
- m_CurrentCursor = CURSOR_HYPERLINK;
- }
- #elif defined(_UNIX) && (!(defined(_BEOS)))
- if (!m_hHyperlinkCursor && m_pPixmapDisplay && m_lastWindow)
- {
- m_hHyperlinkCursor = XCreateFontCursor(m_pPixmapDisplay,
- XC_hand2);
- }
- if (m_hHyperlinkCursor)
- {
- XDefineCursor(m_pPixmapDisplay, m_lastWindow, m_hHyperlinkCursor);
- m_bHandActivated = TRUE;
- }
- #endif // /_WINDOWS -else- _MACINTOSH -else- (_UNIX && !_BEOS) _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- #if defined(HELIX_3GPPTT_USE_STATUS_BAR)
- if (m_pStatusMessage)
- {
- const char* pszDisplayURL = pszURL;
-
- // /If Alt URL is set, then use it instead in the status area:
- if (pHyperTextBox->HasAltURL())
- {
- pszDisplayURL = pHyperTextBox->GetAltURL();
- HX_ASSERT(pszDisplayURL && *pszDisplayURL != ' ');
- }
-
- if( !m_pszHLinkToDisplay || (0 != strcmp(pszDisplayURL, m_pszHLinkToDisplay)))
- {
- // we have a new url; copy display url
- HX_DELETE(m_pszHLinkToDisplay);
-
- UINT32 uDisplayURLlen = strlen(pszDisplayURL);
- m_pszHLinkToDisplay = new char[uDisplayURLlen + 1];
- if (!m_pszHLinkToDisplay)
- {
- return FALSE; // /Out of memory
- }
- HX_ASSERT(uDisplayURLlen <= MAX_3GPPTT_URL_LEN);
-
- memcpy(m_pszHLinkToDisplay, /* Flawfinder: ignore */
- pszDisplayURL, uDisplayURLlen);
- m_pszHLinkToDisplay[uDisplayURLlen] = ' ';
-
- m_bStatusMsgWillNeedErasing = TRUE;
- m_pStatusMessage->SetStatus(m_pszHLinkToDisplay);
- }
-
- }
- #endif /* HELIX_3GPPTT_USE_STATUS_BAR */
- return TRUE;
-
- }
- else
- {
- #if defined(_WINDOWS) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- if(hCurrentCursor == m_hHyperlinkCursor)
- {
- //We need to change it back -- we just moved off of a hyperlink:
- //Handle this in WM_SETCURSOR (which should arrive
- // shortly):
- m_bNeedToSetHyperlinkHandCursor = FALSE;
- }
- #elif defined(_MACINTOSH)
- if (m_CurrentCursor == CURSOR_HYPERLINK)
- {
- InitCursor();
- m_CurrentCursor = CURSOR_ARROW;
- }
- #elif defined(_UNIX) && (!(defined(_BEOS)))
- if (m_bHandActivated)
- {
- XUndefineCursor(m_pPixmapDisplay, m_lastWindow);
- m_bHandActivated = FALSE;
- }
- #endif // /_WINDOWS -else- _MACINTOSH -else- (_UNIX && !_BEOS) _____^^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- #if defined(HELIX_3GPPTT_USE_STATUS_BAR)
- if (m_pStatusMessage &&
- // /Only set this to NULL if we
- // have recently set the status message, otherwise we may
- // cause SMIL's (or other presentation-parent's) setting of the
- // status message to be overwritten with NULL, i.e., erased:
- m_bStatusMsgWillNeedErasing)
- {
- m_bStatusMsgWillNeedErasing = FALSE;
- m_pStatusMessage->SetStatus(NULL);
- }
- #endif /* HELIX_3GPPTT_USE_STATUS_BAR */
- return FALSE;
- }
- return FALSE;
- }
- /****************************************************************************
- * C3GPPTimedTextRenderer::findActiveHyperlinkAtXY
- *
- * This looks through the textContainers to see if any are time-active at
- * and hyperlinked at the specified location. Returns NULL if none found.
- */
- C3GPPTextHyperTextBox*
- C3GPPTimedTextRenderer::findActiveHyperlinkAtXY(
- INT16 iXPos, INT16 iYPos)
- {
- C3GPPTextHyperTextBox* pRetHyperTextBox = NULL;
- // /Look at current TextContainer of m_pTextContainerList (which is at
- // [m_pTextContainerListFutureTimePos - 1] and return its href URL, if any:
- if (m_pTextContainerList)
- {
- LISTPOSITION pListPosTmp = NULL;
- C3GPPTextContainer* pCurTextContainer = NULL;
- if (!m_pTextContainerListFutureTimePos)
- {
- // /No future-begin TextContainer, so get last one received which
- // should be currently active:
- pListPosTmp = m_pTextContainerList->GetTailPosition();
- pCurTextContainer = (C3GPPTextContainer*)
- m_pTextContainerList->GetAt(pListPosTmp);
- HX_ASSERT(pCurTextContainer &&
- pCurTextContainer->GetBeginTime() <= m_ulTimeOfLastTimeSync);
- }
- else
- {
- // /Get latest non-future-begin packet:
- pListPosTmp = m_pTextContainerListFutureTimePos;
- pCurTextContainer = (C3GPPTextContainer*)
- m_pTextContainerList->GetAtPrev(pListPosTmp);
- if (pListPosTmp)
- {
- // /Make sure we didn't change m_pTextContainerListFutureTimePos:
- HX_ASSERT(pListPosTmp != m_pTextContainerListFutureTimePos);
- }
- }
- HX_ASSERT(pCurTextContainer);
- if (pCurTextContainer &&
- // /XXXEH- handle possible time-offset!:
- pCurTextContainer->GetBeginTime() <= m_ulTimeOfLastTimeSync &&
- pCurTextContainer->IsHyperlinked() &&
- pCurTextContainer->ContainsPoint(iXPos, iYPos) )
- {
- pRetHyperTextBox = pCurTextContainer->m_pTextHyperTextBox;
- }
- }
- return pRetHyperTextBox;
- }
- /****************************************************************************
- * C3GPPTimedTextRenderer::GetPacketContentTime(IHXPacket* pNewPacket)
- *
- */
- UINT32
- C3GPPTimedTextRenderer::GetPacketContentTime(IHXPacket* pPacket)
- {
- UINT32 ulPacketContentsBeginTime = HX_3GPPTT_INVALID_TIME;
- if (pPacket)
- {
- if (!m_bRTPPacketTested)
- {
- m_bRTPPacketTested = TRUE;
- IHXRTPPacket* pRTPPacket = NULL;
- m_bUsesRTPPackets = (pPacket->QueryInterface(IID_IHXRTPPacket,
- (void**) &pRTPPacket)
- == HXR_OK);
- HX_RELEASE(pRTPPacket);
- }
- if (m_bUsesRTPPackets)
- {
- ulPacketContentsBeginTime = ((IHXRTPPacket*)pPacket)->GetRTPTime();
- }
- else
- {
- ulPacketContentsBeginTime = pPacket->GetTime();
- }
- }
- return ulPacketContentsBeginTime;
- }
- /****************************************************************************
- * C3GPPTimedTextRenderer::HandleNewText(IHXPacket* pNewPacket)
- *
- * This creates n TextContainers, each of which pt to the packet,
- * and it AddRef's the packet in each one's ctor and then fills the
- * m_pTextContainerList with all the new textContainer ptrs (sorted
- * chronologically):
- */
- HX_RESULT
- C3GPPTimedTextRenderer::HandleNewText(IHXPacket* pNewPacket,
- LISTPOSITION& plistPosOfFirstTxtCntnr)
- {
- HX_ASSERT(pNewPacket);
- HX_RESULT hxrslt = HXR_OK;
- IHXBuffer* pBuff = NULL;
- if (pNewPacket && NULL != (pBuff = pNewPacket->GetBuffer()))
- {
- UINT32 ulPacketContentsBeginTime = GetPacketContentTime(pNewPacket);
- // /Walk through the textModifiers, if any, of the packet and break
- // text into textContainers, each pointing to the start of same-
- // attributed text blocks. For instance, if chars [0]-[3] had
- // defaulted attributes (say black color, plain, ..etc.), [4]-[8] were
- // changed to red color, chars [7]-[10] were changed to BOLD, and
- // chars [11]-[20] had defaulted attributes, then chars [0]-[3] would
- // be in T.C. #1, [4]-[6] would be in T.C. #2, [7]-[8] would be in
- // T.C. #3, [9]-[10] would be in T.C. #4, and [11]-[20] would be in
- // T.C. #5. Each of those 5 T.C.'s would point into the same packet.
- UINT16 uiStartCharOffset = 0;
- UINT16 uiREFIndexOfLastChar = HX_3GPPTT_INVALID_INDEX;
- BOOL bIsFirstTextContainerFromNewPkt = TRUE;
- C3GPPTextContainer* pNewTextContainer = new C3GPPTextContainer();
- if(!pNewTextContainer)
- {
- hxrslt = HXR_OUTOFMEMORY;
- goto exit;
- }
- hxrslt = pNewTextContainer->Init(pNewPacket, ulPacketContentsBeginTime,
- // /Set end to stream end time; we won't know this pkt's end
- // time until next pkt arrives, unless this is last pkt in
- // which case end time *is* the stream duration:
- m_ulDuration,
- uiStartCharOffset, uiREFIndexOfLastChar);
- if(FAILED(hxrslt))
- {
- HX_DELETE(pNewTextContainer);
- goto exit;
- }
- while (pNewTextContainer && pNewTextContainer->m_pTextSample)
- {
- m_pTextContainerList->AddTail((void*) pNewTextContainer);
- if (bIsFirstTextContainerFromNewPkt)
- {
- plistPosOfFirstTxtCntnr = m_pTextContainerList->GetTailPosition();
- }
- if (uiREFIndexOfLastChar <
- pNewTextContainer->m_pTextSample->GetTextLenInBytes())
- {
- // /Don't add 1 here; it's end-point exclusive:
- uiStartCharOffset = uiREFIndexOfLastChar;
- pNewTextContainer = new C3GPPTextContainer();
- if(!pNewTextContainer)
- {
- hxrslt = HXR_OUTOFMEMORY;
- break;
- }
- hxrslt = pNewTextContainer->Init(pNewPacket,
- ulPacketContentsBeginTime, m_ulDuration /*=for max end time*/,
- uiStartCharOffset, /*REF*/ uiREFIndexOfLastChar);
- if(FAILED(hxrslt))
- {
- HX_DELETE(pNewTextContainer);
- break;
- }
- // /Make sure we advanced; if not, something's whack:
- HX_ASSERT(uiREFIndexOfLastChar > uiStartCharOffset);
- if (uiREFIndexOfLastChar <= uiStartCharOffset)
- {
- HX_DELETE(pNewTextContainer);
- break; // /Shaggy: "Let's get outta here Scooby!"
- }
- }
- else
- {
- break; // /We're done splitting text up into textContainers
- }
- bIsFirstTextContainerFromNewPkt = FALSE;
- }
- }
- else
- {
- hxrslt = HXR_INVALID_PARAMETER;
- }
- exit:
- return hxrslt;
- }
- // /Now go through prior packet's T.C.'s and establish their
- // end times (which is prior packet's content time ):
- HX_RESULT
- C3GPPTimedTextRenderer::SetPriorPacketTCsEndTimes()
- {
- HX_RESULT hxrslt = HXR_UNEXPECTED;
- if (m_pTextContainerList)
- {
- UINT32 ulEndTime = GetPacketContentTime(m_pLatestPacket);
- LISTPOSITION pos = m_pTextContainerList->GetHeadPosition();
- while (pos)
- {
- C3GPPTextContainer* pTextContainer =
- (C3GPPTextContainer*)m_pTextContainerList->GetNext(pos);
- HX_ASSERT(pTextContainer);
- if (pTextContainer)
- {
- if (pTextContainer->m_pPacket == m_pLatestPacket)
- {
- break; // /We're done w/prior pkt's T.C.(s)
- }
- // /It's initialized to stream's m_ulDuration so
- // it's not set, yet, if it equals that:
- if (m_ulDuration <= pTextContainer->GetEndTime() )
- {
- pTextContainer->m_ulEndTime = ulEndTime;
- HX_ASSERT(pTextContainer->m_ulEndTime > pTextContainer->m_ulBeginTime);
- if (pTextContainer->m_ulEndTime <= pTextContainer->m_ulBeginTime)
- {
- pTextContainer->m_ulEndTime = pTextContainer->m_ulBeginTime + 1;
- }
- }
- }
- }
- }
- return hxrslt;
- }
- // /#define DEBUG_OUT_REDRAWLIST_ACTIVITY
- #if defined(DEBUG_OUT_REDRAWLIST_ACTIVITY)
- #pragma message("====##### undef DEBUG_OUT_REDRAWLIST_ACTIVITY from source tree! #####====")
- static int icount = 0;
- #endif // /DEBUG_OUT_REDRAWLIST_ACTIVITY.
- HX_RESULT
- C3GPPTimedTextRenderer::InsertInRedrawListInTemporalOrder(
- const C3GPPTextContainer* pTextContainer)
- {
- #if defined(DEBUG_OUT_REDRAWLIST_ACTIVITY)
- FILE* pDrawFile = fopen("c:\3gppttInsertIntoRedrawList.txt", icount?"a+":"w");
- if (pDrawFile)
- {
- fprintf(pDrawFile, "at time %lutinserting %p tbegin=%lutend=%lut"
- "prevActivityTime=%lutNextActivityTime=%lun",
- m_ulTimeOfLastTimeSync, pTextContainer, pTextContainer->GetBeginTime(),
- pTextContainer->GetEndTime(), pTextContainer->GetPrevActivityTime(),
- pTextContainer->GetNextActivityTime());
- fclose(pDrawFile);
- icount++;
- }
- #endif // /DEBUG_OUT_REDRAWLIST_ACTIVITY.
- HX_RESULT hxrslt = HXR_OK;
- if (!m_pTextContainerRedrawList)
- {
- m_pTextContainerRedrawList = new CHXSimpleList();
- if (!m_pTextContainerRedrawList)
- {
- hxrslt = HXR_OUTOFMEMORY;
- goto cleanup;
- }
- }
- // /First, find it and remove it if it's already in there:
- RemoveFromRedrawList(pTextContainer);
- if (pTextContainer->GetEndTime() > pTextContainer->GetNextActivityTime())
- {
- // /XXXEH- todo: need to look through list and insert temporally; ties are
- // resolved by making sure that earlier-start-char-index one is first:
- m_pTextContainerRedrawList->AddTail((void*)pTextContainer);
- #if defined(DEBUG_OUT_REDRAWLIST_ACTIVITY)
- pDrawFile = fopen("c:\3gppttInsertIntoRedrawList.txt", icount?"a+":"w");
- if (pDrawFile)
- {
- fprintf(pDrawFile, "t--inserting %p into list.n",
- m_ulTimeOfLastTimeSync, pTextContainer->GetBeginTime(),
- pTextContainer->GetEndTime(), pTextContainer->GetNextActivityTime());
- fclose(pDrawFile);
- icount++;
- }
- #endif // /DEBUG_OUT_REDRAWLIST_ACTIVITY.
- }
- cleanup:
- return hxrslt;
- }
- HX_RESULT
- C3GPPTimedTextRenderer::RemoveFromRedrawList(
- const C3GPPTextContainer* pTextContainer)
- {
- #if defined(DEBUG_OUT_REDRAWLIST_ACTIVITY)
- FILE* pDrawFile = fopen("c:\3gppttInsertIntoRedrawList.txt", icount?"a+":"w");
- if (pDrawFile)
- {
- fprintf(pDrawFile, "at time %lutremoving %p tbegin=%lutend=%lut"
- "prevActivityTime=%lutNextActivityTime=%lun",
- m_ulTimeOfLastTimeSync, pTextContainer, pTextContainer->GetBeginTime(),
- pTextContainer->GetEndTime(), pTextContainer->GetPrevActivityTime(),
- pTextContainer->GetNextActivityTime());
- fclose(pDrawFile);
- icount++;
- }
- #endif // /DEBUG_OUT_REDRAWLIST_ACTIVITY.
- HX_RESULT hxrslt = HXR_UNEXPECTED;
- LISTPOSITION pos = NULL;
- if (m_pTextContainerRedrawList && pTextContainer)
- {
- hxrslt = HXR_OK;
- // /Find it and remove it if it's in there:
- pos = m_pTextContainerRedrawList->Find((void*)pTextContainer);
- if (pos)
- {
- m_pTextContainerRedrawList->RemoveAt(pos);
- }
- }
- return hxrslt;
- }
- #if defined(USE_DIB_SECTION) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- /****************************************************************************
- * IUnknown::AddRef ref: pncom.h
- *
- * Get new space for bitmapinfo struct (usually plus some bytes for color)
- */
- BOOL
- C3GPPTimedTextRenderer::AllocNewLPBITMAPINFO(UINT32 ulNumBytes)
- {
- if (m_LPBITMAPINFO)
- { //This SHOULD have been initialized to NULL, so free it:
- delete m_LPBITMAPINFO;
- m_LPBITMAPINFO = NULL;
- }
- m_LPBITMAPINFO = (LPBITMAPINFO) new BYTE[ulNumBytes];
- return (NULL != m_LPBITMAPINFO);
- }
- #endif //USE_DIB_SECTION. _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- // IUnknown COM Interface Methods
- /****************************************************************************
- * IUnknown::AddRef ref: pncom.h
- *
- * This routine increases the object reference count in a thread safe
- * manner. The reference count is used to manage the lifetime of an object.
- * This method must be explicitly called by the user whenever a new
- * reference to an object is used.
- */
- STDMETHODIMP_(UINT32)
- C3GPPTimedTextRenderer::AddRef()
- {
- return InterlockedIncrement(&m_lRefCount);
- }
- /****************************************************************************
- * IUnknown::Release ref: pncom.h
- *
- * This routine decreases the object reference count in a thread safe
- * manner, and deletes the object if no more references to it exist. It must
- * be called explicitly by the user whenever an object is no longer needed.
- */
- STDMETHODIMP_(UINT32)
- C3GPPTimedTextRenderer::Release()
- {
- if (InterlockedDecrement(&m_lRefCount) > 0)
- {
- return m_lRefCount;
- }
- delete this;
- return 0;
- }
- /****************************************************************************
- * IUnknown::QueryInterface ref: pncom.h
- *
- * This routine indicates which interfaces this object supports. If a given
- * interface is supported, the object's reference count is incremented, and
- * a reference to that interface is returned. Otherwise a NULL object and
- * error code are returned. This method is called by other objects to
- * discover the functionality of this object.
- */
- STDMETHODIMP
- C3GPPTimedTextRenderer::QueryInterface(REFIID riid, void** ppvObj)
- {
- if (IsEqualIID(riid, IID_IUnknown))
- {
- AddRef();
- *ppvObj = (IUnknown*)(IHXPlugin*)this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IHXPlugin))
- {
- AddRef();
- *ppvObj = (IHXPlugin*)this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IHXRenderer))
- {
- AddRef();
- *ppvObj = (IHXRenderer*)this;
- return HXR_OK;
- }
- else if (IsEqualIID(riid, IID_IHXSiteUser))
- {
- AddRef();
- *ppvObj = (IHXSiteUser*)this;
- return HXR_OK;
- }
- #if defined (HELIX_FEATURE_MISU)
- else if (IsEqualIID(riid, IID_IHXSiteUserSupplier))
- {
- if (m_pMISUS)
- {
- return m_pMISUS->QueryInterface(IID_IHXSiteUserSupplier,ppvObj);
- }
- else
- {
- *ppvObj = NULL;
- return HXR_UNEXPECTED;
- }
- }
- #endif // / HELIX_FEATURE_MISU.
- *ppvObj = NULL;
- return HXR_NOINTERFACE;
- }
- HX_RESULT
- C3GPPTimedTextRenderer::CreateOffscreenBuffer(HXxSize& hxsize)
- {
- HX_RESULT retVal = HXR_OK;
-
- #if defined(_SYMBIAN) // / -----vvvvvvvvvvvvvvvvvvvvvvvvvv-----
- // /Create offscreen bitmap.
- HX_ASSERT(!m_pBitMap);
- HX_DELETE(m_pBitMap);
- m_pBitMap = new CFbsBitmap();
- HX_ASSERT(m_pBitMap);
- if(!m_pBitMap)
- {
- retVal = HXR_OUTOFMEMORY;
- }
- else
- {
- // /XXXEH- EColor16M (24-bit) means 3 bytes are allocated per pixel.
- TInt err = m_pBitMap->Create(TSize(hxsize.cx, hxsize.cy),
- #if (12 == HX_3GPPTT_DEFAULT_bits_PER_PIXEL)
- EColor4K /*12-bit*/
- #elif (16 == HX_3GPPTT_DEFAULT_bits_PER_PIXEL)
- EColor64K /*16-bit*/
- #elif (24 == HX_3GPPTT_DEFAULT_bits_PER_PIXEL)
- EColor16M /*24-bit*/
- #else
- #error: cant create CFbsBitmap with color depth > 24
- #endif // /12 , elif 16 , elif 24 == HX_3GPPTT_DEFAULT_bits_PER_PIXEL else...
- );
- HX_ASSERT( err == KErrNone );
-
- if( err != KErrNone )
- {
- retVal = HXR_OUTOFMEMORY;
- }
- else
- {
- m_pDrawOutputBuffer = (UCHAR*)m_pBitMap->DataAddress();
- m_ulDrawOutputBufferSizeInBytes = m_ulBitsPerPixel *
- (UINT32)hxsize.cx * (UINT32)hxsize.cy / 8;
- // /Create the offscreen GC for DrawText() calls:
- m_pGCOffscreen = NULL;
- CFbsBitmapDevice* pBsBitmapDevice =
- CFbsBitmapDevice::NewL(m_pBitMap);
- HX_ASSERT(pBsBitmapDevice);
- if (pBsBitmapDevice)
- {
- err = pBsBitmapDevice->CreateContext(m_pGCOffscreen);
- HX_ASSERT(KErrNone == err);
- if (KErrNone != err)
- {
- HX_ASSERT(false);
- m_pGCOffscreen = NULL;
- }
- }
- if (!pBsBitmapDevice || !m_pGCOffscreen)
- {
- retVal = HXR_OUTOFMEMORY;// /XXXEH- can fail for other reasons?
- }
- }
- }
- HX_ASSERT(retVal==HXR_OK);
- if( FAILED(retVal) )
- {
- HX_DELETE(m_pBitMap);
- m_pDrawOutputBuffer = NULL;
- m_ulDrawOutputBufferSizeInBytes = 0;
- }
- #elif !defined(USE_DIB_SECTION) // /else of _SYMBIAN ------------------------------------
- // / Allocate an output buffer if none yet exists:
- if (!m_pDrawOutputBuffer && m_size.cx > 0 && m_size.cy > 0)
- {
- // Compute the size of the output buffer
- UINT32 ulDataWidth = (UINT32)m_size.cx * m_ulBitsPerPixel / 8;
- // /Round up to nearest multiple of 4:
- UINT32 ulPaddedWidth = (ulDataWidth + 3) & ~3;
- m_ulDrawOutputBufferSizeInBytes = ulPaddedWidth * (UINT32)m_size.cy;
- m_pDrawOutputBuffer = new BYTE [m_ulDrawOutputBufferSizeInBytes];
- if (!m_pDrawOutputBuffer)
- {
- retVal = HXR_OUTOFMEMORY;
- goto cleanup;
- }
- /* Clear the output buffer */
- memset(m_pDrawOutputBuffer, 0, m_ulDrawOutputBufferSizeInBytes);
- }
- #else // /else USE_DIB_SECTION (_WINDOWS): // / ------------------------------------
- if (!m_hBitmap)
- {
- HDC hDC = (HDC)m_pDeviceContextMemory;
- m_BITMAPINFOHEADER.biSize = sizeof(BITMAPINFOHEADER);
- m_BITMAPINFOHEADER.biWidth = m_size.cx;
- m_BITMAPINFOHEADER.biHeight = m_size.cy;
- m_BITMAPINFOHEADER.biPlanes = 1; //Must be 1.
- m_BITMAPINFOHEADER.biBitCount = 32; //Bit depth.
- m_BITMAPINFOHEADER.biCompression = HX_RGB;
- m_BITMAPINFOHEADER.biSizeImage =//size of image (bytes):
- m_size.cx * m_size.cy *
- (m_BITMAPINFOHEADER.biBitCount/8);
- m_BITMAPINFOHEADER.biClrUsed = 0;
- m_BITMAPINFOHEADER.biClrImportant = 0;
- m_BITMAPINFOHEADER.biXPelsPerMeter = 0;
- m_BITMAPINFOHEADER.biYPelsPerMeter = 0;
- //Allocate space for a BITMAPINFOHEADER and the 3 color masks :
- if (NULL == m_LPBITMAPINFO)
- {
- AllocNewLPBITMAPINFO(sizeof(BITMAPINFOHEADER) +
- 4 * sizeof(ULONG32));
- if (!m_LPBITMAPINFO)
- {
- retVal = HXR_OUTOFMEMORY; //malloc failed.
- goto cleanup;
- }
- memset(m_LPBITMAPINFO, 0, sizeof(BITMAPINFOHEADER) +
- 4 * sizeof(ULONG32));
- ULONG32* colorMasksPtr = //For RGB 888 format:
- (ULONG32*)m_LPBITMAPINFO->bmiColors;
- colorMasksPtr[0] = 0x00ff0000; //8 bits for red.
- colorMasksPtr[1] = 0x0000ff00; //8 bits for green.
- colorMasksPtr[2] = 0x000000ff; //8 bits for blue.
- }
- //Make sure we're pointing at the new info (using the default
- // assignment operator since there are no ptrs in
- // BITMAPINFOHEADER struct):
- m_LPBITMAPINFO->bmiHeader = m_BITMAPINFOHEADER;
- m_hBitmap = ::CreateDIBSection(NULL, m_LPBITMAPINFO,
- DIB_RGB_COLORS, (void**)&m_pDrawOutputBuffer, NULL, 0);
- if (!m_hBitmap)
- {
- retVal = HXR_OUTOFMEMORY;
- goto cleanup;
- }
- m_ulDrawOutputBufferSizeInBytes = m_BITMAPINFOHEADER.biSizeImage;
- m_hOldBitmap = (HBITMAP)(::SelectObject(hDC, m_hBitmap));
- if (!m_hOldBitmap)
- {
- retVal = HXR_OUTOFMEMORY;
- goto cleanup;
- }
- }
- #endif // /end if _SYMBIAN elif !USE_DIB_SECTION else (USE_DIB_SECTION) _____^^^^^^^^^^^^^^^^^^^^^^^^^^_____
- cleanup:
- return retVal;
- }
- HX_RESULT
- C3GPPTimedTextRenderer::RecomputeTextContainerDrawList(UINT32 ulCurTime)
- {
- // /Adjust m_pTextContainerListFutureTimePos so that it points
- // to the text that is current at time ulCurTime:
- if (m_pTextContainerRedrawList)
- {
- // /The text containers inside are owned by (& will be cleaned up by)
- // the m_pTextContainerList:
- m_pTextContainerRedrawList->RemoveAll();
- }
- // /Helps fix many seeking problems (Helix Issue 667):
- if (m_pTextContainerList)
- {
- C3GPPTextContainer* pTextContainer = NULL;
- // /Reset draw update times and find the time-current T.C.:
- LISTPOSITION pos = m_pTextContainerList->GetHeadPosition();
- while (pos)
- {
- m_pTextContainerListFutureTimePos = pos;
- pTextContainer =
- (C3GPPTextContainer*)m_pTextContainerList->GetNext(pos);
- HX_ASSERT(pTextContainer);
- pTextContainer->m_ulPrevDrawUpdateTimeOffset = HX_3GPPTT_INVALID_TIME;
- pTextContainer->m_ulNextDrawUpdateTimeOffset = 0;
- if (pTextContainer &&
- pTextContainer->GetBeginTime() <= ulCurTime &&
- pTextContainer->GetEndTime() > ulCurTime)
- {
- break; // /We found the first time-current one.
- }
- }
- while (pos) // /pos already points to next due to GetNext, above
- {
- LISTPOSITION posRemove = pos;
- pTextContainer =
- (C3GPPTextContainer*)m_pTextContainerList->GetNext(pos);
- HX_ASSERT(pTextContainer);
- if (pTextContainer)
- {
- if (!m_bGotAllPacketsAlready)
- {
- // /And now get rid of all later-than-the-seek-to-time
- // text since it will be resent by the ff if it's needed:
- HX_DELETE(pTextContainer);
- m_pTextContainerList->RemoveAt(posRemove);
- }
- else
- {
- // /If all packets have arrived then we have all the
- // data already and we'll just refuse all future pkts
- // in OnPacket() calls so just reset the later-than-
- // the-seek-to-time text's draw update variables:
- pTextContainer->m_ulPrevDrawUpdateTimeOffset =
- HX_3GPPTT_INVALID_TIME;
- pTextContainer->m_ulNextDrawUpdateTimeOffset = 0;
- }
- }
- else
- {
- // /Remove invalid (NULL) T.C. from list:
- m_pTextContainerList->RemoveAt(posRemove);
- }
- }
- }
- return HXR_OK;
- }