brushrnd.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:17k
源码类别:

Symbian

开发平台:

Visual C++

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