예제 #1
0
CtrlRadialSlider::CtrlRadialSlider( intf_thread_t *pIntf,
                                    const GenericBitmap &rBmpSeq, int numImg,
                                    VarPercent &rVariable, float minAngle,
                                    float maxAngle, const UString &rHelp,
                                    VarBool *pVisible ):
    CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ), m_numImg( numImg ),
    m_rVariable( rVariable ), m_minAngle( minAngle ), m_maxAngle( maxAngle ),
    m_cmdUpDown( this ), m_cmdDownUp( this ),
    m_cmdMove( this )
{
    // Build the images of the sequence
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );
    m_pImgSeq = pOsFactory->createOSGraphics( rBmpSeq.getWidth(),
                                              rBmpSeq.getHeight() );
    m_pImgSeq->drawBitmap( rBmpSeq, 0, 0 );

    m_width = rBmpSeq.getWidth();
    m_height = rBmpSeq.getHeight() / numImg;

    // States
    m_fsm.addState( "up" );
    m_fsm.addState( "down" );

    // Transitions
    m_fsm.addTransition( "up", "mouse:left:down", "down", &m_cmdUpDown );
    m_fsm.addTransition( "down", "mouse:left:up", "up", &m_cmdDownUp );
    m_fsm.addTransition( "down", "motion", "down", &m_cmdMove );

    // Initial state
    m_fsm.setState( "up" );

    // Observe the variable
    m_rVariable.addObserver( this );
}
예제 #2
0
CtrlButton::CtrlButton( intf_thread_t *pIntf, const GenericBitmap &rBmpUp,
                        const GenericBitmap &rBmpOver,
                        const GenericBitmap &rBmpDown, CmdGeneric &rCommand,
                        const UString &rTooltip, const UString &rHelp,
                        VarBool *pVisible ):
    CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ),
    m_rCommand( rCommand ), m_tooltip( rTooltip ),
    m_cmdUpOverDownOver( this, &transUpOverDownOver ),
    m_cmdDownOverUpOver( this, &transDownOverUpOver ),
    m_cmdDownOverDown( this, &transDownOverDown ),
    m_cmdDownDownOver( this, &transDownDownOver ),
    m_cmdUpOverUp( this, &transUpOverUp ),
    m_cmdUpUpOver( this, &transUpUpOver ),
    m_cmdDownUp( this, &transDownUp ),
    m_cmdUpHidden( this, &transUpHidden ),
    m_cmdHiddenUp( this, &transHiddenUp )
{
    // Build the images of the button
    OSFactory *pOsFactory = OSFactory::instance( pIntf );
    m_pImgUp = pOsFactory->createOSGraphics( rBmpUp.getWidth(),
                                             rBmpUp.getHeight() );
    m_pImgUp->drawBitmap( rBmpUp, 0, 0 );
    m_pImgDown = pOsFactory->createOSGraphics( rBmpDown.getWidth(),
                                               rBmpDown.getHeight() );
    m_pImgDown->drawBitmap( rBmpDown, 0, 0 );
    m_pImgOver = pOsFactory->createOSGraphics( rBmpOver.getWidth(),
                                               rBmpOver.getHeight() );
    m_pImgOver->drawBitmap( rBmpOver, 0, 0 );

    // States
    m_fsm.addState( "up" );
    m_fsm.addState( "down" );
    m_fsm.addState( "upOver" );
    m_fsm.addState( "downOver" );
    m_fsm.addState( "hidden" );

    // Transitions
    m_fsm.addTransition( "upOver", "mouse:left:down", "downOver",
                         &m_cmdUpOverDownOver );
    m_fsm.addTransition( "upOver", "mouse:left:dblclick", "downOver",
                         &m_cmdUpOverDownOver );
    m_fsm.addTransition( "downOver", "mouse:left:up", "upOver",
                         &m_cmdDownOverUpOver );
    m_fsm.addTransition( "downOver", "leave", "down", &m_cmdDownOverDown );
    m_fsm.addTransition( "down", "enter", "downOver", &m_cmdDownDownOver );
    m_fsm.addTransition( "upOver", "leave", "up", &m_cmdUpOverUp );
    m_fsm.addTransition( "up", "enter", "upOver", &m_cmdUpUpOver );
    m_fsm.addTransition( "down", "mouse:left:up", "up", &m_cmdDownUp );
    // XXX: It would be easy to use a "ANY" initial state to handle these
    // four lines in only one. But till now it isn't worthwhile...
    m_fsm.addTransition( "up", "special:hide", "hidden", &m_cmdUpHidden );
    m_fsm.addTransition( "down", "special:hide", "hidden", &m_cmdUpHidden );
    m_fsm.addTransition( "upOver", "special:hide", "hidden", &m_cmdUpHidden );
    m_fsm.addTransition( "downOver", "special:hide", "hidden", &m_cmdUpHidden );
    m_fsm.addTransition( "hidden", "special:show", "up", &m_cmdHiddenUp );

    // Initial state
    m_fsm.setState( "up" );
    m_pImg = m_pImgUp;
}
예제 #3
0
CtrlSliderCursor::CtrlSliderCursor( intf_thread_t *pIntf,
                                    const GenericBitmap &rBmpUp,
                                    const GenericBitmap &rBmpOver,
                                    const GenericBitmap &rBmpDown,
                                    const Bezier &rCurve,
                                    VarPercent &rVariable,
                                    VarBool *pVisible,
                                    const UString &rTooltip,
                                    const UString &rHelp ):
    CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ),
    m_rVariable( rVariable ), m_tooltip( rTooltip ),
    m_width( rCurve.getWidth() ), m_height( rCurve.getHeight() ),
    m_cmdOverDown( this, &transOverDown ),
    m_cmdDownOver( this, &transDownOver ), m_cmdOverUp( this, &transOverUp ),
    m_cmdUpOver( this, &transUpOver ), m_cmdMove( this, &transMove ),
    m_cmdScroll( this, &transScroll ),
    m_lastPercentage( 0 ), m_xOffset( 0 ), m_yOffset( 0 ),
    m_pEvt( NULL ), m_rCurve( rCurve )
{
    // Build the images of the cursor
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );
    m_pImgUp = pOsFactory->createOSGraphics( rBmpUp.getWidth(),
               rBmpUp.getHeight() );
    m_pImgUp->drawBitmap( rBmpUp, 0, 0 );
    m_pImgDown = pOsFactory->createOSGraphics( rBmpDown.getWidth(),
                 rBmpDown.getHeight() );
    m_pImgDown->drawBitmap( rBmpDown, 0, 0 );
    m_pImgOver = pOsFactory->createOSGraphics( rBmpOver.getWidth(),
                 rBmpOver.getHeight() );
    m_pImgOver->drawBitmap( rBmpOver, 0, 0 );

    // States
    m_fsm.addState( "up" );
    m_fsm.addState( "over" );
    m_fsm.addState( "down" );

    // Transitions
    m_fsm.addTransition( "over", "mouse:left:down", "down",
                         &m_cmdOverDown );
    m_fsm.addTransition( "down", "mouse:left:up", "over",
                         &m_cmdDownOver );
    m_fsm.addTransition( "over", "leave", "up", &m_cmdOverUp );
    m_fsm.addTransition( "up", "enter", "over", &m_cmdUpOver );
    m_fsm.addTransition( "down", "motion", "down", &m_cmdMove );
    m_fsm.addTransition( "over", "scroll", "over", &m_cmdScroll );

    // Initial state
    m_fsm.setState( "up" );
    m_pImg = m_pImgUp;

    // Observe the position variable
    m_rVariable.addObserver( this );

    // Initial position of the cursor
    m_lastPercentage = m_rVariable.get();
}
예제 #4
0
bool BitmapImpl::drawBitmap( const GenericBitmap &rSource, int xSrc, int ySrc,
                             int xDest, int yDest, int width, int height )
{
    int srcWidth = rSource.getWidth();
    uint32_t *pSrc = (uint32_t*)rSource.getData() + ySrc * srcWidth + xSrc;
    if( !pSrc )
    {
        return false;
    }
    if( xSrc < 0 || xSrc + width > srcWidth ||
        ySrc < 0 || ySrc + height > rSource.getHeight() )
    {
        msg_Warn( getIntf(), "drawBitmap: source rect too small, ignoring" );
        return false;
    }
    if( xDest < 0 || xDest + width > m_width ||
        yDest < 0 || yDest + height > m_height )
    {
        msg_Warn( getIntf(), "drawBitmap: dest rect too small, ignoring" );
        return false;
    }

    uint32_t *pDest = (uint32_t*)m_pData + yDest * m_width + xDest ;
    for( int y = 0; y < height; y++ )
    {
        memcpy( pDest, pSrc, 4 * width );
        pSrc += srcWidth;
        pDest += m_width;
    }
    return true;
}
예제 #5
0
CtrlImage::CtrlImage( intf_thread_t *pIntf, const GenericBitmap &rBitmap,
                      CmdGeneric &rCommand, resize_t resizeMethod,
                      const UString &rHelp, VarBool *pVisible ):
    CtrlFlat( pIntf, rHelp, pVisible ), m_rBitmap( rBitmap ),
    m_rCommand( rCommand ), m_resizeMethod( resizeMethod )
{
    OSFactory *pOsFactory = OSFactory::instance( pIntf );
    // Create an initial unscaled image in the buffer
    m_pImage = pOsFactory->createOSGraphics( rBitmap.getWidth(),
                                             rBitmap.getHeight() );
    m_pImage->drawBitmap( m_rBitmap );
}
예제 #6
0
void BitmapImpl::drawBitmap( const GenericBitmap &rSource, int xSrc, int ySrc,
                             int xDest, int yDest, int width, int height )
{
    int srcWidth = rSource.getWidth();
    uint32_t *pSrc = (uint32_t*)rSource.getData() + ySrc * srcWidth + xSrc;
    uint32_t *pDest = (uint32_t*)m_pData + yDest * m_width + xDest ;
    for( int y = 0; y < height; y++ )
    {
        memcpy( pDest, pSrc, 4 * width );
        pSrc += srcWidth;
        pDest += m_width;
    }
}
예제 #7
0
AnimBitmap::AnimBitmap( intf_thread_t *pIntf, const GenericBitmap &rBitmap ):
    SkinObject( pIntf ), m_pImage( NULL ), m_curFrame( 0 ), m_pTimer( NULL ),
    m_cmdNextFrame( this ), m_rBitmap( rBitmap )
{
    // Build the graphics
    OSFactory *pOsFactory = OSFactory::instance( pIntf );
    m_pImage = pOsFactory->createOSGraphics( rBitmap.getWidth(),
                                             rBitmap.getHeight() );
    m_pImage->drawBitmap( rBitmap, 0, 0 );

    m_nbFrames = rBitmap.getNbFrames();
    m_frameRate = rBitmap.getFrameRate();

    // Create the timer
    m_pTimer = pOsFactory->createOSTimer( m_cmdNextFrame );
}
예제 #8
0
void Tooltip::makeImage( const UString &rText )
{
    // Render the text on a bitmap
    GenericBitmap *pBmpTip = m_rFont.drawString( rText, 0 );
    if( !pBmpTip )
    {
        return;
    }
    int w = pBmpTip->getWidth() + 10;
    int h = m_rFont.getSize() + 8;

    // Create the image of the tooltip
    delete m_pImage;
    m_pImage = OSFactory::instance( getIntf() )->createOSGraphics( w, h );
    m_pImage->fillRect( 0, 0, w, h, 0xffffd0 );
    m_pImage->drawRect( 0, 0, w, h, 0x000000 );
    m_pImage->drawBitmap( *pBmpTip, 0, 0, 5, 5, -1, -1, true );

    delete pBmpTip;
}
예제 #9
0
void X11Graphics::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();
    }
    else if( width > rBitmap.getWidth() )
    {
        msg_Dbg( getIntf(), "bitmap width too small (%i)", rBitmap.getWidth() );
        width = rBitmap.getWidth();
    }
    if( height == -1 )
    {
        height = rBitmap.getHeight();
    }
    else if( height > rBitmap.getHeight() )
    {
        msg_Dbg( getIntf(), "bitmap height too small (%i)", rBitmap.getHeight()
                                 );
        height = rBitmap.getHeight();
    }

    // Nothing to draw if width or height is null
    if( width == 0 || height == 0 )
    {
        return;
    }

    // Safety check for debugging purpose
    if( xDest + width > m_width || yDest + height > m_height )
    {
        msg_Dbg( getIntf(), "bitmap too large" );
        return;
    }

    // Get a buffer on the image data
    uint8_t *pBmpData = rBitmap.getData();
    if( pBmpData == NULL )
    {
        // Nothing to draw
        return;
    }

    // Get the image from the pixmap
    XImage *pImage = XGetImage( XDISPLAY, m_pixmap, xDest, yDest, width,
                                height, AllPlanes, ZPixmap );
    if( pImage == NULL )
    {
        msg_Dbg( getIntf(), "XGetImage returned NULL" );
        return;
    }
    char *pData = pImage->data;

    // Get the padding of this image
    int pad = pImage->bitmap_pad >> 3;
    int shift = ( pad - ( (width * XPIXELSIZE) % pad ) ) % pad;

    // Mask for transparency
    Region mask = XCreateRegion();

    // Get a pointer on the right X11Display::makePixel method
    X11Display::MakePixelFunc_t makePixelFunc = ( blend ?
        m_rDisplay.getBlendPixel() : m_rDisplay.getPutPixel() );

    // 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
            (m_rDisplay.*makePixelFunc)( (uint8_t*)pData, r, g, b, a );
            pData += XPIXELSIZE;
            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
                    addHSegmentInRegion( mask, visibleSegmentStart, x, y );
                }
                wasVisible = false;
            }
        }
        if( wasVisible )
        {
            // End of a visible segment: add it to the mask
            addHSegmentInRegion( mask, visibleSegmentStart, width, y );
        }
        pData += shift;
        // Skip uninteresting bytes at the end of the line
        pBmpData += 4 * (rBitmap.getWidth() - width - xSrc);
    }

    // Apply the mask to the graphics context
    XOffsetRegion( mask, xDest, yDest );
    XSetRegion( XDISPLAY, m_gc, mask );
    // Copy the image on the pixmap
    XPutImage( XDISPLAY, m_pixmap, m_gc, pImage, 0, 0, xDest, yDest, width,
               height);
    XDestroyImage( pImage );

    // Add the bitmap mask to the global graphics mask
    Region newMask = XCreateRegion();
    XUnionRegion( mask, m_mask, newMask );
    XDestroyRegion( m_mask );
    m_mask = newMask;

    XDestroyRegion( mask );
}
예제 #10
0
void Win32Graphics::drawBitmap( const GenericBitmap &rBitmap,
                                int xSrc, int ySrc, int xDest, int yDest,
                                int width, int height, bool blend )
{
    (void)blend;

    // check and adapt to source if needed
    if( !checkBoundaries( 0, 0, rBitmap.getWidth(), rBitmap.getHeight(),
                          xSrc, ySrc, width, height ) )
    {
        msg_Err( getIntf(), "empty source! pls, debug your skin" );
        return;
    }

    // check destination
    if( !checkBoundaries( 0, 0, m_width, m_height,
                          xDest, yDest, width, height ) )
    {
        msg_Err( getIntf(), "out of reach destination! pls, debug your skin" );
        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 Independent 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
    if( !AlphaBlend( m_hDC, xDest, yDest, width, height, hDC, 0, 0,
                     width, height, bf ) )
    {
        msg_Err( getIntf(), "AlphaBlend() failed" );
    }

    // 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 );
}
예제 #11
0
void CtrlTree::makeImage()
{
    stats_TimerStart( getIntf(), "[Skins] Playlist image",
                      STATS_TIMER_SKINS_PLAYTREE_IMAGE );
    delete m_pImage;

    // Get the size of the control
    const Position *pPos = getPosition();
    if( !pPos )
    {
        stats_TimerStop( getIntf(), STATS_TIMER_SKINS_PLAYTREE_IMAGE );
        return;
    }
    int width = pPos->getWidth();
    int height = pPos->getHeight();

    int i_itemHeight = itemHeight();

    // Create an image
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );
    m_pImage = pOsFactory->createOSGraphics( width, height );

    VarTree::Iterator it = m_firstPos;

    if( m_pBgBitmap )
    {
        // Draw the background bitmap
        if( !m_pScaledBitmap ||
            m_pScaledBitmap->getWidth() != width ||
            m_pScaledBitmap->getHeight() != height )
        {
            delete m_pScaledBitmap;
            m_pScaledBitmap =
                new ScaledBitmap( getIntf(), *m_pBgBitmap, width, height );
        }
        m_pImage->drawBitmap( *m_pScaledBitmap, 0, 0 );

        for( int yPos = 0; yPos < height; yPos += i_itemHeight )
        {
            if( it != m_rTree.end() )
            {
                if( it->isSelected() )
                {
                    int rectHeight = __MIN( i_itemHeight, height - yPos );
                    m_pImage->fillRect( 0, yPos, width, rectHeight,
                                        m_selColor );
                }
                do
                {
                    it = m_flat ? m_rTree.getNextLeaf( it )
                                : m_rTree.getNextVisibleItem( it );
                } while( it != m_rTree.end() && it->isDeleted() );
            }
        }
    }
    else
    {
        // FIXME (TRYME)
        // Fill background with background color
        uint32_t bgColor = m_bgColor1;
        m_pImage->fillRect( 0, 0, width, height, bgColor );
        for( int yPos = 0; yPos < height; yPos += i_itemHeight )
        {
            int rectHeight = __MIN( i_itemHeight, height - yPos );
            if( it == m_rTree.end() )
                m_pImage->fillRect( 0, yPos, width, rectHeight, bgColor );
            else
            {
                uint32_t color = ( it->isSelected() ? m_selColor : bgColor );
                m_pImage->fillRect( 0, yPos, width, rectHeight, color );
                do
                {
                    it = m_flat ? m_rTree.getNextLeaf( it )
                                : m_rTree.getNextVisibleItem( it );
                } while( it != m_rTree.end() && it->isDeleted() );
            }
            bgColor = ( bgColor == m_bgColor1 ? m_bgColor2 : m_bgColor1 );
        }
    }

    int bitmapWidth = itemImageWidth();

    int yPos = 0;
    it = m_firstPos;
    while( it != m_rTree.end() && yPos < height )
    {
        const GenericBitmap *m_pCurBitmap;
        UString *pStr = it->getString();
        uint32_t color = ( it->isPlaying() ? m_playColor : m_fgColor );

        // Draw the text
        if( pStr != NULL )
        {
            int depth = m_flat ? 1 : it->depth();
            GenericBitmap *pText = m_rFont.drawString( *pStr, color, width - bitmapWidth * depth );
            if( !pText )
            {
                stats_TimerStop( getIntf(), STATS_TIMER_SKINS_PLAYTREE_IMAGE );
                return;
            }
            if( it->size() )
                m_pCurBitmap = it->isExpanded() ? m_pOpenBitmap : m_pClosedBitmap;
            else
                m_pCurBitmap = m_pItemBitmap;

            if( m_pCurBitmap )
            {
                // Make sure we are centered on the line
                int yPos2 = yPos+(i_itemHeight-m_pCurBitmap->getHeight()+1)/2;
                if( yPos2 >= height )
                {
                    delete pText;
                    break;
                }
                m_pImage->drawBitmap( *m_pCurBitmap, 0, 0,
                                      bitmapWidth * (depth - 1 ), yPos2,
                                      m_pCurBitmap->getWidth(),
                                      __MIN( m_pCurBitmap->getHeight(),
                                             height -  yPos2), true );
            }
            yPos += i_itemHeight - pText->getHeight();
            int ySrc = 0;
            if( yPos < 0 )
            {
                ySrc = - yPos;
                yPos = 0;
            }
            int lineHeight = __MIN( pText->getHeight() - ySrc, height - yPos );
            m_pImage->drawBitmap( *pText, 0, ySrc, bitmapWidth * depth, yPos,
                                  pText->getWidth(),
                                  lineHeight, true );
            yPos += (pText->getHeight() - ySrc );
            delete pText;
        }
        do
        {
            it = m_flat ? m_rTree.getNextLeaf( it )
                : m_rTree.getNextVisibleItem( it );
        } while( it != m_rTree.end() && it->isDeleted() );
    }
    stats_TimerStop( getIntf(), STATS_TIMER_SKINS_PLAYTREE_IMAGE );
}
예제 #12
0
파일: ctrl_list.cpp 프로젝트: IAPark/vlc
void CtrlList::makeImage()
{
    delete m_pImage;

    // Get the size of the control
    const Position *pPos = getPosition();
    if( !pPos )
    {
        return;
    }
    int width = pPos->getWidth();
    int height = pPos->getHeight();
    int itemHeight = m_rFont.getSize() + LINE_INTERVAL;

    // Create an image
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );
    m_pImage = pOsFactory->createOSGraphics( width, height );

    VarList::ConstIterator it = m_rList[m_lastPos];

    // Draw the background
    if( m_pBitmap )
    {
        // A background bitmap is given, so we scale it, ignoring the
        // background colors
        ScaledBitmap bmp( getIntf(), *m_pBitmap, width, height );
        m_pImage->drawBitmap( bmp, 0, 0 );

        // Take care of the selection color
        for( int yPos = 0; yPos < height; yPos += itemHeight )
        {
            int rectHeight = __MIN( itemHeight, height - yPos );
            if( it != m_rList.end() )
            {
                if( (*it).m_selected )
                {
                    m_pImage->fillRect( 0, yPos, width, rectHeight,
                                        m_selColor );
                }
                ++it;
            }
        }
    }
    else
    {
        // No background bitmap, so use the 2 background colors
        // Current background color
        uint32_t bgColor = m_bgColor1;
        for( int yPos = 0; yPos < height; yPos += itemHeight )
        {
            int rectHeight = __MIN( itemHeight, height - yPos );
            if( it != m_rList.end() )
            {
                uint32_t color = ( (*it).m_selected ? m_selColor : bgColor );
                m_pImage->fillRect( 0, yPos, width, rectHeight, color );
                ++it;
            }
            else
            {
                m_pImage->fillRect( 0, yPos, width, rectHeight, bgColor );
            }
            // Flip the background color
            bgColor = ( bgColor == m_bgColor1 ? m_bgColor2 : m_bgColor1 );
        }
    }

    // Draw the items
    int yPos = 0;
    for( it = m_rList[m_lastPos]; it != m_rList.end() && yPos < height; ++it )
    {
        UString *pStr = (UString*)(it->m_cString.get());
        uint32_t color = ( it->m_playing ? m_playColor : m_fgColor );

        // Draw the text
        GenericBitmap *pText = m_rFont.drawString( *pStr, color, width );
        if( !pText )
        {
            return;
        }
        yPos += itemHeight - pText->getHeight();
        int ySrc = 0;
        if( yPos < 0 )
        {
            ySrc = - yPos;
            yPos = 0;
        }
        int lineHeight = __MIN( pText->getHeight() - ySrc, height - yPos );
        m_pImage->drawBitmap( *pText, 0, ySrc, 0, yPos, pText->getWidth(),
                              lineHeight, true );
        yPos += (pText->getHeight() - ySrc );
        delete pText;

    }
}
예제 #13
0
void X11Graphics::drawBitmap( const GenericBitmap &rBitmap, int xSrc,
                              int ySrc, int xDest, int yDest, int width,
                              int height, bool blend )
{
    // check and adapt to source if needed
    if( !checkBoundaries( 0, 0, rBitmap.getWidth(), rBitmap.getHeight(),
                          xSrc, ySrc, width, height ) )
    {
        msg_Err( getIntf(), "empty source! pls, debug your skin" );
        return;
    }

    // check destination
    if( !checkBoundaries( 0, 0, m_width, m_height,
                          xDest, yDest, width, height ) )
    {
        msg_Err( getIntf(), "out of reach destination! pls, debug your skin" );
        return;
    }

    // Get a buffer on the image data
    uint8_t *pBmpData = rBitmap.getData();
    if( pBmpData == NULL )
    {
        // Nothing to draw
        return;
    }

    // Force pending XCopyArea to be sent to the X Server
    // before issuing an XGetImage.
    XSync( XDISPLAY, False );

    // Get the image from the pixmap
    XImage *pImage = XGetImage( XDISPLAY, m_pixmap, xDest, yDest, width,
                                height, AllPlanes, ZPixmap );
    if( pImage == NULL )
    {
        msg_Dbg( getIntf(), "XGetImage returned NULL" );
        return;
    }
    char *pData = pImage->data;

    // Get the padding of this image
    int pad = pImage->bitmap_pad >> 3;
    int shift = ( pad - ( (width * XPIXELSIZE) % pad ) ) % pad;

    // Mask for transparency
    Region mask = XCreateRegion();

    // Get a pointer on the right X11Display::makePixel method
    X11Display::MakePixelFunc_t makePixelFunc = ( blend ?
        m_rDisplay.getBlendPixel() : m_rDisplay.getPutPixel() );

    // 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
            (m_rDisplay.*makePixelFunc)( (uint8_t*)pData, r, g, b, a );
            pData += XPIXELSIZE;
            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
                    addHSegmentInRegion( mask, visibleSegmentStart, x, y );
                }
                wasVisible = false;
            }
        }
        if( wasVisible )
        {
            // End of a visible segment: add it to the mask
            addHSegmentInRegion( mask, visibleSegmentStart, width, y );
        }
        pData += shift;
        // Skip uninteresting bytes at the end of the line
        pBmpData += 4 * (rBitmap.getWidth() - width - xSrc);
    }

    // Apply the mask to the graphics context
    XOffsetRegion( mask, xDest, yDest );
    XSetRegion( XDISPLAY, m_gc, mask );
    // Copy the image on the pixmap
    XPutImage( XDISPLAY, m_pixmap, m_gc, pImage, 0, 0, xDest, yDest, width,
               height);
    XDestroyImage( pImage );

    // Add the bitmap mask to the global graphics mask
    Region newMask = XCreateRegion();
    XUnionRegion( mask, m_mask, newMask );
    XDestroyRegion( m_mask );
    m_mask = newMask;

    XDestroyRegion( mask );
}
예제 #14
0
void CtrlTree::makeImage()
{
    delete m_pImage;

    // Get the size of the control
    const Position *pPos = getPosition();
    if( !pPos )
        return;
    int width = pPos->getWidth();
    int height = pPos->getHeight();

    int i_itemHeight = itemHeight();

    // Create an image
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );
    m_pImage = pOsFactory->createOSGraphics( width, height );

    Iterator it = m_firstPos;

    if( m_pBgBitmap )
    {
        // Draw the background bitmap
        if( !m_pScaledBitmap ||
            m_pScaledBitmap->getWidth() != width ||
            m_pScaledBitmap->getHeight() != height )
        {
            delete m_pScaledBitmap;
            m_pScaledBitmap =
                new ScaledBitmap( getIntf(), *m_pBgBitmap, width, height );
        }
        m_pImage->drawBitmap( *m_pScaledBitmap, 0, 0 );

        for( int yPos = 0;
             yPos < height && it != m_rTree.end();
             yPos += i_itemHeight, ++it )
        {
            if( it->isSelected() )
            {
                int rectHeight = __MIN( i_itemHeight, height - yPos );
                m_pImage->fillRect( 0, yPos, width, rectHeight, m_selColor );
            }
        }
    }
    else
    {
        // Fill background with background color
        uint32_t bgColor = m_bgColor1;
        m_pImage->fillRect( 0, 0, width, height, bgColor );
        // Overwrite with alternate colors (bgColor1, bgColor2)
        for( int yPos = 0; yPos < height; yPos += i_itemHeight )
        {
            int rectHeight = __MIN( i_itemHeight, height - yPos );
            if( it == m_rTree.end() )
                m_pImage->fillRect( 0, yPos, width, rectHeight, bgColor );
            else
            {
                uint32_t color = ( it->isSelected() ? m_selColor : bgColor );
                m_pImage->fillRect( 0, yPos, width, rectHeight, color );
                ++it;
            }
            bgColor = ( bgColor == m_bgColor1 ? m_bgColor2 : m_bgColor1 );
        }
    }

    int bitmapWidth = itemImageWidth();

    it = m_firstPos;
    for( int yPos = 0; yPos < height && it != m_rTree.end(); ++it )
    {
        const GenericBitmap *m_pCurBitmap;
        UString *pStr = it->getString();
        if( pStr != NULL )
        {
            uint32_t color = it->isPlaying() ? m_playColor : m_fgColor;
            int depth = m_flat ? 1 : it->depth();
            GenericBitmap *pText =
                m_rFont.drawString( *pStr, color, width-bitmapWidth*depth );
            if( !pText )
            {
                return;
            }
            if( it->size() )
                m_pCurBitmap =
                    it->isExpanded() ? m_pOpenBitmap : m_pClosedBitmap;
            else
                m_pCurBitmap = m_pItemBitmap;

            if( m_pCurBitmap )
            {
                // Make sure we are centered on the line
                int yPos2 = yPos+(i_itemHeight-m_pCurBitmap->getHeight()+1)/2;
                if( yPos2 >= height )
                {
                    delete pText;
                    break;
                }
                // Draw the icon in front of the text
                m_pImage->drawBitmap( *m_pCurBitmap, 0, 0,
                                      bitmapWidth * (depth - 1 ), yPos2,
                                      m_pCurBitmap->getWidth(),
                                      __MIN( m_pCurBitmap->getHeight(),
                                             height -  yPos2), true );
            }
            yPos += i_itemHeight - pText->getHeight();
            int ySrc = 0;
            if( yPos < 0 )
            {
                ySrc = - yPos;
                yPos = 0;
            }
            int lineHeight = __MIN( pText->getHeight() - ySrc, height - yPos );
            // Draw the text
            m_pImage->drawBitmap( *pText, 0, ySrc, bitmapWidth * depth, yPos,
                                  pText->getWidth(),
                                  lineHeight, true );
            yPos += (pText->getHeight() - ySrc );

            if( it == m_itOver )
            {
                // Draw the underline bar below the text for drag&drop
                m_pImage->fillRect(
                    bitmapWidth * (depth - 1 ), yPos - 2,
                    bitmapWidth + pText->getWidth(), __MAX( lineHeight/5, 3 ),
                    m_selColor );
            }
            delete pText;
        }
    }
}