📄 rtrender.cpp
字号:
// Method:// IHXRenderer::OnBuffering// Purpose:// Called by client engine to inform the renderer that buffering// of data is occuring. The render is informed of the reason for// the buffering (start-up of stream, seek has occured, network// congestion, etc.), as well as percentage complete of the // buffering process.//STDMETHODIMP CRealTextRenderer::OnBuffering(ULONG32 ulFlags, UINT16 unPercentComplete){ m_pMutex->Lock();#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"OnBuffering();" " Setting m_PlayState to Paused\n"); }#endif#endif m_PlayState = Paused; m_pMutex->Unlock(); return HXR_OK;}/////////////////////////////////////////////////////////////////////////// Method:// IHXRenderer::GetDisplayType// Purpose:// Called by client engine to ask the renderer for it's preferred// display type. When layout information is not present, the // renderer will be asked for it's prefered display type. Depending// on the display type a buffer of additional information may be // needed. This buffer could contain information about preferred// window size.//STDMETHODIMP CRealTextRenderer::GetDisplayType( REF(HX_DISPLAY_TYPE) ulFlags, REF(IHXBuffer*) pBuffer){ ulFlags = HX_DISPLAY_WINDOW | HX_DISPLAY_SUPPORTS_RESIZE | HX_DISPLAY_SUPPORTS_FULLSCREEN; return HXR_OK;}/************************************************************************ * Method: * IHXRenderer::OnEndofPackets * Purpose: * Called by client engine to inform the renderer that all the * packets have been delivered. However, if the user seeks before * EndStream() is called, renderer may start getting packets again * and the client engine will eventually call this function again. */STDMETHODIMP CRealTextRenderer::OnEndofPackets(void){#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"OnEndofPackets()\n"); }#endif#endif if(m_pTextWindow) { //In case the last line is not yet centered because it doesn't // know it's a complete line yet, make sure it is centered (noting // that this function will only center text that hasn't yet been // centered and that is between a <center> and a </center> tag): m_pTextWindow->CenterPriorLine(); } return HXR_OK;}/************************************************************************ * Method: * IHXStatistics::Init * Purpose: * Pass registry ID to the caller * */STDMETHODIMPCRealTextRenderer::InitializeStatistics( UINT32 /*IN*/ ulRegistryID){ HX_RESULT rc = HXR_OK; IHXRegistry* pRegistry; if (HXR_OK == m_pContext->QueryInterface(IID_IHXRegistry, (void**)&pRegistry)) { char szRegistryEntry[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */ IHXBuffer* pszRegistryName = NULL; // Get the current registry key name if (HXR_OK == pRegistry->GetPropName(ulRegistryID, pszRegistryName)) { IHXBuffer* pValue = new CHXBuffer(); pValue->AddRef(); SafeSprintf(szRegistryEntry, MAX_DISPLAY_NAME, "%s.name", pszRegistryName->GetBuffer()); pValue->Set((const UCHAR*)zm_pName, strlen(zm_pName) + 1); pRegistry->AddStr(szRegistryEntry, pValue); HX_RELEASE(pValue); HX_RELEASE(pszRegistryName); } HX_RELEASE(pRegistry); } return rc;}/************************************************************************ * Method: * IHXStatistics::Update * Purpose: * Notify the client to update its statistics stored in the registry * */STDMETHODIMP CRealTextRenderer::UpdateStatistics(){ return HXR_OK;}STDMETHODIMPCRealTextRenderer::AttachSite(IHXSite* /*IN*/ pSite){ HX_ASSERT(!m_pMISUSSite); if (m_pMISUSSite) return HXR_UNEXPECTED; m_pMISUSSite = pSite; HX_ASSERT(m_pMISUSSite); if (!m_pMISUSSite) return HXR_UNEXPECTED; m_pMISUSSite->AddRef(); IHXInterruptSafe* pIHXInterruptSafe = NULL; if (HXR_OK == m_pMISUSSite->QueryInterface(IID_IHXInterruptSafe, (void**)&pIHXInterruptSafe)) { // Get the pref to use the optimized scheduler or not BOOL bUseOptimized = TRUE; IHXBuffer* pPrefBuffer; if (m_pPreferences->ReadPref("UseOptimizedScheduler", pPrefBuffer) == HXR_OK) { bUseOptimized = *(pPrefBuffer->GetBuffer()) == '1'; HX_RELEASE(pPrefBuffer); } if (pIHXInterruptSafe->IsInterruptSafe() && bUseOptimized) { HX_RELEASE(m_pOptimizedScheduler); if (HXR_OK != m_pContext->QueryInterface(IID_IHXOptimizedScheduler, (void **) &m_pOptimizedScheduler)) { // just for good luck m_pOptimizedScheduler = NULL; } } } HX_RELEASE(pIHXInterruptSafe); HXxSize rtxFileSpecifiedSize; rtxFileSpecifiedSize.cx = m_txtWin.getWidth(); rtxFileSpecifiedSize.cy = m_txtWin.getHeight(); m_pMISUSSite->SetSize(rtxFileSpecifiedSize); return HXR_OK;}STDMETHODIMPCRealTextRenderer::DetachSite(){ HX_RELEASE(m_pMISUSSite); // We're done with these... if (m_pMISUS) m_pMISUS->ReleaseSingleSiteUser(); HX_RELEASE(m_pMISUS); return HXR_OK;}STDMETHODIMP_(BOOL)CRealTextRenderer::NeedsWindowedSites() { return FALSE; };STDMETHODIMPCRealTextRenderer::HandleEvent(HXxEvent* /*IN*/ pEvent){ pEvent->handled = FALSE; pEvent->result = 0;#ifdef _WINDOWS m_hWnd = (HWND)pEvent->window;#endif#if defined(_UNIX) && (!(defined(_BEOS))) && (!(defined(_MAC_UNIX))) // XEvent* xevent = (XEvent*)pEvent->param1; // what is pEvent->window?#endif switch (pEvent->event) { case HX_MOUSE_ENTER: case HX_MOUSE_LEAVE: case HX_MOUSE_MOVE: { pEvent->handled = TRUE; m_pEvent = pEvent; HXxPoint* mousePt = (HXxPoint*) pEvent->param1; OnMouseMove (0, (INT16)mousePt->x, (INT16)mousePt->y); } break; case HX_PRIMARY_BUTTON_UP: { HXxPoint* mousePt = (HXxPoint*) pEvent->param1; OnLbuttonUp (0, (INT16)mousePt->x, (INT16)mousePt->y); pEvent->handled = TRUE; } break;#ifdef _WINDOWS case WM_SETCURSOR: { pEvent->handled = TRUE; if(m_bNeedToSetHyperlinkHandCursor) { m_hPreHyperlinkCursor = SetCursor(m_hHyperlinkCursor); } else { //Fix for PR-15110; we can no longer count on //Hxgui to handle the setting of the cursor (back to // arrow cursor), so we have to do it ourselves: SetCursor(LoadCursor(NULL, IDC_ARROW)); } } break;#endif case HX_SURFACE_UPDATE: { m_pEvent = pEvent; Draw(); pEvent->handled = TRUE; m_pEvent = NULL; } break; } return HXR_OK;}/////////////////////////////////////////////////////////////////////////// Method:// CRealTextRenderer::Draw// Purpose:// //void CRealTextRenderer::Draw(){ // changed the following from "get[Width|Height]()" // to "getWindow[Width|Height]()" so that the actual valid area // in which to draw (which may be smaller than specified in the // header of an .rtx file if the metafile's width&height override it: //m_txtWin width,height were set in RealTextRenderer::OnHeader(), above: HXxSize siteWinSize; BOOL bSizeChanged = FALSE; if(m_txtWin.m_bHandlingWindowResizing) { //ignore this draw request since we're in the process of // re-allocating the bitmap in a not-yet-finished prior // CRealTextRenderer::Draw() call, below. return; } m_pMISUSSite->GetSize(siteWinSize); float widthRatioNewOverOrig = 1.0; LONG32 lEffectiveCrawlRate = m_txtWin.getCrawlRate(); float heightRatioNewOverOrig = 1.0; LONG32 lEffectiveScrollRate = m_txtWin.getScrollRate(); //Since we are drawing each word at (x,y) assuming a fixed // rate of motion, we need to adjust the rates of motion if our // current visible window is different in size from our original // size, in other words we need to transform the rates of motion // if we have transformed the coordinate system: if(lEffectiveCrawlRate && (m_txtWin.getWidth() != siteWinSize.cx) && m_txtWin.getWidth()!=0) { widthRatioNewOverOrig = (float)siteWinSize.cx / (float)m_txtWin.getWidth(); lEffectiveCrawlRate = LONG32((float)lEffectiveCrawlRate * widthRatioNewOverOrig); } if(lEffectiveScrollRate && (m_txtWin.getHeight() != siteWinSize.cy) && m_txtWin.getHeight()!=0) { heightRatioNewOverOrig = (float)siteWinSize.cy / (float)m_txtWin.getHeight(); lEffectiveScrollRate = LONG32((float)lEffectiveScrollRate * heightRatioNewOverOrig); } if (m_lastKnownSize.cx != siteWinSize.cx || m_lastKnownSize.cy != siteWinSize.cy) { bSizeChanged = TRUE; // /This if() block helps fix PR 59951. If this is plain text from // in-line data in a SMIL file, then we don't want to scale the text // when the window resizes. Instead, change where wordwraps happen // to accommodate the new window dimensions: // /(Now, we do same for .txt streams): if (RealTextRenderer::isPlainText() && (m_txtWin.getWidth() != siteWinSize.cx || m_txtWin.getHeight() != siteWinSize.cy) ) { m_txtWin.overrideDefaultWindowWidth(siteWinSize.cx); m_txtWin.overrideDefaultWindowHeight(siteWinSize.cy); }#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile) { if(m_txtWin.getDebugFlags()&RT_RENDER_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"\nCRealTextRenderer::Draw()\n" " SiteWinSize changed from %d*%d to %d*%d\n", m_lastKnownSize.cx, m_lastKnownSize.cy, siteWinSize.cx, siteWinSize.cy); } fflush(m_logfile); }#endif#endif } LONG32 lXAdditionalRoomForMotion = 0L; LONG32 lYAdditionalRoomForMotion = 0L;#if defined(DO_CPU_FRIENDLY_SCROLLING) /* { */ lXAdditionalRoomForMotion = //XXXEH- no neg crawlRate handled yet... (lEffectiveCrawlRate <= 0? 0 : siteWinSize.cx/2); //LONG32-align it: LONG32 lRemainder = 4L - ((siteWinSize.cx + lXAdditionalRoomForMotion) % 4L); if(4L == lRemainder) { lRemainder = 0L; } lXAdditionalRoomForMotion += lRemainder; lYAdditionalRoomForMotion = //XXXEH- no neg scrollRate handled yet... (lEffectiveScrollRate <= 0? 0 : siteWinSize.cy/2); //LONG32-align it: lRemainder = 4L - ((siteWinSize.cy + lYAdditionalRoomForMotion) % 4L); if(4L == lRemainder) { lRemainder = 0L; } lYAdditionalRoomForMotion += lRemainder;#endif /* } */ // Following if/else/else block (one section each for windows, // unix and mac) contains code which allocates the offscreen // storage which we draw into in OnPaint(). /* begin offscreen storage allocation code { */#if defined(_WINDOWS) /* { */ if (bSizeChanged) { if(m_lastKnownSize.cx != 0 && m_lastKnownSize.cy != 0) { m_txtWin.m_bHandlingWindowResizing = TRUE; } m_lastKnownSize = siteWinSize;#if !defined(USE_DIB_SECTION) /* { */ if(m_txtWin.m_pBmpCompat) {// OutputDebugString("cleaning up offscreen bitmap\r\n"); DeleteObject((HBITMAP)m_txtWin.m_pBmpCompat); m_txtWin.m_pBmpCompat = NULL; }#else //USE_DIB_SECTION: /* }{ */ // Need to make new bitmap if window was resized; // first, deselect it from the DC: if(m_txtWin.m_hOldBitmap && m_txtWin.m_pDeviceContextMemory) { SelectObject((HDC)m_txtWin.m_pDeviceContextMemory, m_txtWin.m_hOldBitmap); } if(m_txtWin.m_hBitmap) { HBITMAP hTmpBmp = m_txtWin.m_hBitmap; m_txtWin.m_hBitmap = NULL; De
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -