⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win32_graphics.cpp

📁 video linux conference
💻 CPP
字号:
/***************************************************************************** * win32_graphics.cpp ***************************************************************************** * Copyright (C) 2003 VideoLAN * $Id: win32_graphics.cpp 11017 2005-05-14 23:50:13Z asmax $ * * Authors: Cyril Deguet     <asmax@via.ecp.fr> *          Olivier Teuli鑢e <ipkiss@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************/#ifdef WIN32_SKINS#define WINVER 0x500#ifndef AC_SRC_ALPHA#define AC_SRC_ALPHA 1#endif#include "win32_factory.hpp"#include "win32_graphics.hpp"#include "win32_window.hpp"#include "../src/generic_bitmap.hpp"Win32Graphics::Win32Graphics( intf_thread_t *pIntf, int width, int height ):    OSGraphics( pIntf ), m_width( width ), m_height( height ), m_hDC( NULL ){    HBITMAP hBmp;    HDC hDC = GetDC( NULL );    hBmp = CreateCompatibleBitmap( hDC, m_width, m_height );    ReleaseDC( NULL, hDC );    m_hDC = CreateCompatibleDC( NULL );    SelectObject( m_hDC, hBmp );    DeleteObject( hBmp );    // Create the mask    m_mask = CreateRectRgn( 0, 0, 0, 0 );}Win32Graphics::~Win32Graphics(){    DeleteDC( m_hDC );    DeleteObject( m_mask );}void Win32Graphics::clear(){    // Clear the transparency mask    DeleteObject( m_mask );    m_mask = CreateRectRgn( 0, 0, 0, 0 );}void Win32Graphics::drawBitmap( const GenericBitmap &rBitmap,                                int xSrc, int ySrc, int xDest, int yDest,                                int width, int height, bool blend ){    // Get the bitmap size if necessary    if( width == -1 )    {        width = rBitmap.getWidth();    }    if( height == -1 )    {        height = rBitmap.getHeight();    }    if( xDest + width > m_width || yDest + height > m_height )    {        msg_Err( getIntf(), "Bitmap too large !" );        return;    }    // Get a buffer on the image data    uint8_t *pBmpData = rBitmap.getData();    if( pBmpData == NULL )    {        // Nothing to draw        return;    }    void *pBits;     // pointer to DIB section    // Fill a BITMAPINFO structure    BITMAPINFO bmpInfo;    memset( &bmpInfo, 0, sizeof( bmpInfo ) );    bmpInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );    bmpInfo.bmiHeader.biWidth = width;    bmpInfo.bmiHeader.biHeight = -height;    bmpInfo.bmiHeader.biPlanes = 1;    bmpInfo.bmiHeader.biBitCount = 32;    bmpInfo.bmiHeader.biCompression = BI_RGB;    bmpInfo.bmiHeader.biSizeImage = width * height * 4;    // Create a DIB (Device Independant Bitmap) and associate it with    // a temporary DC    HDC hDC = CreateCompatibleDC( m_hDC );    HBITMAP hBmp = CreateDIBSection( hDC, &bmpInfo, DIB_RGB_COLORS,                                     &pBits, NULL, 0 );    SelectObject( hDC, hBmp );    // Mask for transparency    HRGN mask = CreateRectRgn( 0, 0, 0, 0 );    // Skip the first lines of the image    pBmpData += 4 * ySrc * rBitmap.getWidth();    // Copy the bitmap on the image and compute the mask    for( int y = 0; y < height; y++ )    {        // Skip uninteresting bytes at the beginning of the line        pBmpData += 4 * xSrc;        // Flag to say whether the previous pixel on the line was visible        bool wasVisible = false;        // Beginning of the current visible segment on the line        int visibleSegmentStart = 0;        for( int x = 0; x < width; x++ )        {            uint8_t b = *(pBmpData++);            uint8_t g = *(pBmpData++);            uint8_t r = *(pBmpData++);            uint8_t a = *(pBmpData++);            // Draw the pixel            ((UINT32 *)pBits)[x + y * width] =                (a << 24) | (r << 16) | (g << 8) | b;            if( a > 0 )            {                // Pixel is visible                if( ! wasVisible )                {                    // Beginning of a visible segment                    visibleSegmentStart = x;                }                wasVisible = true;            }            else            {                // Pixel is transparent                if( wasVisible )                {                    // End of a visible segment: add it to the mask                    addSegmentInRegion( mask, visibleSegmentStart, x, y );                }                wasVisible = false;            }        }        if( wasVisible )        {            // End of a visible segment: add it to the mask            addSegmentInRegion( mask, visibleSegmentStart, width, y );        }        // Skip uninteresting bytes at the end of the line        pBmpData += 4 * (rBitmap.getWidth() - width - xSrc);    }    // Apply the mask to the internal DC    OffsetRgn( mask, xDest, yDest );    SelectClipRgn( m_hDC, mask );    BLENDFUNCTION bf;      // structure for alpha blending    bf.BlendOp = AC_SRC_OVER;    bf.BlendFlags = 0;    bf.SourceConstantAlpha = 0xff;  // don't use constant alpha    bf.AlphaFormat = AC_SRC_ALPHA;    // Blend the image onto the internal DC    BOOL (WINAPI *AlphaBlend)( HDC, int, int, int, int, HDC, int, int,                               int, int, BLENDFUNCTION );    AlphaBlend = ((Win32Factory*)OSFactory::instance( getIntf() ))->AlphaBlend;    if( AlphaBlend &&        !AlphaBlend( m_hDC, xDest, yDest, width, height, hDC, 0, 0,                     width, height, bf ) )    {        msg_Err( getIntf(), "AlphaBlend() failed" );    }    else if( !AlphaBlend )    {        // Copy the image onto the internal DC        BitBlt( m_hDC, xDest, yDest, width, height, hDC, 0, 0, SRCCOPY );    }    // Add the bitmap mask to the global graphics mask    CombineRgn( m_mask, m_mask, mask, RGN_OR );    // Do cleanup    DeleteObject( hBmp );    DeleteObject( mask );    DeleteDC( hDC );}void Win32Graphics::drawGraphics( const OSGraphics &rGraphics, int xSrc,                                  int ySrc, int xDest, int yDest, int width,                                  int height ){    if( width == -1 )    {        width = rGraphics.getWidth();    }    if( height == -1 )    {        height = rGraphics.getHeight();    }    // Create the mask for transparency    HRGN mask = CreateRectRgn( xSrc, ySrc, xSrc + width, ySrc + height );    CombineRgn( mask, ((Win32Graphics&)rGraphics).getMask(), mask, RGN_AND );    OffsetRgn( mask, xDest - xSrc, yDest - ySrc );    // Copy the image    HDC srcDC = ((Win32Graphics&)rGraphics).getDC();    SelectClipRgn( m_hDC, mask );    BitBlt( m_hDC, xDest, yDest, width, height, srcDC, xSrc, ySrc, SRCCOPY );    // Add the source mask to the mask of the graphics    CombineRgn( m_mask, mask, m_mask, RGN_OR );    DeleteObject( mask );}void Win32Graphics::fillRect( int left, int top, int width, int height,                              uint32_t color ){    // Update the mask with the rectangle area    HRGN newMask = CreateRectRgn( left, top, left + width, top + height );    CombineRgn( m_mask, m_mask, newMask, RGN_OR );    SelectClipRgn( m_hDC, m_mask );    DeleteObject( newMask );    // Create a brush with the color    int red = (color & 0xff0000) >> 16;    int green = (color & 0xff00) >> 8;    int blue = color & 0xff;    HBRUSH hBrush = CreateSolidBrush( RGB( red, green, blue ) );    // Draw the rectangle    RECT r;    r.left = left;    r.top = top;    r.right = left + width;    r.bottom = top + height;    FillRect( m_hDC, &r, hBrush );    DeleteObject( hBrush );}void Win32Graphics::drawRect( int left, int top, int width, int height,                              uint32_t color ){    // Update the mask with the rectangle    HRGN l1 = CreateRectRgn( left, top, left + width, top + 1 );    HRGN l2 = CreateRectRgn( left + width - 1, top,                             left + width, top + height );    HRGN l3 = CreateRectRgn( left, top + height - 1,                             left + width, top + height );    HRGN l4 = CreateRectRgn( left, top, left + 1, top + height );    CombineRgn( m_mask, m_mask, l1, RGN_OR );    CombineRgn( m_mask, m_mask, l2, RGN_OR );    CombineRgn( m_mask, m_mask, l3, RGN_OR );    CombineRgn( m_mask, m_mask, l4, RGN_OR );    DeleteObject( l1 );    DeleteObject( l2 );    DeleteObject( l3 );    DeleteObject( l4 );    SelectClipRgn( m_hDC, m_mask );    // Create a pen with the color    int red = (color & 0xff0000) >> 16;    int green = (color & 0xff00) >> 8;    int blue = color & 0xff;    HPEN hPen = CreatePen( PS_SOLID, 0, RGB( red, green, blue ) );    SelectObject( m_hDC, hPen );    // Draw the rectangle    MoveToEx( m_hDC, left, top, NULL );    LineTo( m_hDC, left + width - 1, top );    LineTo( m_hDC, left + width - 1, top + height - 1 );    LineTo( m_hDC, left, top + height - 1 );    LineTo( m_hDC, left, top );    // Delete the pen    DeleteObject( hPen );}void Win32Graphics::applyMaskToWindow( OSWindow &rWindow ){    // Get window handle    HWND hWnd = ((Win32Window&)rWindow).getHandle();    // Apply the mask    // We need to copy the mask, because SetWindowRgn modifies it in our back    HRGN mask = CreateRectRgn( 0, 0, 0, 0 );    CombineRgn( mask, m_mask, NULL, RGN_COPY );    SetWindowRgn( hWnd, mask, TRUE );}void Win32Graphics::copyToWindow( OSWindow &rWindow, int xSrc, int ySrc,                                  int width, int height, int xDest, int yDest ){    // Initialize painting    HWND hWnd = ((Win32Window&)rWindow).getHandle();    HDC wndDC = GetWindowDC( hWnd );    HDC srcDC = m_hDC;    // Draw image on window    BitBlt( wndDC, xDest, yDest, width, height, srcDC, xSrc, ySrc, SRCCOPY );    // Release window device context    ReleaseDC( hWnd, wndDC );}bool Win32Graphics::hit( int x, int y ) const{    return PtInRegion( m_mask, x, y );}void Win32Graphics::addSegmentInRegion( HRGN &rMask, int start,                                        int end, int line ){    HRGN buffer = CreateRectRgn( start, line, end, line + 1 );    CombineRgn( rMask, buffer, rMask, RGN_OR );    DeleteObject( buffer );}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -