brushrnd.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:17k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. // include
  36. #include "hxtypes.h"
  37. #include "hxwintyp.h"
  38. #include "hxcom.h"
  39. #include "hxcomm.h"
  40. #include "ihxpckts.h"
  41. #include "hxplugn.h"
  42. #include "hxrendr.h"
  43. #include "hxvsurf.h"
  44. #include "hxhyper.h"
  45. #include "hxwin.h"
  46. #include "hxver.h"
  47. #include "hxasm.h"
  48. #include "hxprefs.h"
  49. #include "hxmon.h"
  50. #include "hxupgrd.h"
  51. #include "hxcore.h"
  52. #include "hxerror.h"
  53. // pnmisc
  54. #include "baseobj.h"
  55. #include "hxparse.h"
  56. // pxcomlib
  57. #include "pxtransp.h"
  58. // baserend
  59. #include "baserend.h"
  60. #include "vbasernd.h"
  61. // brushrnd
  62. #include "brushrnd.h"
  63. #include "brushrnd.ver"
  64. // pndebug
  65. #include "errdbg.h"
  66. #include "hxheap.h"
  67. // runtime
  68. #include "hlxclib/string.h"
  69. #ifdef _DEBUG
  70. #undef HX_THIS_FILE
  71. static const char HX_THIS_FILE[] = __FILE__;
  72. #endif
  73. const char* const CBrushRenderer::m_pszName        = "Brush";
  74. const char* const CBrushRenderer::m_pszDescription = "RealNetworks Brush Renderer Plugin";
  75. const char* const CBrushRenderer::m_ppszMimeType[] = {"application/vnd.rn-brushstream", NULL};
  76. CBrushRenderer::CBrushRenderer() : CRNVisualBaseRenderer()
  77. {
  78.     m_ulColor              = 0x00000000;
  79.     m_pHeader              = NULL;
  80.     m_ulChromaKey          = 0x00000000;
  81.     m_ulChromaKeyTolerance = 0x00000000;
  82.     m_ulChromaKeyOpacity   = 0;
  83.     m_ulLastColor          = 0;
  84.     m_pucBuffer            = NULL;
  85.     m_bFirstDraw           = TRUE;
  86.     m_bChromaKeySpecified  = FALSE;
  87.     m_bNullBrush           = FALSE;
  88. };
  89. CBrushRenderer::~CBrushRenderer()
  90. {
  91.     HX_DELETE(m_pHeader);
  92.     HX_VECTOR_DELETE(m_pucBuffer);
  93. };
  94. STDMETHODIMP CBrushRenderer::QueryInterface(REFIID riid, void** ppvObj)
  95. {
  96.     // If we ever have any new interfaces to add which
  97.     // are specific to the brush renderer, then we'll need
  98.     // to add them here. Until then we simply proxy the
  99.     // visual base renderer.
  100.     return CRNVisualBaseRenderer::QueryInterface(riid, ppvObj);
  101. }
  102. STDMETHODIMP_(UINT32) CBrushRenderer::AddRef()
  103. {
  104.     return CRNVisualBaseRenderer::AddRef();
  105. }
  106. STDMETHODIMP_(UINT32) CBrushRenderer::Release()
  107. {
  108.     return CRNVisualBaseRenderer::Release();
  109. }
  110. STDMETHODIMP CBrushRenderer::OnHeader(IHXValues* pHeader)
  111. {
  112.     HX_RESULT retVal = HXR_FAIL;
  113.     if (pHeader)
  114.     {
  115.         // Check presentation stream and content versions
  116.         retVal = CheckStreamVersions(pHeader);
  117.         if (SUCCEEDED(retVal))
  118.         {
  119.             // Allocate a bitmap info header
  120.             HX_DELETE(m_pHeader);
  121.             m_pHeader = new HXBitmapInfoHeader;
  122.             if (m_pHeader)
  123.             {
  124.                 // Set up the bitmap info header
  125.                 m_pHeader->biSize          = 40;
  126.                 m_pHeader->biWidth         = 1;
  127.                 m_pHeader->biHeight        = 1;
  128.                 m_pHeader->biPlanes        = 1;
  129.                 m_pHeader->biBitCount      = 32;
  130.                 m_pHeader->biCompression   = HX_RGB;
  131.                 m_pHeader->biSizeImage     = 0;
  132.                 m_pHeader->biXPelsPerMeter = 0;
  133.                 m_pHeader->biYPelsPerMeter = 0;
  134.                 m_pHeader->biClrUsed       = 0;
  135.                 m_pHeader->biClrImportant  = 0;
  136.                 m_pHeader->rcolor          = 0;
  137.                 m_pHeader->gcolor          = 0;
  138.                 m_pHeader->bcolor          = 0;
  139.                 // See if we are a null brush
  140.                 UINT32 ulTmp = 0;
  141.                 HX_RESULT rv = pHeader->GetPropertyULONG32("NullBrush", ulTmp);
  142.                 if (SUCCEEDED(rv) && ulTmp)
  143.                 {
  144.                     m_bNullBrush = TRUE;
  145.                 }
  146.                 // Get the opaque data from the stream header
  147.                 IHXBuffer* pBuffer = NULL;
  148.                 pHeader->GetPropertyBuffer("OpaqueData", pBuffer);
  149.                 if (pBuffer)
  150.                 {
  151.                     // XXXMEH - TODO - make more robust parsing. Since
  152.                     // we are creating this "file" in the SMIL renderer,
  153.                     // then we can afford to do simple parsing.
  154.                     const char* pszStr = (const char*) pBuffer->GetBuffer();
  155.                     char*       pTmp   = new char [strlen(pszStr) + 1];
  156.                     if (pTmp)
  157.                     {
  158.                         // Copy the string
  159.                         strcpy(pTmp, pszStr); /* Flawfinder: ignore */
  160.                         // Look for " separators
  161.                         const char* pSep   = """;
  162.                         char*       pToken = strtok(pTmp, pSep);
  163.                         BOOL        bNext  = FALSE;
  164.                         while (pToken)
  165.                         {
  166.                             if (bNext)
  167.                             {
  168.                                 UINT32    ulColor = 0;
  169.                                 HX_RESULT rv      = HXParseColorUINT32(pToken, ulColor);
  170.                                 if (SUCCEEDED(rv))
  171.                                 {
  172.                                     m_ulColor = ulColor;
  173.                                     // Initialize some persistent properties
  174.                                     CRNBaseRenderer::SetPropertyULONG32("color",             m_ulColor);
  175.                                     CRNBaseRenderer::SetPropertyULONG32("mediaOpacity",      255);
  176.                                     CRNBaseRenderer::SetPropertyULONG32("backgroundOpacity", 255);
  177.                                 }
  178.                                 break;
  179.                             }
  180.                             if (strstr(pToken, "color"))
  181.                             {
  182.                                 bNext = TRUE;
  183.                             }
  184.                             pToken = strtok(NULL, pSep);
  185.                         }
  186.                     }
  187.                     HX_VECTOR_DELETE(pTmp);
  188.                 }
  189.                 HX_RELEASE(pBuffer);
  190.             }
  191.             else
  192.             {
  193.                 retVal = HXR_OUTOFMEMORY;
  194.             }
  195.         }
  196.         else
  197.         {
  198.             AddMimeToUpgradeCollection(m_ppszMimeType[0]);
  199.         }
  200.     }
  201.     return retVal;
  202. }
  203. STDMETHODIMP CBrushRenderer::OnPacketNoOffset(IHXPacket* pPacket)
  204. {
  205.     HX_RESULT retVal = HXR_OK;
  206.     return retVal;
  207. }
  208. STDMETHODIMP CBrushRenderer::OnTimeSyncOffset(UINT32 ulTime)
  209. {
  210.     // We should force a redraw ONLY on
  211.     // the first time sync
  212.     if (m_bFirstDraw && !m_bNullBrush)
  213.     {
  214.         // Redraw our data by damaging the entire area of our data
  215.         HXxSize size;
  216.         m_pSite->GetSize(size);
  217.         HXxRect cRect = {0, 0, size.cx, size.cy};
  218.         m_pSite->DamageRect(cRect);
  219.         m_pSite->ForceRedraw();
  220.         // Clear the first draw flag
  221.         m_bFirstDraw = FALSE;
  222.     }
  223.     return HXR_OK;
  224. }
  225. STDMETHODIMP CBrushRenderer::GetDisplayType(REF(HX_DISPLAY_TYPE) rulFlags,
  226.                                             REF(IHXBuffer*)      pBuffer)
  227. {
  228.     if (m_bNullBrush)
  229.     {
  230.         rulFlags = HX_DISPLAY_NONE;
  231.     }
  232.     else
  233.     {
  234.         rulFlags = GetDisplayFlags();
  235.     }
  236.     return HXR_OK;
  237. }
  238. STDMETHODIMP CBrushRenderer::GetWindowSize(REF(HXxSize) rSize)
  239. {
  240.     rSize.cx = 1;
  241.     rSize.cy = 1;
  242.     return HXR_OK;
  243. }
  244. STDMETHODIMP CBrushRenderer::IsMouseOverActiveLink(INT16 x, INT16 y, REF(BOOL) rbActive, REF(IHXBuffer*) rpLink)
  245. {
  246.     HX_RESULT retVal = HXR_OK;
  247.     rbActive = FALSE;
  248.     return retVal;
  249. }
  250. STDMETHODIMP CBrushRenderer::RMASurfaceUpdate(IHXVideoSurface* pSurface)
  251. {
  252.     HX_RESULT retVal = HXR_FAIL;
  253.     if (pSurface && m_pHeader && !m_bNullBrush)
  254.     {
  255.         retVal = SetupBuffer();
  256.         if (SUCCEEDED(retVal))
  257.         {
  258.             // Set up the src and dst rect
  259.             HXxRect rSrcRect = {0, 0, m_pHeader->biWidth, m_pHeader->biHeight};
  260.             HXxRect rDstRect = rSrcRect;
  261.             // Blit to the video surface
  262.             retVal = pSurface->Blt(m_pucBuffer,
  263.                                    m_pHeader,
  264.                                    rDstRect,
  265.                                    rSrcRect);
  266.         }
  267.     }
  268.     return retVal;
  269. }
  270. STDMETHODIMP CBrushRenderer::HandleClick(INT16 x, INT16 y)
  271. {
  272.     return HXR_OK;
  273. }
  274. STDMETHODIMP CBrushRenderer::SetPropertyULONG32(const char* pName, ULONG32 ulVal)
  275. {
  276.     HX_RESULT retVal = HXR_OK;
  277.     if (pName)
  278.     {
  279.         // Clear the flag
  280.         BOOL bChromaKeyUpdate = FALSE;
  281.         // Switch based on property name
  282.         if (!strcmp(pName, "color"))
  283.         {
  284.             // Preserve the current alpha from the
  285.             // color and set the color from ulVal
  286.             m_ulColor = (m_ulColor & 0xFF000000) |
  287.                         (ulVal     & 0x00FFFFFF);
  288.         }
  289.         else if (!strcmp(pName, "mediaOpacity") ||
  290.                  !strcmp(pName, "backgroundOpacity"))
  291.         {
  292.             // Cap the opacity
  293.             if (ulVal > 255) ulVal = 255;
  294.             // Update the color
  295.             m_ulColor = (m_ulColor             & 0x00FFFFFF) |
  296.                         (((255 - ulVal) << 24) & 0xFF000000);
  297.         }
  298.         else if (!strcmp(pName, "chromaKey"))
  299.         {
  300.             // Save the value
  301.             m_ulChromaKey         = ulVal;
  302.             m_bChromaKeySpecified = TRUE;
  303.             // We do need to update the color
  304.             bChromaKeyUpdate = TRUE;
  305.         }
  306.         else if (!strcmp(pName, "chromaKeyTolerance"))
  307.         {
  308.             // Save the value
  309.             m_ulChromaKeyTolerance = ulVal & 0x00FFFFFF;
  310.             // If we have a chroma key already specified, then update
  311.             if (m_bChromaKeySpecified)
  312.             {
  313.                 bChromaKeyUpdate = TRUE;
  314.             }
  315.         }
  316.         else if (!strcmp(pName, "chromaKeyOpacity"))
  317.         {
  318.             // Cap the value
  319.             if (ulVal > 255) ulVal = 255;
  320.             // Save the value
  321.             m_ulChromaKeyOpacity = ulVal;
  322.             // If we have a chroma key already specified, then update
  323.             if (m_bChromaKeySpecified)
  324.             {
  325.                 bChromaKeyUpdate = TRUE;
  326.             }
  327.         }
  328.         // If we need to update the color because of
  329.         // chroma key changes, then do it now
  330.         if (bChromaKeyUpdate &&
  331.             DoesChromaKeyMatch(m_ulColor, m_ulChromaKey, m_ulChromaKeyTolerance))
  332.         {
  333.             // Update the color
  334.             m_ulColor = (m_ulColor & 0x00FFFFFF) |
  335.                         (((255 - m_ulChromaKeyOpacity) << 24) & 0xFF000000);
  336.         }
  337.         // Now pass this on to our base class
  338.         retVal = CRNBaseRenderer::SetPropertyULONG32(pName, ulVal);
  339.     }
  340.     else
  341.     {
  342.         retVal = HXR_FAIL;
  343.     }
  344.     return retVal;
  345. }
  346. HX_RESULT STDAPICALLTYPE CBrushRenderer::HXCreateInstance(IUnknown** ppIUnknown)
  347. {
  348.     HX_RESULT retVal = HXR_FAIL;
  349.     if (ppIUnknown)
  350.     {
  351.         // Create the object
  352.         CBrushRenderer* pObj = new CBrushRenderer();
  353.         if (pObj)
  354.         {
  355.             // QI for IUnknown
  356.             retVal = pObj->QueryInterface(IID_IUnknown, (void**) ppIUnknown);
  357.         }
  358.     }
  359.     return retVal;
  360. }
  361. HX_RESULT STDAPICALLTYPE CBrushRenderer::CanUnload2()
  362. {
  363.     return ((CHXBaseCountingObject::ObjectsActive() > 0) ? HXR_FAIL : HXR_OK );
  364. }
  365. HX_RESULT CBrushRenderer::RMASurfaceUpdate2(IHXSubRectVideoSurface* pSurface,
  366.                                             HXxRect*                 pExtents,
  367.                                             HXxBoxRegion*              pDirtyRegion)
  368. {
  369.     HX_RESULT retVal = HXR_FAIL;
  370.     if (pSurface && m_pHeader && !m_bNullBrush)
  371.     {
  372.         retVal = SetupBuffer();
  373.         if (SUCCEEDED(retVal))
  374.         {
  375.             retVal = pSurface->BltSubRects(m_pucBuffer,
  376.                                            m_pHeader,
  377.                                            pDirtyRegion,
  378.                                            pDirtyRegion,
  379.                                            1.0,1.0 );
  380.         }
  381.     }
  382.     return retVal;
  383. }
  384. void CBrushRenderer::_AttachSite()
  385. {
  386.     if (m_pSite)
  387.     {
  388.         // Subscribe to the sub rect messages, HX_SURFACE_UPDATE2.
  389.         IHXSubRectSite* pSubRectSite = NULL;
  390.         m_pSite->QueryInterface(IID_IHXSubRectSite, (void**) &pSubRectSite);
  391.         if (pSubRectSite)
  392.         {
  393.             // If so, since IHXSubRectSite inheirits from IHXSite, lets
  394.             // just swap the pointers and sign up for the service.
  395.             HX_RELEASE(m_pSite);
  396.             m_pSite = pSubRectSite;
  397.             pSubRectSite->SendSubRectMessages(TRUE);
  398.         }
  399.     }
  400. }
  401. HX_RESULT CBrushRenderer::SetupBuffer()
  402. {
  403.     HX_RESULT retVal = HXR_FAIL;
  404.     if (m_pSite && m_pHeader)
  405.     {
  406.         // Get the site's current size
  407.         HXxSize cSize = {0, 0};
  408.         m_pSite->GetSize(cSize);
  409.         // Make sure the site has non-zero dimensions
  410.         if (cSize.cx > 0 && cSize.cy > 0)
  411.         {
  412.             // Do we need to allocate a buffer?
  413.             BOOL bAllocated = FALSE;
  414.             if (!m_pucBuffer                    ||
  415.                 m_pHeader->biWidth  != cSize.cx ||
  416.                 m_pHeader->biHeight != cSize.cy)
  417.             {
  418.                 UINT32 ulNumBytes = (UINT32) cSize.cx * cSize.cy * 4;
  419.                 HX_VECTOR_DELETE(m_pucBuffer);
  420.                 m_pucBuffer = new BYTE [ulNumBytes];
  421.                 if (m_pucBuffer)
  422.                 {
  423.                     m_pHeader->biWidth     = cSize.cx;
  424.                     m_pHeader->biHeight    = cSize.cy;
  425.                     m_pHeader->biSizeImage = ulNumBytes;
  426.                     bAllocated             = TRUE;
  427.                 }
  428.             }
  429.             if (m_pucBuffer)
  430.             {
  431.                 // Do we need to fill in the color?
  432.                 if (bAllocated || m_ulLastColor != m_ulColor)
  433.                 {
  434.                     // Fill in the buffer
  435.                     UINT32  ulNumPix = (UINT32) cSize.cx * cSize.cy;
  436.                     UINT32* pPix     = (UINT32*) m_pucBuffer;
  437.                     while (ulNumPix--)
  438.                     {
  439.                         *pPix++ = m_ulColor;
  440.                     }
  441.                     // Save this color
  442.                     m_ulLastColor = m_ulColor;
  443.                     // Set the bitmap info header compression
  444.                     m_pHeader->biCompression = (m_ulColor & 0xFF000000 ? HX_ARGB : HX_RGB);
  445.                 }
  446.                 // Clear the return value
  447.                 retVal = HXR_OK;
  448.             }
  449.         }
  450.     }
  451.     return retVal;
  452. }
  453. STDMETHODIMP CBrushRenderer::GetName(REF(const char*) rpszName)
  454. {
  455.     rpszName = (const char*) m_pszName;
  456.     return HXR_OK;
  457. }
  458. STDMETHODIMP CBrushRenderer::GetDescription(REF(const char*) rpszDescription)
  459. {
  460.     rpszDescription = (const char*) m_pszDescription;
  461.     return HXR_OK;
  462. }
  463. STDMETHODIMP CBrushRenderer::GetMimeTypes(REF(const char**) rppszMimeType)
  464. {
  465.     rppszMimeType = (const char**) m_ppszMimeType;
  466.     return HXR_OK;
  467. }
  468. STDMETHODIMP_(UINT32) CBrushRenderer::GetPluginVersion()
  469. {
  470.     return TARVER_ULONG32_VERSION;
  471. }
  472. STDMETHODIMP_(UINT32) CBrushRenderer::GetInitialGranularity()
  473. {
  474.     return 200;
  475. }