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

📄 textst_render.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
 *
 * @retval
 *      TEXTST_STATUS
 */
TEXTST_STATUS   TextSTRenderResume(void)
{
    DBGPRINT(DBG_ON(DBG_TRACE), ("TextSTRenderResume: Enter\n"));

    if (hTextSTRender == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("TextSTRenderResume: TextST Presentation Controller not created!\n"));
        return (TEXTST_FAILURE);
    }

    /* Force the render task to stop wait */
    OS_SemGive(hTextSTRender->semSuspend);

    return (TEXTST_SUCCESS);
}

//////////////////////////////////////////////////////////////////////////////////
// Private Functions
//

/**
 * TextSTRenderResume --  Resume the TextST Renderer
 *
 * @param
 *      hTextST -- TextST Module Info
 *      pRenderInfo -- pointer to render info needed to render the subtitle bitmap
 *      pBmpObj -- pointer to bitmap object
 *
 * @retval
 *      TEXTST_STATUS
 */
static TEXTST_STATUS textstrenderDPSRender(TEXTST_INFO *hTextST, TEXTST_RENDER_INFO *pRenderInfo, TEXTST_BITMAP_OBJECT *pBmpObj)
{
    IDirectFBFont           *font = NULL;
    DFBSurfaceDescription   dsc;
    DFBFontDescription      font_dsc;
    UBYTE                   ubRegionID;
    USHORT                  usSfcWidth;
    USHORT                  usSfcHeight;
    USHORT                  usXcoord;
    USHORT                  usXoffset;
    USHORT                  usYcoord;
    USHORT                  usTextBoxW;
    USHORT                  usTextBoxH;
    USHORT                  usTextBoxX;
    USHORT                  usTextBoxY;
    UBYTE                   ubFontSize;
    UBYTE                   ubFontID;
    UBYTE                   ubCharsRendered;
    UBYTE                   ubStrLength;
    UBYTE                   ubInlineStyleIndex;
    UBYTE                   ubInlinePosIndex;
    BOOLEAN                 fInlineColorChange;
    BOOLEAN                 fInlineFontChange;
    int                     str_width;
    int                     i;

    DBGPRINT(DBG_ON(DBG_TRACE), ("textstrenderDPSRender: Enter\n"));

    if ( (hTextST == NULL) || (pBmpObj == NULL) || (pRenderInfo == NULL) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("textstrenderDPSRender: NULL pointer!\n"));
        return (TEXTST_NULL_PTR);
    }

    for (i = 0; i < pBmpObj->ubNumberOfRegions; i++)
    {
        /*
         * Get region style id from DPS rendering information.  This region style id will
         * be used to get region and textbox information from the differ region styles in the DSS.
         */
        ubRegionID = pRenderInfo->region_style_id_ref[i];

        /* Set surface width & height to the w&h of the specified region. */
        usSfcWidth  = hTextST->pDSS->region_style[ubRegionID].region_info.region_width;
        usSfcHeight = hTextST->pDSS->region_style[ubRegionID].region_info.region_height;

        /* set base settings without user style adjustments */
        ubFontSize = hTextST->pDSS->region_style[ubRegionID].font_size;
        usTextBoxX = hTextST->pDSS->region_style[ubRegionID].text_box_horizontal_position;
        usTextBoxY = hTextST->pDSS->region_style[ubRegionID].text_box_vertical_position;
        usTextBoxW = hTextST->pDSS->region_style[ubRegionID].text_box_width;
        usTextBoxH = hTextST->pDSS->region_style[ubRegionID].text_box_height;

        /* If there are user styles, adjust the user style fields */
        if (hTextST->pDSS->number_of_user_styles > 0)
        {
            /* adjust font size based on user style selected */
            if (hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].font_size_inc_dec == 0)
            {
                // increase
                if ( (ubFontSize + hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].font_size_delta) <= TEXTST_MAX_FONTSIZE)
                {
                    ubFontSize += hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].font_size_delta;
                }
            }
            else
            {
                // decrease
                if (ubFontSize >= (hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].font_size_delta + 8) )
                {
                    ubFontSize -= hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].font_size_delta;
                }
            }

            /* adjust text box horizontal position based on user style selected */
            if (hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_horizontal_position_direction == 0)
            {
                // right
                if ( (usTextBoxX + hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_horizontal_position_delta) <= usSfcWidth)
                {
                    usTextBoxX += hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_horizontal_position_delta;
                }
            }
            else
            {
                // left
                if (usTextBoxX > hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_horizontal_position_delta)
                {
                    usTextBoxX -= hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_horizontal_position_delta;
                }
            }

            /* adjust text box vertical position based on user style selected */
            if (hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_vertical_position_direction == 0)
            {
                // down
                if ( (usTextBoxY + hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_vertical_position_delta) <= usSfcHeight)
                {
                    //usTextBoxY += hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_vertical_position_delta;
                }
            }
            else
            {
                // up
                if (usTextBoxY > hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_vertical_position_delta)
                {
                    //usTextBoxY -= hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_vertical_position_delta;
                }
            }

            /* adjust text box width based on user style selected */
            if (hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_width_inc_dec == 0)
            {
                // increase
                if ( (usTextBoxX + usTextBoxW + hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_width_delta) <= usSfcWidth)
                {
                    usTextBoxW += hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_width_delta;
                }
            }
            else
            {
                // decrease
                if (usTextBoxW > hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_width_delta)
                {
                    usTextBoxW -= hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_width_delta;
                }
            }

            /* adjust text box height based on user style selected */
            if ( (hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_height_inc_dec == 0) &&
                 ( (usTextBoxY + usTextBoxH + hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_height_delta) <= usSfcHeight) )
            {
                // increase
                if ( (usTextBoxY + usTextBoxH + hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_height_delta) <= usSfcHeight)
                {
                    //usTextBoxH += hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_height_delta;
                }
            }
            else
            {
                // decrease
                if (usTextBoxH > hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_height_delta)
                {
                    //usTextBoxH -= hTextST->pDSS->region_style[ubRegionID].user_control_style[hTextST->ubUserStyleID].text_box_height_delta;
                }
            }
        }

#if DBG_ON(DBG_TRACE)
        DBGPRINT(1, ("\nRendering DPS %d, Region %d\n", pRenderInfo->dps_number, i));
        DBGPRINT(1, ("-----------------------------------------\n"));
        DBGPRINT(1, ("Surface Width         = %d\n", usSfcWidth));
        DBGPRINT(1, ("Surface Height        = %d\n", usSfcHeight));
        DBGPRINT(1, ("Text Box X            = %d\n", usTextBoxX));
        DBGPRINT(1, ("Text Box Y            = %d\n", usTextBoxY));
        DBGPRINT(1, ("Text Box Width        = %d\n", usTextBoxW));
        DBGPRINT(1, ("Text Box Height       = %d\n", usTextBoxH));
        DBGPRINT(1, ("Horizontal Alighment  = %d\n", hTextST->pDSS->region_style[ubRegionID].text_horizontal_alignment));
        DBGPRINT(1, ("Vertical Alignment    = %d\n", hTextST->pDSS->region_style[ubRegionID].text_vertical_alignment));
        DBGPRINT(1, ("Font ID               = %d\n", hTextST->pDSS->region_style[ubRegionID].font_id_ref));
        DBGPRINT(1, ("Font Size             = %d\n", ubFontSize));
        DBGPRINT(1, ("Text Color            = %d\n", hTextST->pDSS->region_style[ubRegionID].font_palette_entry_id_ref));
#endif

        /* Set surface description */
        dsc.flags                   = (DFBSurfaceDescriptionFlags)(DSDESC_PREALLOCATED | DSDESC_PIXELFORMAT | DSDESC_WIDTH | DSDESC_HEIGHT);
        dsc.pixelformat             = DSPF_LUT8;
        dsc.width                   = usSfcWidth;
        dsc.height                  = usSfcHeight;
        dsc.preallocated[0].data    = pBmpObj->pvBitmapBuffer[i];
        dsc.preallocated[0].pitch   = usSfcWidth;

        /* Create a directfb surface for the bitmap object */
        if (hTextST->DFBInfo.pDFBHandle->CreateSurface(hTextST->DFBInfo.pDFBHandle, &dsc, &pBmpObj->surface[i]) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("textstrenderDPSRender: Failed to create surface!\n"));
            goto errout;
        }

        /* Set font id and check that it is valid */
        ubFontID = hTextST->pDSS->region_style[ubRegionID].font_id_ref;
        if (ubFontID >= hTextST->ubNumberOfFonts)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("textstrenderDPSRender: Invalid font id (%u), dps # = %lu!\n", ubFontID, pBmpObj->dps_number));
            goto errout;
        }

        /* set font description */
        font_dsc.flags  = DFDESC_HEIGHT;
        font_dsc.height = ubFontSize;

        /* Create the font for the text subtitle */
        if (hTextST->DFBInfo.pDFBHandle->CreateMemoryFont(hTextST->DFBInfo.pDFBHandle, hTextST->font_info[ubFontID].pvFontBuffer, hTextST->font_info[ubFontID].uiBufferSize, &font_dsc, &font) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("textstrenderDPSRender: Failed to create font!\n"));
            goto errout;
        }

        /* Set the font for the surface */
        if (pBmpObj->surface[i]->SetFont(pBmpObj->surface[i], font) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("textstrenderDPSRender: Failed to set font for surface!\n"));
            goto errout;
        }

        /* Set background color */
        if (pBmpObj->surface[i]->SetColorIndex(pBmpObj->surface[i], hTextST->pDSS->region_style[ubRegionID].region_info.region_bg_palette_entry_id_ref) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("textstrenderDPSRender: Failed to set bg color index!\n"));
            goto errout;
        }

        /* Render background */
        if (pBmpObj->surface[i]->FillRectangle(pBmpObj->surface[i], 0, 0, usSfcWidth, usSfcHeight) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("textstrenderDPSRender: Failed to render bg!\n"));
            goto errout;
        }

        /* set text string based on the text flow */
        if (hTextST->pDSS->region_style[ubRegionID].text_flow == 2)
        {
            char ctmp;

            /* reverse order of string */
            for (int j = 0; j < pRenderInfo->region_subtitle[i].data_length / 2; j++)
            {
                ctmp = pRenderInfo->region_subtitle[i].text_string[pRenderInfo->region_subtitle[i].data_length - j - 1];
                pRenderInfo->region_subtitle[i].text_string[pRenderInfo->region_subtitle[i].data_length - j - 1] = pRenderInfo->region_subtitle[i].text_string[j];
                pRenderInfo->region_subtitle[i].text_string[j] = ctmp;
            }
        }

        /* Set text horizontal coordinates, depends on horizontal alignment */
        if (hTextST->pDSS->region_style[ubRegionID].text_horizontal_alignment == 1)
        {
            // left
            usXcoord = usTextBoxX;
        }
        else
        {
            /* get string width */
            if (font->GetStringWidth(font, (char *)pRenderInfo->region_subtitle[i].text_string,
                                     pRenderInfo->region_subtitle[i].data_length, &str_width) != DFB_OK)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("textstrenderDPSRender: Failed to get string width!\n"));
                goto errout;
            }

            if (hTextST->pDSS->region_style[ubRegionID].text_horizontal_alignment == 3)
            {
                // right
                usXcoord = (usTextBoxX + usTextBoxW) - str_width;
            }
            else
            {
                // center
                usXcoord = (usTextBoxX + (usTextBoxW / 2) ) - (str_width / 2);
            }
        }

        if (hTextST->pDSS->region_style[ubRegionID].text_vertical_alignment == 1)
        {
            // top
            usYcoord = usTextBoxY;
        }
        else
        {
            /*
             * NOTE: Use font size specified in the textst data to calculate vertical coordinate
             * rather than using the DirectFB GetHeight() function.  The DirectFB function returns
             * the distance from one baseline to another baseline if there are multiple lines of text.
             * This value may be larger than the actual text height.
             */
            if (hTextST->pDSS->region_style[ubRegionID].text_vertical_alignment == 2)
            {
                // middle
                usYcoord = (usTextBoxY + (usTextBoxH / 2) ) - (ubFontSize / 2);
            }
            else
            {
                // bottom
                usYcoord = (usTextBoxY + usTextBoxH) - ubFontSize;
            }
        }

        /* set default text color */
        if (pBmpObj->surface[i]->SetColorIndex(pBmpObj->surface[i], hTextST->pDSS->region_style[ubRegionID].font_palette_entry_id_ref) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("textstrenderDPSRender: Failed to set default text color index!\n"));
            goto errout;
        }

        /* Render the text string to the surface, applying any inline style changes */
        ubCharsRendered     = 0;
        ubInlineStyleIndex  = 0;
        ubInlinePosIndex    = 0;
        usXoffset           = 0;
        fInlineColorChange  = FALSE;
        fInlineFontChange   = FALSE;
        while (ubCharsRendered < pRenderInfo->region_subtitle[i].data_length)
        {
            /*
             * Determine string length.  If there is an inline style change in the string, we only
             * want to draw the string up to the point of the inline style change.
             */
            if (pRenderInfo->region_subtitle[i].inline_style_position[ubInlinePosIndex] != 0xff)
            {
                ubStrLength = pRenderInfo->region_subtitle[i].inline_style_position[ubInlinePosIndex] - ubCharsRendered;
            }
            else
            {
                ubStrLength = pRenderInfo->region_subtitle[i].data_length - ubCharsRendered;
            }

            /* Render text */
            if (pBmpObj->surface[i]->DrawString(pBmpObj->surface[i], (char *)&pRenderInfo->region_subtitle[i].text_string[ubCharsRendered],
                                    ubStrLength, (usXcoord + usXoffset), usYcoord, (DFBSurfaceTextFlags)(DSTF_TOP | DSTF_LEFT) ) != DFB_OK)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("textstrenderDPSRender: Failed to render text!\n"));
                goto errout;
            }

            /* get string width */
            if (font->GetStringWidth(font, (char *)&pRenderInfo->region_subtitle[i].text_string[ubCharsRendered],
                                     ubStrLength, &str_width) != DFB_OK)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("textstrenderDPSRender: Failed to get string width!\n"));
                goto errout;
            }

            /* adjust x-coordinate */
            usXoffset += str_width;

            /* adjust number of chars rendered */
            ubCharsRendered += ubStrLength;

            /* If there is an inline style change, then make the change. */
            if (pRenderInfo->region_subtitle[i].inline_style_position[ubInlinePosIndex] != 0xff)
            {
                switch (pRenderInfo->region_subtitle[i].inline_style_type[ubInlinePosIndex])
                {

⌨️ 快捷键说明

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