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

📄 ig_graphics.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2005-2006 Videon Central, Inc.                            **
**  All rights reserved.                                                    **
**                                                                          **
**  The computer program contained herein contains proprietary information  **
**  which is the property of Videon Central, Inc.  The program may be used  **
**  and/or copied only with the written permission of Videon Central, Inc.  **
**  or in accordance with the terms and conditions stipulated in the        **
**  agreement/contract under which the programs have been supplied.         **
**                                                                          **
******************************************************************************
*****************************************************************************/
/**
 * @file ig_graphics.cpp
 *
 * $Revision: 1.3 $ 
 *
 * IG graphics drawing routines
 *
 */

#include "ig_api.h"
#include "directfb.h"
#include "ig_util.h"
#include "ig_defs.h"
#include "ig_graphics.h"

#define DEBUG_IG_GRAPHICS   DBG_ERROR
#define DBG_ON(x)           (DEBUG_IG_GRAPHICS >= x)

/* stuff from another file */
extern PALETTE IGPalettes[IG_MAX_PALETTES];
extern OBJECT_DEFINITION_SEGMENT IGObjList[IG_MAX_ODS];
extern IGINFO IGInfo;
extern IGSTATS IGStats;

/* locals */
DFBRegion gIGFlipRegion;
extern ULONG gIGImageIndex;
extern DFBRectangle IGCleanupList[IG_MAX_VISIBLE_ODS];  /* our list of objects to clean on screen */
IG_STATUS IGAddtoCleanupList(int X, int Y, int Width, int Height);

/**
 * IGGraphicsDrawCompObj - draw the given composition object on screen, cropped images also
 *
 * @param COMPOSITION_OBJECT *CompObj - The Composition object to draw
 * @param int ClearObject - set to 1 if the object should be erased
 *
 * @return IG_STATUS
 */
IG_STATUS IGGraphicsDrawCompObj(COMPOSITION_OBJECT *CompObj, int ClearObject)
{
    OBJECT_DEFINITION_SEGMENT *Img=NULL;
    USHORT DrawX, DrawY, DrawW, DrawH;
    USHORT ScreenMaxX, ScreenMaxY;
#ifdef ALLOW_IG_PROFILING
    ULONG TickStart = 0;
#endif

    /* grab the object from the list */
    Img = &IGObjList[CompObj->ObjectIDRef];
    if (0 == Img->InUse)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsDrawCompObj(): Could not render object it is not available id %d\n", CompObj->ObjectIDRef));
        return IG_STATUS_ERROR;
    }

    /* we need to create a new surface */
    int imgsize = Img->ObjData.Width * Img->ObjData.Height;
    if (0 == imgsize)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsDrawCompObj(): imgsize was zero\n"));
        return IG_STATUS_ERROR;
    }

    /* check to see if the image is big enough to render */
    if ((Img->ObjData.Width < 8) || (Img->ObjData.Height < 8))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsDrawCompObj(): Could not render object id %d, too small\n", CompObj->ObjectIDRef));
        return IG_STATUS_ERROR;
    }

    if (ClearObject)
    {
        IGInfo.IGDFBInfo.PrimarySurface->SetColorIndex(IGInfo.IGDFBInfo.PrimarySurface, 0xff);  // all transparent
        DFBRectangle r;

        r.y = CompObj->YPosition;
        r.h = Img->ObjData.Height;

        if (IGInfo.CoordsHalfWidth == 0)
        {
            r.x = CompObj->XPosition;
            r.w = Img->ObjData.Width;
        }
        else
        {
            r.x = CompObj->XPosition/2;
            r.w = (Img->ObjData.Width+1)/2;
        }

        IGInfo.IGDFBInfo.PrimarySurface->FillRectangle(IGInfo.IGDFBInfo.PrimarySurface, r.x, r.y, r.w, r.h);
        IGAddtoCleanupList(r.x, r.y, r.w, r.h);
        return IG_STATUS_SUCCESS;
    }

    /* load drawing params, if we are drawing half width cut all x coords in half */
    if (IGInfo.CoordsHalfWidth == 0)
    {
        DrawX = CompObj->XPosition;
        DrawY = CompObj->YPosition;
        DrawW = Img->ObjData.Width;
        DrawH = Img->ObjData.Height;
        ScreenMaxX = MAX_GRFX_WIDTH;
        ScreenMaxY = MAX_GRFX_HEIGHT;
    }
    else
    {
        DrawX = CompObj->XPosition/2;
        DrawY = CompObj->YPosition;
        DrawW = (Img->ObjData.Width+1)/2;
        DrawH = Img->ObjData.Height;
        ScreenMaxX = MAX_GRFX_WIDTH/2;
        ScreenMaxY = MAX_GRFX_HEIGHT;
    }

    /* see if the image is cropped */
    if (0 == CompObj->CroppedFlag)
    {
        /* check that we do not go outside screen space */
        if ((DrawX <= ScreenMaxX) && (DrawY <= ScreenMaxY) &&
           ((DrawX + DrawW) <= ScreenMaxX) && ((DrawY + DrawH) <= ScreenMaxY))
        {
            /* image is not cropped */
#ifdef ALLOW_IG_PROFILING
            if (IGStats.Profiling == 1)
            {
                TickStart = OS_GetTicks();
            }
#endif
            if (IGInfo.IGDFBInfo.PrimarySurface->Blit(IGInfo.IGDFBInfo.PrimarySurface,
                Img->SurfaceLUT8, NULL, DrawX, DrawY) == DFB_OK)
            {
#ifdef ALLOW_IG_PROFILING
                if (IGStats.Profiling == 1)
                {
                    IGStats.TotalBlitTicks += OS_GetTicks() - TickStart;
                }
#endif
                IGAddtoCleanupList(DrawX, DrawY, DrawW, DrawH);
            }
        }
        else
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsDrawCompObj(): image tried to draw out of bounds %d %d %d %d\n",
                DrawX, DrawY, DrawX + DrawW, DrawY + DrawH));
        }
    }
    else
    {
        /* img is cropped */
        DFBRectangle Rect;

        Rect.y = CompObj->Rect.Y;
        Rect.h = CompObj->Rect.Height;

        if (IGInfo.CoordsHalfWidth == 0)
        {
            Rect.x = CompObj->Rect.X;
            Rect.w = CompObj->Rect.Width;
        }
        else
        {
            Rect.x = CompObj->Rect.X/2;
            Rect.w = (CompObj->Rect.Width+1)/2;
        }

        /* draw the image */
        if ((DrawX <= ScreenMaxX) && (DrawY <= ScreenMaxY) &&
           ((DrawX + Rect.w) <= ScreenMaxX) && ((DrawY + Rect.h) <= ScreenMaxY))
        {
#ifdef ALLOW_IG_PROFILING
            if (IGStats.Profiling == 1)
            {
                TickStart = OS_GetTicks();
            }
#endif
            if (IGInfo.IGDFBInfo.PrimarySurface->Blit(IGInfo.IGDFBInfo.PrimarySurface, Img->SurfaceLUT8,
                &Rect, DrawX, DrawY) == DFB_OK)
            {
#ifdef ALLOW_IG_PROFILING
                if (IGStats.Profiling == 1)
                {
                    IGStats.TotalBlitTicks += OS_GetTicks() - TickStart;
                }
#endif
                IGAddtoCleanupList(DrawX, DrawY, Rect.w, Rect.h);
            }
        }
        else
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsDrawCompObj(): image tried to draw out of bounds %d %d %d %d\n",
                DrawX, DrawY, DrawX + Rect.w, DrawY + Rect.h));
        }
    }

    return IG_STATUS_SUCCESS;
}

/**
 * IGAddtoCleanupList - add to list of objects to be cleaned up on an animation
 *
 * @param int X - X coord of image
 * @param int Y - Y coord of image
 * @param int Width - Width of image
 * @param int Height - Height of image
 *
 * @return IG_STATUS
 */
IG_STATUS IGAddtoCleanupList(int X, int Y, int Width, int Height)
{
    /* stretch the flipping region to fit the new coords,
     * do this here because we may flip a region of the
     * screen but not clear all of it */
    if (X < gIGFlipRegion.x1)
    {
        gIGFlipRegion.x1 = X;
    }

    if (Y < gIGFlipRegion.y1)
    {
        gIGFlipRegion.y1 = Y;
    }

    if (X+Width > gIGFlipRegion.x2)
    {
        gIGFlipRegion.x2 = X+Width;
    }

    if (Y+Height > gIGFlipRegion.y2)
    {
        gIGFlipRegion.y2 = Y+Height;
    }

    /* loop looking for a match */
    for (ULONG i=0; i<gIGImageIndex; i++)
    {
        /* see if we match inputs */
        if ((IGCleanupList[i].h == Height) &&
            (IGCleanupList[i].w == Width)  &&
            (IGCleanupList[i].x == X)      &&
            (IGCleanupList[i].y == Y))
        {
            /* input matches one in the list, don't add */
            return IG_STATUS_SUCCESS;
        }
    }

    if (gIGImageIndex >= IG_MAX_VISIBLE_ODS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGAddToCleanupList(): failed, too many images on screen!!\n\n"));
        return IG_STATUS_ERROR;
    }

    /* if we didn't find a match in the list, we got here, so add it */
    IGCleanupList[gIGImageIndex].h = Height;
    IGCleanupList[gIGImageIndex].w = Width;
    IGCleanupList[gIGImageIndex].x = X;
    IGCleanupList[gIGImageIndex].y = Y;

    DBGPRINT(DBG_ON(DBG_TRACE), ("IG Image: (%d, %d) w=%d, h=%d\n",
                IGCleanupList[gIGImageIndex].x, IGCleanupList[gIGImageIndex].y,
                            IGCleanupList[gIGImageIndex].w, IGCleanupList[gIGImageIndex].h));

    gIGImageIndex++;

    return IG_STATUS_SUCCESS;
}

/**
 * IGGraphicsSetPalette - update the palette for the currently displayed surface
 *
 * @param PALETTE *Pal - The palette to set on DirectFB
 *
 * @return IG_STATUS
 */
IG_STATUS IGGraphicsSetPalette(PALETTE *Pal)
{
    /* set the palette */
    DFBResult res;

    if (Pal == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsSetPalette(): Null Pal\n"));
        return IG_STATUS_ERROR;
    }

    if (Pal->DFBPal == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsSetPalette(): Null DFBPal\n"));
        return IG_STATUS_ERROR;
    }

    /* call create palette with the entries we give here */
    if (Pal->DFBPal->SetEntries(Pal->DFBPal, Pal->Colors, IG_MAX_PALETTE_COLORS, 0) != DFB_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsSetPalette(): SetEntries Failed\n"));
        return IG_STATUS_ERROR;
    }

    res = IGInfo.IGDFBInfo.PrimarySurface->SetPalette(IGInfo.IGDFBInfo.PrimarySurface, Pal->DFBPal);
    if (res != DFB_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGGraphicsSetPalette(): Failed to set palette, error %d\n", res));
        return IG_STATUS_ERROR;
    }

    return IG_STATUS_SUCCESS;
}

/**
 * IGGraphicsCreatePalette - update the palette for the currently displayed surface
 *
 * @param int PaletteNumber - the palette number that is getting new colors
 * @param BYTE *DataPtr - the palette color information from the stream
 * @param int NumEntries - the number of entries that are in the stream
 *
 * @return IG_STATUS
 */
IG_STATUS IGGraphicsSetPaletteColors(int PaletteNumber, BYTE *DataPtr, BYTE NumEntries, BYTE fClearPalette, IG_COLOR_SPACE ColorSpace)
{
    int PalColor;
    ULONG Color;
    BYTE *ClrBytes = (BYTE *)&Color;
    PALETTE *CurPal = &IGPalettes[PaletteNumber];

    /* we are clearing the palette before setting entries */
    if (fClearPalette)
    {
        memset(CurPal->Colors, 0, IG_MAX_PALETTE_COLORS * sizeof(DFBColor));
    }

    for (int i=0; i<NumEntries; i++)
    {
        PalColor = *DataPtr;
        DataPtr++; /* move to color area, past palette_entry_id */

        /* convert all colors to ARGB, 601 or 709 colorspace */
        if (ColorSpace == REC_709)
        {
            Color = IGMakeARGBfromYCrCb709(*DataPtr++,  // y
                                           *DataPtr++,  //cr

⌨️ 快捷键说明

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