SmartAudio/package/allwinner/liballwinner_tina/liballwinner/LIBRARY/PLAYER/subtitleNativeDisplay/subtitleNativeDisplay.cpp

2720 lines
75 KiB
C++
Raw Normal View History

2018-07-13 01:31:50 +00:00
//
// Copyright 2010 The Android Open Source Project
//
// The Display dispatcher.
//
//#define LOG_NDEBUG 0
#define LOG_TAG "subtitleNativeDisplay"
#include "log.h"
#include "cdx_config.h"
#include <stddef.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <utils/Errors.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <binder/IInterface.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <ui/Region.h>
#include <ui/Rect.h>
#include <ui/PixelFormat.h>
#include <EGL/egl.h>
#include <SkCanvas.h>
#include <SkBitmap.h>
#include <SkImageEncoder.h>
#include <SkXfermode.h>
#include <SkRegion.h>
#include <SkTypeface.h>
#include <SkGlyphCache.h>
#include <SkUtils.h>
#include <SkAutoKern.h>
#include <cutils/properties.h>
#ifdef __cplusplus
extern "C"
{
#endif
#include "unicode/ucnv.h"
#include "unicode/ustring.h"
#ifdef __cplusplus
}
#endif
#include "subtitleNativeDisplay.h"
#include "ui/DisplayInfo.h"
#include "native_window.h"
#include "SkDevice.h"
#include "sdecoder.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BASELAYER 8 //5, 3, higher number layer is on topper.
#define TOPBASELAYER 8 //5, 3
#define BOTTOMBASELAYER 8
#define LAYER_MULTIPLIER 10000
#define LAYER_OFFSET 1000
#define TRANSPARENT_COLOR 0x00050107
#define MAX_TEXTLINE 3
#define MAX_FONTHEIGHT 36
#define SUB_DISPLAY 0
#define FONT_SIZE_UNIT 16
#define DEFAULT_TEXT_SIZE 24
#define SUB_SHOW_NEW_VALID 1
#define SUB_SHOW_OLD_VALID 2
#define SUB_SHOW_INVALID 0
#define SUB_HAS_NONE_COLOR 0
#define SUB_HAS_DEFINED_COLOR 1
#define SUB_HAS_DEFINED_FONTSIZE 1
#define SUB_HAS_NONE_FONTSIZE 0
#define SUB_HAS_DEFINED_STYLE 1
#define SUB_HAS_NONE_STYLE 0
#define SUB_INIT_SET_FONT_INFO 1
#define SUB_USER_SET_FONT_INFO 2
#define PROP_SUBTITLE_MAXFONTSIZE_KEY "media.stagefright.maxsubfont"
#define SAVE_BITMAP_TO_PNG 0
#if SAVE_BITMAP_TO_PNG
static bool save(const char filename[], SkBitmap &bitmap)
{
//remove(filename);
if(!SkImageEncoder::EncodeFile(filename, bitmap, SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality))
{
printf("save png %s failed \n",filename);
}
printf("%s saved ok\n",filename);
return true;
}
#endif
namespace android
{
static SkBitmap::Config convertPixelFormat(PixelFormat ePixelFormat)
{
switch (ePixelFormat)
{
case PIXEL_FORMAT_RGBX_8888:
{
return SkBitmap::kARGB_8888_Config;
}
case PIXEL_FORMAT_RGBA_8888:
{
return SkBitmap::kARGB_8888_Config;
}
case PIXEL_FORMAT_RGBA_4444:
{
return SkBitmap::kARGB_4444_Config;
}
case PIXEL_FORMAT_RGB_565:
{
return SkBitmap::kRGB_565_Config;
}
//case PIXEL_FORMAT_A_8: return SkBitmap::kA8_Config;
default:
{
return SkBitmap::kNo_Config;
}
}
}
static inline int is_ws_(int ch)
{
return !((ch - 1) >> 5);
}
static inline int is_break(int c1,int c2)
{
if(c1 == 0x0D && c2 == 0x0A)
{
return true;
}
return false;
}
static size_t subLineBreak(const char cText[], const char cStop[], const SkPaint& paint, SkScalar margin,size_t *drawCount, int specialEffectFlag, SkScalar* lineWidth)
{
const char* pStart =NULL;
#if(CONFIG_OS_VERSION == OPTION_OS_VERSION_ANDROID_4_2)
SkAutoGlyphCache ac(paint, NULL);
#else
SkAutoGlyphCache ac(paint, NULL, NULL);
#endif
SkGlyphCache* cache = NULL;
SkFixed w = 0;
SkFixed limit=0;
SkAutoKern autokern;
size_t count = 0;
const char* pWord_start = NULL;
int prevWS = true;
int isbreak = false;
int forbidBreakFlag = 0;
const char* pPrevText = NULL;
const char* breaktext = NULL;
SkUnichar uni;
int currWS;
SkUnichar nextuni;
pStart = cText;
cache = ac.getCache();
limit = SkScalarToFixed(margin);
pWord_start = cText;
forbidBreakFlag = ((specialEffectFlag==SUB_RENDER_EFFECT_BANNER_LTOR)||
(specialEffectFlag==SUB_RENDER_EFFECT_BANNER_RTOL)||
(specialEffectFlag==SUB_RENDER_EFFECT_KARAOKE));
while (cText < cStop)
{
pPrevText = cText;
uni = SkUTF8_NextUnichar(&cText);
currWS = is_ws_(uni);
const SkGlyph& mGlyph = cache->getUnicharMetrics(uni);
if (!currWS && prevWS)
{
pWord_start = pPrevText;
}
prevWS = currWS;
if(uni == 0x0D)
{
breaktext = cText;
nextuni = SkUTF8_NextUnichar(&breaktext);
if(nextuni == 0x0A)
{
isbreak = true;
}
else
{
count += SkUTF8_CountUTF8Bytes(pPrevText);
}
}
else
{
count += SkUTF8_CountUTF8Bytes(pPrevText);
}
w += autokern.adjust(mGlyph) + mGlyph.fAdvanceX;
//if ((w > limit) || isbreak)
if(isbreak ||((w>limit)&&(forbidBreakFlag==0)))
{
if (currWS) // eat the rest of the whitespace
{
*drawCount = count;
while (cText < cStop && is_ws_(SkUTF8_ToUnichar(cText)))
{
cText += SkUTF8_CountUTF8Bytes(cText);
}
}
else // backup until a whitespace (or 1 char)
{
if (pWord_start == pStart)
{
if (pPrevText > pStart)
{
cText = pPrevText;
}
}
else
{
cText = pWord_start;
}
*drawCount = cText - pStart;
}
break;
}
}
*lineWidth = (w>limit)? ((SkScalar)(limit>>16)): ((SkScalar)(w>>16));
if(cText >= cStop)
{
*drawCount = count;
}
return cText - pStart;
}
int CedarXSubTextBox::countLines(const char* pText, size_t len, const SkPaint& paint, SkScalar mWidth, SkScalar* subTextWidth, int specialEffectFlag)
{
const char* stop = pText + len;
int nCount = 0;
size_t charCount;
SkScalar lineWidth = 0;
*subTextWidth = 0;
if (mWidth > 0)
{
do
{
nCount += 1;
pText += subLineBreak(pText, stop, paint, mWidth, &charCount, specialEffectFlag, &lineWidth);
if(*subTextWidth < lineWidth)
{
*subTextWidth = lineWidth;
}
} while (pText < stop);
}
return nCount;
}
//////////////////////////////////////////////////////////////////////////////
CedarXSubTextBox::CedarXSubTextBox()
{
mFBox.setEmpty();
mFSpacingMul = SK_Scalar1;
mFSpacingAdd = 0;
fMode = CedarXSubTextBoxLineBreak_Mode;
fSpacingAlign = CedarXSubTextBoxEnd_SpacingAlign;
mLastDispXPos = -1;
mLastDispYPos = -1;
}
void CedarXSubTextBox::setMode(CedarXSubTextBoxMode mode)
{
fMode = SkToU8(mode);
}
void CedarXSubTextBox::setSpacingAlign(CedarXSubTextBoxSpacingAlign align)
{
fSpacingAlign = SkToU8(align);
}
void CedarXSubTextBox::subGetBox(SkRect* box) const
{
if (box)
{
*box = mFBox;
}
}
void CedarXSubTextBox::subSetBox(const SkRect& box)
{
mFBox = box;
}
void CedarXSubTextBox::subSetBox(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom)
{
mFBox.set(left, top, right, bottom);
}
void CedarXSubTextBox::subGetSpacing(SkScalar* mul, SkScalar* add) const
{
if (mul)
{
*mul = mFSpacingMul;
}
if (add)
{
*add = mFSpacingAdd;
}
}
void CedarXSubTextBox::subSetSpacing(SkScalar mul, SkScalar add)
{
mFSpacingMul = mul;
mFSpacingAdd = add;
}
int CedarXSubTextBox::getLastXPos()
{
return mLastDispXPos;
}
int CedarXSubTextBox::getLastYPos()
{
return mLastDispYPos;
}
/////////////////////////////////////////////////////////////////////////////////////////////
int CedarXSub::Show()
{
if(mShow == false)
{
mSurfaceControl->show();
mShow = true;
}
return NO_ERROR;
}
int CedarXSub::Hide()
{
if(mShow == true)
{
mSurfaceControl->hide();
mShow = false;
}
return NO_ERROR;
}
int CedarXSub::setZorderBottom()
{
mSurfaceControl->setLayer(mBottomBaseLayer);
return NO_ERROR;
}
int CedarXSub::setZorderTop()
{
mSurfaceControl->setLayer(mTopBaseLayer);
return NO_ERROR;
}
int CedarXSub::setLayer(int layer)
{
if(mShow == true)
{
SurfaceComposerClient::openGlobalTransaction();
mSurfaceControl->setLayer(layer);
SurfaceComposerClient::closeGlobalTransaction();
}
mLayer = layer;
return NO_ERROR;
}
int CedarXSub::getLayer()
{
return mLayer;
}
int CedarXSub::setBackColor(int color)
{
if(mBackColor != color)
{
mBackColor = color;
if(mShow == true)
{
startRender();
render();
endRender();
}
}
return NO_ERROR;
}
int CedarXSub::getBackColor()
{
return mBackColor;
}
int CedarXSub::getBitmapFormat()
{
int format;
//format = (int)get_bitmap_format();
return PIXEL_FORMAT_RGBA_8888;
}
int CedarXSub::mapDecToRender(int deccharset)
{
switch(deccharset)
{
case SUB_ENCODING_UTF8:
return SUB_CHARSET_UTF_8;
case SUB_ENCODING_UTF16LE:
return SUB_CHARSET_UTF_16LE;
case SUB_ENCODING_UTF32LE:
return SUB_CHARSET_UTF_32LE;
case SUB_ENCODING_UTF32BE:
return SUB_CHARSET_UTF_32BE;
case SUB_ENCODING_BIG5:
return SUB_CHARSET_BIG5;
case SUB_ENCODING_GBK:
return SUB_CHARSET_GBK;
case SUB_ENCODING_UTF16BE:
return SUB_CHARSET_UTF_16BE;
default:
return SUB_CHARSET_UNKNOWN;
}
}
int CedarXSub::convertUniCode(sub_item_inf *sub_info)
{
int charset;
const char* enc = NULL;
//logd("******************CedarXSub::convertUniCode sub_info->encodingType = %d mCharset=%d",sub_info->encodingType,mCharset);
charset = sub_info->encodingType; //mapDecToRender(sub_info->encodingType);
if(charset == SUBTITLE_TEXT_FORMAT_UNKNOWN)
{
charset = mCharset;
}
#if 0
logd("((((((((((((((((((((((((((((((((((((((((((((( CedarXSub::convertUniCode charset = %d",charset);
logd("CedarXSub::convertUniCode!sub_info->subTextBuf = %s",sub_info->subTextBuf);
char fname[128];
sprintf(fname, "/data/camera/fuqiang.txt");
FILE *fp = fopen(fname, "w");
fwrite((void *)sub_info->subTextBuf, sub_info->subTextLen, 1, fp);
fflush(fp);
fclose(fp);
#endif
switch(charset)
{
case SUBTITLE_TEXT_FORMAT_UTF8:
enc = "UTF-8";
break;
case SUBTITLE_TEXT_FORMAT_GB2312:
enc = "HZ-GB-2312" ;
break;
case SUBTITLE_TEXT_FORMAT_UTF16LE:
enc = "UTF-16LE";
break;
case SUBTITLE_TEXT_FORMAT_UTF16BE:
enc = "UTF-16BE";
break;
case SUBTITLE_TEXT_FORMAT_UTF32LE:
enc = "UTF-32LE";
break;
case SUBTITLE_TEXT_FORMAT_UTF32BE:
enc = "UTF-32BE";
break;
case SUBTITLE_TEXT_FORMAT_BIG5:
enc = "Big5";
break;
case SUBTITLE_TEXT_FORMAT_GBK:
enc = "GBK";
break;
case SUBTITLE_TEXT_FORMAT_ANSI: //can not match,set to "UTF-8"
enc = "UTF-8";
break;
default:
enc = "UTF-8";
break;
}
if (enc)
{
UErrorCode status = U_ZERO_ERROR;
UConverter *conv = ucnv_open(enc, &status);
if (U_FAILURE(status))
{
logw("could not create UConverter for %s\n", enc);
return -1;
}
UConverter *utf8Conv = ucnv_open("UTF-8", &status);
if (U_FAILURE(status))
{
logw("could not create UConverter for UTF-8\n");
ucnv_close(conv);
return -1;
}
// first we need to untangle the utf8 and convert it back to the original bytes
// since we are reducing the length of the string, we can do this in place
const char* src = (const char*)sub_info->subTextBuf;
int len = sub_info->subTextLen;
// now convert from native encoding to UTF-8
int targetLength = len * 3 + 1;
memset(mText,0,MAX_SUBLENGTH);
char* target = &mText[0];
ucnv_convertEx(utf8Conv, conv, &target, (const char*)target + targetLength,&src, (const char*)src + len, NULL, NULL, NULL, NULL, true, true, &status);
if (U_FAILURE(status))
{
logw("ucnv_convertEx failed: %d\n", status);
memset(mText,0,MAX_SUBLENGTH);
}
logv("CedarXSub::convertUniCode src = %s, mText: %s\n",sub_info->subTextBuf, mText);
ucnv_close(conv);
ucnv_close(utf8Conv);
}
return NO_ERROR;
}
//*************************************************************************************************//
//*************************************************************************************************//
int CedarXSub::setPosition(int posX,int posY)
{
if(true)
{
size_t count;
int posx;
int posy;
mPosX = posX;
mPosY = posY;
if(mPosX + mMaxWidth > mScreenWidth)
{
//mPosX = mScreenWidth - mMaxWidth;
mMaxWidth = mScreenWidth - mPosX;
}
if(mPosY + mMaxHeight > mScreenHeight)
{
//mPosY = mScreenHeight - mMaxHeight;
mMaxHeight = mScreenHeight - mPosY;
}
SurfaceComposerClient::openGlobalTransaction();
mSurfaceControl->setPosition(mPosX,mPosY);
SurfaceComposerClient::closeGlobalTransaction();
}
return NO_ERROR;
}
int CedarXSub::setPositionYPercent(int percent)
{
int maxYPos = 0;
if(mSubMode & PIC_SUBTITLE)
{
mPosY = (mScreenHeight - mMaxHeight)* (100 - percent) / 100;
if(mPosY + mMaxHeight > mScreenHeight)
{
mPosY = mScreenHeight - mMaxHeight;
}
logd("2@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ %d %d", mPosX, mPosY);
mSurfaceControl->setPosition(mPosX,mPosY);
}
else if((mShow == true) && (mSubMode & TEXT_SUBTITLE))
{
maxYPos = mScreenHeight*(100-percent)/100;
if(mEndy > maxYPos)
{
mEndy = maxYPos;
}
if((mEndy-mStarty)<mTextHeight)
{
mStarty = mEndy-mTextHeight;
}
if(mStarty < 0)
{
mStarty = 0;
}
setPosition(mStartx,mStarty);
mTextBox->subSetBox(0,0,SkIntToScalar(mEndx-mStartx),SkIntToScalar(mEndy-mStarty));
}
return NO_ERROR;
}
int CedarXSub::getPositionX()
{
return mPosX;
}
int CedarXSub::getPositionY()
{
return mPosY;
}
int CedarXSub::getWidth()
{
return mWidth;
}
int CedarXSub::getHeight()
{
return mHeight;
}
int CedarXSub::setFontSize(int fontsize)
{
int len;
SkScalar textBoxHeight;
if(mSubMode & PIC_SUBTITLE)
{
return NO_ERROR;
}
if(fontsize != mFontSize)
{
mFontSize = fontsize;
mPaint.setTextSize(fontsize * mFontScaleRatio / FONT_SIZE_UNIT);
if(mShow == true)
{
len = strlen((char*)mText);
mTextBox->getTextVerInf(mText,len,mPaint,&mTextHeight,&mTextWidth, &textBoxHeight, mStartx, mEndx, mStarty, mEndy, mDispSubInfo->subEffectFlag);
needModifyBoxInf(textBoxHeight);
setPosition(mStartx,mStarty);
mTextBox->subSetBox(0,0,SkIntToScalar(mEndx-mStartx),SkIntToScalar(mEndy-mStarty));
startRender();
render();
endRender();
}
}
return NO_ERROR;
}
int CedarXSub::getFontSize()
{
return mFontSize;
}
int CedarXSub::setTextColor(int color)
{
if(mTextColor != (unsigned int)color)
{
mTextColor = (unsigned int)color;
mPaint.setColor(mTextColor);
if(mShow == true)
{
startRender();
render();
endRender();
}
}
return NO_ERROR;
}
int CedarXSub::getTextColor()
{
return mTextColor;
}
int CedarXSub::setCharset(int Charset)
{
mCharset = Charset;
return NO_ERROR;
}
int CedarXSub::getCharset()
{
return mCharset;
}
int CedarXSub::setTextAlign(int align)
{
if(mTextAlign != align)
{
mTextAlign = align;
if((align & SUN_RENDER_HALIGN_MASK) == SUB_RENDER_HALIGN_LEFT)
{
mPaint.setTextAlign(SkPaint::kLeft_Align);
}
else if((align & SUN_RENDER_HALIGN_MASK) == SUB_RENDER_HALIGN_CENTER)
{
mPaint.setTextAlign(SkPaint::kCenter_Align);
}
else if((align & SUN_RENDER_HALIGN_MASK) == SUB_RENDER_HALIGN_RIGHT)
{
mPaint.setTextAlign(SkPaint::kRight_Align);
}
else
{
mPaint.setTextAlign(SkPaint::kLeft_Align);
}
if((align & SUN_RENDER_VALIGN_MASK) == SUB_RENDER_VALIGN_TOP)
{
if(mTextBox != NULL)
{
mTextBox->setSpacingAlign(CedarXSubTextBox::CedarXSubTextBoxStart_SpacingAlign);
}
}
else if((align & SUN_RENDER_VALIGN_MASK) == SUB_RENDER_VALIGN_CENTER)
{
if(mTextBox != NULL)
{
mTextBox->setSpacingAlign(CedarXSubTextBox::CedarXSubTextBoxCenter_SpacingAlign);
}
}
else if((align & SUN_RENDER_VALIGN_MASK) == SUB_RENDER_VALIGN_BOTTOM)
{
if(mTextBox != NULL)
{
mTextBox->setSpacingAlign(CedarXSubTextBox::CedarXSubTextBoxEnd_SpacingAlign);
}
}
else
{
if(mTextBox != NULL)
{
mTextBox->setSpacingAlign(CedarXSubTextBox::CedarXSubTextBoxStart_SpacingAlign);
}
}
if(mShow == true)
{
startRender();
render();
endRender();
}
}
return NO_ERROR;
}
int CedarXSub::getTextAlign()
{
return mTextAlign;
}
int CedarXSub::setFontStyle(int style)
{
if(mFontStyle != style)
{
mFontStyle = style;
if((style & SUB_RENDER_STYLE_BOLD) == SUB_RENDER_STYLE_BOLD)
{
mPaint.setFakeBoldText(true);
}
else
{
mPaint.setFakeBoldText(false);
}
if((style & SUB_RENDER_STYLE_ITALIC) == SUB_RENDER_STYLE_ITALIC)
{
mPaint.setLinearText(true);
}
else
{
mPaint.setLinearText(false);
}
if((style & SUB_RENDER_STYLE_UNDERLINE) == SUB_RENDER_STYLE_UNDERLINE)
{
mPaint.setUnderlineText(true);
}
else
{
mPaint.setUnderlineText(false);
}
if((style & SUB_RENDER_STYLE_STRIKETHROUGH) == SUB_RENDER_STYLE_STRIKETHROUGH)
{
mPaint.setStrikeThruText(true);
}
else
{
mPaint.setStrikeThruText(false);
}
if(mShow == true)
{
startRender();
render();
endRender();
}
}
return NO_ERROR;
}
int CedarXSub::getFontStyle()
{
return mFontStyle;
}
//************************************************************************************************//
//*************************************************************************************************//
CedarXSubRender::CedarXSubRender()
{
sp<CedarXSub> cedarXSub;
logd("CedarXSubRender::CedarXSubRender xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1");
mUserSetFontColor = 0;
mUserSetFontSize = 20;
mUserSetFontStyle = 0;
mUserSetYPercent = 10;
sub_pre = NULL;
mInitSetFontColor = 0;
mInitSetFontSize = 0;
mInitSetFontStyle = 0;
mDisplay = 0;
mPid = 0;
mBaseLayer = 0;
cedarXSub = new CedarXSub(0, mUserSetFontColor, mUserSetFontSize, mUserSetFontStyle, mUserSetYPercent);
logd("CedarXSubRender::CedarXSubRender xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx2");
/*create main cedarXSub*/
mCedarXSubs.add(cedarXSub);
}
CedarXSubRender::~CedarXSubRender()
{
logd("CedarXSubRender::~CedarXSubRender!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n");
}
int CedarXSubRender::cedarxSubShow()
{
size_t count;
logv("CedarXSubRender::cedarxSubShow!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n");
count = mCedarXSubs.size();
SurfaceComposerClient::openGlobalTransaction();
for(size_t i = 0;i < count;i++)
{
if(mCedarXSubs[i]->getSubShowFlag() == SUB_SHOW_NEW_VALID)
{
mCedarXSubs[i]->Show();
}
}
SurfaceComposerClient::closeGlobalTransaction();
return NO_ERROR;
}
int CedarXSubRender::cedarxSubHide(unsigned int systemTime, unsigned int* hasSubShowFlag)
{
size_t count;
unsigned int remainSubShowFlag;
logv("CedarXSubRender::cedarxSubHide!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n");
count = mCedarXSubs.size();
SurfaceComposerClient::openGlobalTransaction();
remainSubShowFlag = 0;
if(systemTime == 0xFFFFFFFF)
{
for(size_t i = 0;i < count;i++)
{
mCedarXSubs[i]->setSubShowFlag(SUB_SHOW_INVALID);
mCedarXSubs[i]->Hide();
}
}
else
{
for(size_t i = 0;i < count;i++)
{
if(mCedarXSubs[i]->getSubShowFlag()!=SUB_SHOW_INVALID)
{
if((mCedarXSubs[i]->getSubShowEndTime())<=systemTime)
{
mCedarXSubs[i]->setSubShowFlag(SUB_SHOW_INVALID);
mCedarXSubs[i]->Hide();
}
else
{
remainSubShowFlag = 1;
mCedarXSubs[i]->setSubShowFlag(SUB_SHOW_OLD_VALID);
}
}
}
}
if(hasSubShowFlag != NULL)
{
*hasSubShowFlag = remainSubShowFlag;
}
SurfaceComposerClient::closeGlobalTransaction();
if(remainSubShowFlag == 1)
{
for(size_t i = 0;i < count;i++)
{
if(mCedarXSubs[i]->getSubShowFlag()!=SUB_SHOW_INVALID)
{
mCedarXSubs[i]->processSpecialEffect(systemTime);
}
}
}
return NO_ERROR;
}
int CedarXSubRender::cedarxSubSetZorderTop()
{
size_t count;
logd("CedarXSubRender::cedarxSubSetZorderTop!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n");
count = mCedarXSubs.size();
SurfaceComposerClient::openGlobalTransaction();
for(size_t i = 0;i < count;i++)
{
mCedarXSubs[i]->setZorderTop();
}
SurfaceComposerClient::closeGlobalTransaction();
return NO_ERROR;
}
int CedarXSubRender::cedarxSubSetZorderBottom()
{
size_t count;
logd("CedarXSubRender::cedarxSubSetZorderBottom!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n");
count = mCedarXSubs.size();
SurfaceComposerClient::openGlobalTransaction();
for(size_t i = 0;i < count;i++)
{
mCedarXSubs[i]->setZorderBottom();
}
SurfaceComposerClient::closeGlobalTransaction();
return NO_ERROR;
}
int CedarXSubRender::cedarxSubSetPosition(int index,int positionx,int positiony)
{
size_t count;
count = mCedarXSubs.size();
if(index > (int)count)
{
logw("Invalid index value!\n");
return -1;
}
logd("???????????????????1");
return mCedarXSubs[index]->setPosition(positionx,positiony);
}
int CedarXSubRender::cedarxSubSetYPercent(int index,int percent)
{
size_t count;
int i;
count = mCedarXSubs.size();
if(index > (int)count)
{
logw("Invalid index value!\n");
return -1;
}
SurfaceComposerClient::openGlobalTransaction();
#if 0
if(index == -1)
{
for(index=0; index<(int)count; index++)
{
mCedarXSubs[index]->setPositionYPercent(percent);
}
}
else
{
mCedarXSubs[index]->setPositionYPercent(percent);
}
#endif
/*
if(count == 1)
{
if(index==-1)
{
mCedarXSubs[0]->setPositionYPercent(percent);
}
else
{
mCedarXSubs[index]->setPositionYPercent(percent);
}
}
*/
mUserSetYPercent = percent;
if(mCedarXSubs[0]->mShow == true)
{
cedarxSubHide(0xFFFFFFFF,NULL);
if(sub_pre!=NULL)
updateSubPara(sub_pre);
cedarxSubShow();
}
SurfaceComposerClient::closeGlobalTransaction();
return 0;
}
int CedarXSubRender::cedarxSubGetPositionX(int index)
{
size_t count;
count = mCedarXSubs.size();
if(index > (int)count)
{
logw("Invalid index value!\n");
return -1;
}
return mCedarXSubs[index]->getPositionX();
}
int CedarXSubRender::cedarxSubGetPositionY(int index)
{
size_t count;
count = mCedarXSubs.size();
if(index > (int)count)
{
logw("Invalid index value!\n");
return -1;
}
return mCedarXSubs[index]->getPositionY();
}
int CedarXSubRender::cedarxSubGetHeight(int index)
{
size_t count;
count = mCedarXSubs.size();
if(index > (int)count)
{
logw("Invalid index value!\n");
return -1;
}
return mCedarXSubs[index]->getHeight();
}
int CedarXSubRender::cedarxSubGetWidth(int index)
{
size_t count;
count = mCedarXSubs.size();
if(index > (int)count)
{
logw("Invalid index value!\n");
return -1;
}
return mCedarXSubs[index]->getWidth();
}
int CedarXSubRender::cedarxSubSetFontColor(int color)
{
size_t count;
count = mCedarXSubs.size();
for(size_t i = 0;i < count;i++)
{
#if 0
if(mCedarXSubs[i]->getTextColorFlag() == SUB_HAS_NONE_COLOR)
{
mCedarXSubs[i]->setTextColor(color);
}
#else
mCedarXSubs[i]->setTextColor(color);
#endif
}
mInitSetFontColor = (mUserSetFontColor ==0)? SUB_INIT_SET_FONT_INFO : SUB_USER_SET_FONT_INFO;
mUserSetFontColor = color;
return NO_ERROR;
}
int CedarXSubRender::cedarxSubGetFontColor()
{
return mCedarXSubs[0]->getTextColor();
}
int CedarXSubRender::cedarxSubSetFontSize(int size)
{
size_t count;
count = mCedarXSubs.size();
for(size_t i = 0;i < count;i++)
{
#if 0
if(mCedarXSubs[i]->getTextFontSizeFlag() == SUB_HAS_NONE_FONTSIZE)
{
mCedarXSubs[i]->setFontSize(size);
}
#else
mInitSetFontSize = (mUserSetFontSize ==0)? SUB_INIT_SET_FONT_INFO : SUB_USER_SET_FONT_INFO;
mCedarXSubs[i]->setFontSize(size);
#endif
}
mUserSetFontSize = size;
return NO_ERROR;
}
int CedarXSubRender::cedarxSubGetFontSize()
{
return mCedarXSubs[0]->getFontSize();
}
int CedarXSubRender::cedarxSubSetCharset(int charset)
{
size_t count;
count = mCedarXSubs.size();
for(size_t i = 0;i < count;i++)
{
mCedarXSubs[i]->setCharset(charset);
}
return NO_ERROR;
}
int CedarXSubRender::cedarxSubGetCharset()
{
return mCedarXSubs[0]->getCharset();
}
int CedarXSubRender::cedarxSubSetBackColor(int color)
{
size_t count;
count = mCedarXSubs.size();
for(size_t i = 0;i < count;i++)
{
mCedarXSubs[i]->setBackColor(color);
}
return NO_ERROR;
}
int CedarXSubRender::cedarxSubGetBackColor()
{
return mCedarXSubs[0]->getBackColor();
}
int CedarXSubRender::cedarxSubSetAlign(int align)
{
size_t count;
count = mCedarXSubs.size();
for(size_t i = 0;i < count;i++)
{
mCedarXSubs[i]->setTextAlign(align);
}
return NO_ERROR;
}
int CedarXSubRender::cedarxSubGetAlign()
{
return mCedarXSubs[0]->getTextAlign();
}
//**********************************************************************************************************//
//**********************************************************************************************************//
int CedarXSubRender::cedarxSubSetFontStyle(int style)
{
size_t count;
count = mCedarXSubs.size();
for(size_t i = 0;i < count;i++)
{
#if 0
if(mCedarXSubs[i]->getTextFontStyleFlag() == SUB_HAS_NONE_STYLE)
{
mCedarXSubs[i]->setFontStyle(style);
}
#else
mInitSetFontStyle = (mUserSetFontStyle ==0)? SUB_INIT_SET_FONT_INFO : SUB_USER_SET_FONT_INFO;
mCedarXSubs[i]->setFontStyle(style);
#endif
}
mUserSetFontStyle = style;
return NO_ERROR;
}
int CedarXSubRender::cedarxSubGetFontStyle()
{
return mCedarXSubs[0]->getFontStyle();
}
//**********************************************************************************************************//
//**********************************************************************************************************//
int CedarXSub::setSubInf(sub_item_inf *sub_info,int startx, int starty, int endx, int endy, int lastDispx, int lastDispy, int newShowSubFlag, int yPercent)
{
mSubShowFlag = SUB_SHOW_NEW_VALID;
mDispSubInfo = sub_info;
logv("setSubInf start");
if(sub_info->subMode != 0)
{
return 0;
}
setTextBox(sub_info, startx, starty, endx, endy, lastDispx, lastDispy, newShowSubFlag, yPercent);
switch(sub_info->subEffectFlag)
{
case SUB_RENDER_EFFECT_NONE:
{
break;
}
case SUB_RENDER_EFFECT_SCROLL_UP:
{
mAlignment &= SUN_RENDER_HALIGN_MASK;
mAlignment |= SUB_RENDER_VALIGN_TOP;
mEndy = mDispSubInfo->effectEndyPos;
mStarty = mEndy - mMaxHeight;
if(mStarty < 0)
{
mStarty = 0;
}
break;
}
case SUB_RENDER_EFFECT_SCROLL_DOWN:
{
mAlignment &= SUN_RENDER_HALIGN_MASK;
mAlignment |= SUB_RENDER_VALIGN_BOTTOM;
mStarty = mDispSubInfo->effectStartyPos;
mEndy = mStarty + mMaxHeight;
if(mEndy > mScreenHeight)
{
mEndy = mScreenHeight;
}
break;
}
case SUB_RENDER_EFFECT_BANNER_LTOR:
{
mAlignment &= SUN_RENDER_VALIGN_MASK;
mAlignment |= SUB_RENDER_HALIGN_RIGHT;
mStartx = 0;
mEndx = mScreenWidth;
break;
}
case SUB_RENDER_EFFECT_BANNER_RTOL:
{
mAlignment &= SUN_RENDER_VALIGN_MASK;
mAlignment |= SUB_RENDER_HALIGN_LEFT;
mStartx = 0;
mEndx = mScreenWidth;
break;
}
case SUB_RENDER_EFFECT_MOVE:
{
mAlignment &= SUN_RENDER_HALIGN_MASK;
mAlignment &= SUN_RENDER_VALIGN_MASK;
mAlignment |= SUB_RENDER_VALIGN_TOP;
mAlignment |= SUB_RENDER_HALIGN_LEFT;
mStartx = 0;
mEndx = mScreenWidth;
mEndy = mScreenHeight;
mStarty = mScreenHeight -mMaxHeight;
break;
}
case SUB_RENDER_EFFECT_KARAOKE:
{
break;
}
}
logv("setSubInf finish");
return NO_ERROR;
}
int CedarXSub::setSubShowFlag(int subShowFlag)
{
mSubShowFlag = subShowFlag;
return NO_ERROR;
}
int CedarXSub::getSubShowFlag()
{
return mSubShowFlag;
}
unsigned int CedarXSub::getSubShowEndTime()
{
return mDispSubInfo->endTime;
}
int CedarXSub::getTextColorFlag()
{
if(mDispSubInfo == NULL)
{
return SUB_HAS_NONE_COLOR;
}
return (mDispSubInfo->primaryColor>0)? SUB_HAS_DEFINED_COLOR: SUB_HAS_NONE_COLOR;
}
int CedarXSub::getTextFontSizeFlag()
{
if(mDispSubInfo == NULL)
{
return SUB_HAS_NONE_STYLE;
}
return (mDispSubInfo->fontSize>0)? SUB_HAS_DEFINED_FONTSIZE: SUB_HAS_NONE_FONTSIZE;
}
int CedarXSub::getTextFontStyleFlag()
{
if(mDispSubInfo == NULL)
{
return SUB_HAS_NONE_STYLE;
}
return (mDispSubInfo->subStyle==SUB_RENDER_STYLE_NONE)? SUB_HAS_NONE_STYLE:SUB_HAS_DEFINED_STYLE;
}
//**************************************************************************************//
//***************************************************************************************//
int CedarXSub::processSpecialEffect(unsigned int systemTime)
{
int xPos = 0;
int yPos = 0;
int startx = 0;
int endx = 0;
int curSubSectionIdx = 0;
int newAlignment = 0;
if((mSubShowFlag==SUB_SHOW_INVALID) ||(mDispSubInfo->subEffectFlag==SUB_RENDER_EFFECT_NONE))
{
return NO_ERROR;
}
switch(mDispSubInfo->subEffectFlag)
{
case SUB_RENDER_EFFECT_SCROLL_UP:
{
xPos = getPositionX();
yPos = mDispSubInfo->effectEndyPos - (systemTime-mDispSubInfo->startTime)/mDispSubInfo->effectTimeDelay;
setPosition(xPos, yPos);
break;
}
case SUB_RENDER_EFFECT_SCROLL_DOWN:
{
xPos = getPositionX();
yPos = mDispSubInfo->effectStartyPos+(systemTime-mDispSubInfo->startTime)/mDispSubInfo->effectTimeDelay;
setPosition(xPos, yPos);
break;
}
case SUB_RENDER_EFFECT_BANNER_LTOR:
{
xPos = mDispSubInfo->effectStartxPos+(systemTime-mDispSubInfo->startTime)/mDispSubInfo->effectTimeDelay;
mTextBox->subSetBox(0,0,SkIntToScalar(xPos),SkIntToScalar(mEndy-mStarty));
break;
}
case SUB_RENDER_EFFECT_BANNER_RTOL:
{
xPos = mDispSubInfo->effectEndxPos-(systemTime-mDispSubInfo->startTime)/mDispSubInfo->effectTimeDelay;
mTextBox->subSetBox(xPos,0,SkIntToScalar(mEndx-mStartx),SkIntToScalar(mEndy-mStarty));
break;
}
case SUB_RENDER_EFFECT_MOVE:
{
if(mDispSubInfo->effectStartyPos < mDispSubInfo->effectEndyPos)
{
yPos = mDispSubInfo->effectStartyPos +
((mDispSubInfo->effectEndyPos-mDispSubInfo->effectStartyPos)*(systemTime-mDispSubInfo->startTime))/(mDispSubInfo->endTime-mDispSubInfo->startTime);
}
else
{
yPos = mDispSubInfo->effectStartyPos -
((mDispSubInfo->effectStartyPos-mDispSubInfo->effectEndyPos)*(systemTime-mDispSubInfo->startTime))/(mDispSubInfo->endTime-mDispSubInfo->startTime);
}
if(mDispSubInfo->effectStartxPos < mDispSubInfo->effectEndxPos)
{
xPos = mDispSubInfo->effectStartxPos +
((mDispSubInfo->effectEndxPos-mDispSubInfo->effectStartxPos)*(systemTime-mDispSubInfo->startTime))/(mDispSubInfo->endTime-mDispSubInfo->startTime);
}
else
{
xPos = mDispSubInfo->effectStartxPos -
((mDispSubInfo->effectStartxPos-mDispSubInfo->effectEndxPos)*(systemTime-mDispSubInfo->startTime))/(mDispSubInfo->endTime-mDispSubInfo->startTime);
}
setPosition(xPos, yPos);
break;
}
#if 0
case SUB_RENDER_EFFECT_KARAOKE:
{
if((systemTime-mDispSubInfo->startTime)> mDispSubInfo->effectTimeDelay)
{
return NO_ERROR;
}
if((mAlignment&SUN_RENDER_HALIGN_MASK) == SUB_RENDER_HALIGN_LEFT)
{
startx = mStartx;
}
else if((mAlignment&SUN_RENDER_HALIGN_MASK) == SUB_RENDER_HALIGN_CENTER)
{
startx = mStartx+(mEndx-mStartx-(int)mTextWidth)/2;
}
else if((mAlignment&SUN_RENDER_HALIGN_MASK) == SUB_RENDER_HALIGN_RIGHT)
{
startx = mEndx-(int)mTextWidth;
}
endx = startx+mTextWidth*(systemTime-mDispSubInfo->startTime)/mDispSubInfo->effectTimeDelay;
setPosition(startx, mStarty);
mTextBox->subSetBox(0,0,SkIntToScalar(endx-startx),SkIntToScalar(mEndy-mStarty));
newAlignment = mAlignment;
newAlignment &= SUN_RENDER_VALIGN_MASK;
newAlignment |= SUB_RENDER_HALIGN_LEFT;
setTextAlign(newAlignment);
SurfaceComposerClient::openGlobalTransaction();
if(mTextColor != mDispSubInfo->primaryColor)
{
mTextColor = mDispSubInfo->primaryColor;
mPaint.setColor(mTextColor);
}
startRenderRegion(startx, mStarty, endx, mEndy);
render(0);
endRender();
SurfaceComposerClient::closeGlobalTransaction();
return NO_ERROR;
}
#endif
#if 0
case SUB_RENDER_EFFECT_KARAOKE:
{
if((systemTime-mDispSubInfo->startTime)> mDispSubInfo->effectTimeDelay)
{
return NO_ERROR;
}
mDispSubInfo->subKarakoEffectInf->karaKoSectionLen[0] = 0;
mDispSubInfo->subKarakoEffectInf->karaKoSectionLen[68] = 0;
mDispSubInfo->subKarakoEffectInf->karaKoSectionLen[126] = 0;
for(curSubSectionIdx=0; curSubSectionIdx<mDispSubInfo->subKarakoEffectInf->karakoSectionNum; curSubSectionIdx++)
{
baseTime1 = mDispSubInfo->subKarakoEffectInf->karaKoSectionStartTime[curSubSectionIdx];
baseTime2 = mDispSubInfo->subKarakoEffectInf->karaKoSectionStartTime[curSubSectionIdx+1];
logd("***********baseTime1=%d, baseTime2=%d, diffTime=%d\n", baseTime1, baseTime2, (systemTime-mDispSubInfo->startTime));
if(((systemTime-mDispSubInfo->startTime)>=baseTime1)&&
((systemTime-mDispSubInfo->startTime)<baseTime2))
{
break;
}
}
if((mAlignment&SUN_RENDER_HALIGN_MASK) == SUB_RENDER_HALIGN_LEFT)
{
startx = mStartx;
}
else if((mAlignment&SUN_RENDER_HALIGN_MASK) == SUB_RENDER_HALIGN_CENTER)
{
startx = mStartx+(mEndx-mStartx-(int)mTextWidth)/2;
}
else if((mAlignment&SUN_RENDER_HALIGN_MASK) == SUB_RENDER_HALIGN_RIGHT)
{
startx = mEndx-(int)mTextWidth;
}
len1 = mDispSubInfo->subKarakoEffectInf->karaKoSectionLen[curSubSectionIdx];
len2 = mDispSubInfo->subKarakoEffectInf->karaKoSectionLen[curSubSectionIdx+1];
logd("***********len1=%d, len2=%d, curSubSectionIdx=%d\n", len1, len2, curSubSectionIdx);
startx += len1;
endx = startx +(systemTime-mDispSubInfo->startTime-baseTime1)*(len2-len1)/(baseTime2-baseTime1);
//endx = startx+mTextWidth*(systemTime-mDispSubInfo->startTime)/mDispSubInfo->effectTimeDelay;
setPosition(startx, mStarty);
mTextBox->subSetBox(0,0,SkIntToScalar(endx-startx),SkIntToScalar(mEndy-mStarty));
newAlignment = mAlignment;
newAlignment &= SUN_RENDER_VALIGN_MASK;
newAlignment |= SUB_RENDER_HALIGN_LEFT;
setTextAlign(newAlignment);
SurfaceComposerClient::openGlobalTransaction();
if(mTextColor != mDispSubInfo->primaryColor)
{
mTextColor = mDispSubInfo->primaryColor;
mPaint.setColor(mTextColor);
}
startRenderRegion(startx, mStarty, endx, mEndy);
render(0);
endRender();
SurfaceComposerClient::closeGlobalTransaction();
return NO_ERROR;
}
#endif
default:
{
return NO_ERROR;
}
}
SurfaceComposerClient::openGlobalTransaction();
startRender();
render();
endRender();
SurfaceComposerClient::closeGlobalTransaction();
return NO_ERROR;
}
//************************************************************************************************************//
//*********************************************************************************************************** //
int CedarXSub::getTextBox(int* startx, int *starty, int* endx, int* endy, int *lastDispx, int *lastDispy)
{
*startx = mStartx;
*starty = mStarty;
*endx = mEndx;
*endy = mEndy;
*lastDispx = mStartDispx;
*lastDispy = mStartDispy;
return NO_ERROR;
}
//************************************************************************************************************//
//*********************************************************************************************************** //
int CedarXSub::setTextBox(sub_item_inf *sub_info,int startx, int starty, int endx, int endy, int lastDispx, int lastDispy, int newShowSubFlag, int yPercent)
{
int align = 0;
int newStartx = 0;
int newStarty = 0;
int newEndx = 0;
int newEndy = 0;
int maxYPos = 0;
mStartx = startx;
mStarty = starty;
mEndx = endx;
mEndy = endy;
mStartDispx = lastDispx;
mStartDispy = lastDispy;
mMaxWidth = mScreenWidth;
//mMaxHeight = mMaxTextLine*mMaxFontHeight;
mMaxHeight = mScreenHeight;
mPosX = 0;
mPosY = 0;
maxYPos = mScreenHeight*(100-yPercent)/100;
switch(sub_info->subDispPos)
{
case SUB_DISPPOS_TOP_LEFT:
align |= SUB_RENDER_HALIGN_LEFT;
align |= SUB_RENDER_VALIGN_TOP;
newStartx = sub_info->startx;
newStarty = sub_info->starty;
newEndx = mScreenWidth;
newEndy = newStarty+mMaxHeight;
if(newEndy > maxYPos)
{
newEndy = maxYPos;
}
break;
case SUB_DISPPOS_TOP_MID:
align |= SUB_RENDER_HALIGN_CENTER;
align |= SUB_RENDER_VALIGN_TOP;
newStartx = 0;
newStarty = sub_info->starty;
newEndx = mScreenWidth;
newEndy = newStarty+mMaxHeight;
if(newEndy > maxYPos)
{
newEndy = maxYPos;
}
break;
case SUB_DISPPOS_TOP_RIGHT:
align |= SUB_RENDER_HALIGN_RIGHT;
align |= SUB_RENDER_VALIGN_TOP;
newStartx = 0;
newStarty = sub_info->starty;
newEndx = sub_info->endx;
newEndy = newStarty+mMaxHeight;
if(newEndy > maxYPos)
{
newEndy = maxYPos;
}
break;
case SUB_DISPPOS_MID_LEFT:
align |= SUB_RENDER_HALIGN_LEFT;
align |= SUB_RENDER_VALIGN_CENTER;
newStartx = sub_info->startx;
newStarty = (mScreenHeight-mMaxHeight)>>1;
newEndx = mScreenWidth;
newEndy = newStarty+mMaxHeight;
if(newEndy > maxYPos)
{
newEndy = maxYPos;
}
break;
case SUB_DISPPOS_MID_MID:
align |= SUB_RENDER_HALIGN_CENTER;
align |= SUB_RENDER_VALIGN_CENTER;
newStartx = 0;
newStarty = (mScreenHeight-mMaxHeight)>>1;
newEndx = mScreenWidth;
newEndy = newStarty+mMaxHeight;
if(newEndy > maxYPos)
{
newEndy = maxYPos;
}
break;
case SUB_DISPPOS_MID_RIGHT:
align |= SUB_RENDER_HALIGN_RIGHT;
align |= SUB_RENDER_VALIGN_CENTER;
newStartx = 0;
newStarty = (mScreenHeight-mMaxHeight)>>1;
newEndx = sub_info->endx;
newEndy = newStarty+mMaxHeight;
if(newEndy > maxYPos)
{
newEndy = maxYPos;
}
break;
case SUB_DISPPOS_BOT_LEFT:
align |= SUB_RENDER_HALIGN_LEFT;
align |= SUB_RENDER_VALIGN_BOTTOM;
newStartx = sub_info->startx;
newEndy = sub_info->endy;
if(newEndy > maxYPos)
{
newEndy = maxYPos;
}
newEndx = mScreenWidth;
newStarty = newEndy-mMaxHeight;
if(newStarty < 0)
{
newStarty = 0;
}
break;
case SUB_DISPPOS_BOT_MID:
align |= SUB_RENDER_HALIGN_CENTER;
align |= SUB_RENDER_VALIGN_BOTTOM;
newStartx = 0;
newEndx = mScreenWidth;
newEndy = sub_info->endy;
if((newEndy+10) > maxYPos)
{
newEndy = maxYPos;
}
newStarty = newEndy-mMaxHeight;
if(newStarty < 0)
{
newStarty = 0;
}
break;
case SUB_DISPPOS_BOT_RIGHT:
align |= SUB_RENDER_HALIGN_RIGHT;
align |= SUB_RENDER_VALIGN_BOTTOM;
newStartx = 0;
newEndx = sub_info->endx;
newEndy = sub_info->endy;
if(newEndy > maxYPos)
{
newEndy = maxYPos;
}
newStarty = newEndy-mMaxHeight;
if(newStarty < 0)
{
newStarty = 0;
}
break;
default:
align |= SUB_RENDER_HALIGN_CENTER;
align |= SUB_RENDER_VALIGN_BOTTOM;
newStartx = mPosX;
newEndx = mPosX+mWidth;
newEndy = maxYPos;
newStarty = newEndy - mMaxHeight;
if(newStarty < 0)
{
newStarty = 0;
}
break;
}
if((newShowSubFlag==0)&&(newStartx==mStartx)&&(newStarty==mStarty)&&(newEndx==mEndx)&&(newEndy==mEndy))
{
mStartx = newStartx;
mEndx = newEndx;
mEndy = mStartDispy+mStarty;
mStarty = mEndy-mMaxHeight;
if(mStarty < 0)
{
mStarty = 0;
}
}
else
{
mStartx = newStartx;
mStarty = newStarty;
mEndx = newEndx;;
mEndy = newEndy;
}
mAlignment = align;
logv("******rendere:align=%x,subDispPos=%d,startx=%d,starty=%d,endx=%d,endy=%d, orgStartx=%d,orgStarty=%d,orgEndx=%d,orgEndy=%d\n",align,sub_info->subDispPos,mStartx,
mStarty, mEndx, mEndy,sub_info->startx,sub_info->starty,sub_info->endx,sub_info->endy);
return NO_ERROR;
}
//************************************************************************************************************//
//*********************************************************************************************************** //
int CedarXSub::generateBitmap(sub_item_inf *sub_info)
{
ssize_t bpr = sub_info->subPicWidth * bytesPerPixel(PIXEL_FORMAT_RGBA_8888);
mBitmap.setConfig(convertPixelFormat(PIXEL_FORMAT_RGBA_8888), sub_info->subPicWidth, sub_info->subPicHeight, bpr);
mBitmap.setIsOpaque(true);
if (sub_info->subPicWidth > 0 && sub_info->subPicHeight > 0)
{
//set R of bitmap(RGBA) to 0
for (int i = 0 ; i < sub_info->subPicWidth * sub_info->subPicHeight; i++ )
{
sub_info->subBitmapBuf[4*i] = 0;
}
mBitmap.setPixels((void *)sub_info->subBitmapBuf);
}
else
{
// be safe with an empty bitmap.
mBitmap.setPixels(NULL);
}
return NO_ERROR;
}
//***************************************************************************************//
//**************************************************************************************//
void CedarXSubTextBox::drawText(SkCanvas* canvas, const char *text, size_t len, const SkPaint& mPaint, SkScalar textHeight, int specialEffectFlag)
{
size_t drawCount;
SkScalar lineWidth;
SkASSERT(canvas && &mPaint && (text || len == 0));
SkScalar mMarginWidth = mFBox.width();
logv("*************&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&CedarXSubTextBox::drawText len = %d,mMarginWidth = %f\n",len,mMarginWidth);
if (mMarginWidth <= 0 || len == 0)
{
return;
}
const char* textStop = text + len;
SkScalar mSkScalarX=0, mSkScalarY=0, mScaledSpacing, height, mFontHeight;
SkPaint::FontMetrics mMetrics;
switch (mPaint.getTextAlign())
{
case SkPaint::kLeft_Align:
mSkScalarX = 0;
break;
case SkPaint::kCenter_Align:
mSkScalarX = SkScalarHalf(mMarginWidth);
break;
default:
mSkScalarX = mMarginWidth;
break;
}
mSkScalarX += mFBox.fLeft;
mFontHeight = mPaint.getFontMetrics(&mMetrics);
mScaledSpacing = SkScalarMul(mFontHeight, mFSpacingMul) + mFSpacingAdd;
height = mFBox.height();
// compute mSkScalarY position for first line
{
switch (fSpacingAlign)
{
case CedarXSubTextBoxStart_SpacingAlign:
mSkScalarY = 0;
break;
case CedarXSubTextBoxCenter_SpacingAlign:
mSkScalarY = SkScalarHalf(height - textHeight);
break;
default:
mSkScalarY = height - textHeight;
break;
}
mSkScalarY += mFBox.fTop - mMetrics.fAscent;
//logd("CedarXSubTextBox::drawText mSkScalarY = %f,mFBox.fTop=%f,mMetrics.fAscent = %f,textHeight = %f,height = %f\n",mSkScalarY,mFBox.fTop,mMetrics.fAscent,textHeight,height);
}
mLastDispXPos = (int)mSkScalarX;
mLastDispYPos = (int)(mSkScalarY-mScaledSpacing);
for (;;)
{
len = subLineBreak(text, textStop, mPaint, mMarginWidth,&drawCount,specialEffectFlag, &lineWidth);
if (mSkScalarY + mMetrics.fDescent + mMetrics.fLeading > 0)
{
canvas->drawText(text, drawCount, mSkScalarX, mSkScalarY, mPaint);
logv("canvas->drawText!text = %s,drawCount = %d\n",text,drawCount);
}
text += len;
if (text >= textStop)
{
break;
}
mSkScalarY += mScaledSpacing;
if (mSkScalarY + mMetrics.fAscent >= height)
{
break;
}
}
}
//************************************************************************************************************//
//*********************************************************************************************************** //
int CedarXSub::render()
{
if(mCanvas == NULL)
{
logd("shit!!!!!!!!!");
}
mCanvas->drawColor(mBackColor, SkXfermode::kSrc_Mode);
if(mSubMode & TEXT_SUBTITLE)
{
int len;
SkScalar textHeight;
SkScalar textBoxHeight;
len = strlen(mText);
mTextBox->drawText(mCanvas, mText, len, mPaint, mTextHeight, mDispSubInfo->subEffectFlag);
mStartDispx = mTextBox->getLastXPos();
mStartDispy = mTextBox->getLastYPos();
}
else if(mSubMode & PIC_SUBTITLE)
{
int posx = 0;
int posy = 0;
int width = mBitmap.width();
int height = mBitmap.height();
if((mDispSubInfo->subScaleWidth==0)||(mDispSubInfo->subScaleHeight==0))
{
posx = (mWidth - width)>>1;
posy = (mHeight - height);
posx = (posx<0)? 0 : posx;
posy = (posy<0)? 0 : posy;
#if SAVE_BITMAP_TO_PNG
save("/data/local/tmp/subBitmapS011",mBitmap);
#endif
mCanvas->drawBitmap(mBitmap,posx,posy,&mPaint);
#if SAVE_BITMAP_TO_PNG
SkBitmap BitmapIncanvas = mCanvas->getDevice()->accessBitmap(false);
save("/data/local/tmp/subBitmapS011-output",BitmapIncanvas);
#endif
}
else
{
SkIRect src;
SkRect dst;
src.set(0,0,width, height);
posx = (mWidth - mDispSubInfo->subScaleWidth)>>1;
posy = (mHeight - mDispSubInfo->subScaleHeight);
posx = (posx<0)? 0 : posx;
posy = (posy<0)? 0 : posy;
dst.set(posx,posy,posx+mDispSubInfo->subScaleWidth, posy+mDispSubInfo->subScaleHeight);
mCanvas->drawBitmapRect(mBitmap, &src, dst,&mPaint);
}
}
return NO_ERROR;
}
//************************************************************************************************************//
//*********************************************************************************************************** //
CedarXSub::CedarXSub(int index, int userSetFontColor, int userSetFontSize, int userSetFontStyle, int userSetYpercent)
{
status_t err;
sp<Surface> mSurface;
char prop_value[4];
int int_val;
DisplayInfo mDisplayInfo;
logd("CedarXSub::CedarXSub #####################\n");
mDisplay = SUB_DISPLAY;
mMaxTextLine = MAX_TEXTLINE;
mFontScaleRatio = FONT_SIZE_UNIT;
mMaxFontHeight = MAX_FONTHEIGHT;
mPid = IPCThreadState::self()->getCallingPid();
mShow = false;
sp<SurfaceComposerClient> mClient = new SurfaceComposerClient;
mSurfaceClient = mClient;
sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
SurfaceComposerClient::getDisplayInfo(dtoken, &mDisplayInfo);
mScreenWidth = mDisplayInfo.w;
mScreenHeight = mDisplayInfo.h;
mMaxWidth = mScreenWidth;
if(mScreenHeight >= 1080)
{
mFontScaleRatio = FONT_SIZE_UNIT * 3; //X3
mMaxFontHeight = mMaxFontHeight * 3;
}
else if (mScreenHeight >= 720) {
mFontScaleRatio = FONT_SIZE_UNIT * 3 / 2; //X1.5
mMaxFontHeight = mMaxFontHeight * 3 / 2;
}
else if (mScreenHeight >= 600) {
mFontScaleRatio = FONT_SIZE_UNIT * 5 / 4; //X1.25
mMaxFontHeight = mMaxFontHeight * 5 / 4;
}
mMaxHeight = mScreenHeight;
if(mScreenHeight >= 1080)
{
if(mMaxHeight <= 300)
{
mMaxHeight = 300;
}
}
else
{
if(mMaxHeight <= 300)
{
mMaxHeight = 300;
}
}
if(mMaxWidth >= mScreenWidth)
{
mPosX = 0;
}
else
{
mPosX = (mScreenWidth - mMaxWidth)>>1;
}
if(mMaxHeight >= mScreenHeight)
{
mPosY = 0;
}
else
{
mPosY = (mScreenHeight - mMaxHeight)* (100 - userSetYpercent) / 100;
}
String8 name;
const size_t SIZE = 128;
char buffer[SIZE];
snprintf(buffer, SIZE, "<pid_%d>", getpid());
name.append(buffer);
mSurfaceControl = mClient->createSurface(name, mMaxWidth, mMaxHeight, PIXEL_FORMAT_TRANSPARENT, ISurfaceComposerClient::eFXSurfaceNormal);
if(mSurfaceControl != NULL)
{
SurfaceComposerClient::openGlobalTransaction();
mTopBaseLayer = TOPBASELAYER * LAYER_MULTIPLIER + LAYER_OFFSET + 2 + index;
mBottomBaseLayer= BOTTOMBASELAYER * LAYER_MULTIPLIER + LAYER_OFFSET - 10 + index;
mLayer = mTopBaseLayer;
logd("3@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ %d %d", mPosX, mPosY);
mSurfaceControl->setPosition(mPosX,mPosY);
//mSurfaceControl->setLayer(mLayer);
mSurfaceControl->setLayer(99999);
mSurfaceControl->hide();
SurfaceComposerClient::closeGlobalTransaction();
mCanvas = new SkCanvas;
mWidth = mMaxWidth;
mHeight = mMaxHeight;
mPaint.setAntiAlias(true);
logd("=**********************8 mFontScaleRatio = %d", mFontScaleRatio);
if(userSetFontSize == 0)
{
mPaint.setTextSize(DEFAULT_TEXT_SIZE * mFontScaleRatio / FONT_SIZE_UNIT);
}
else
{
mPaint.setTextSize(userSetFontSize * mFontScaleRatio / FONT_SIZE_UNIT);
}
if(userSetFontColor == 0)
{
mPaint.setColor(0xFFFFFFFF);
}
else
{
mPaint.setColor(userSetFontColor);
}
if(userSetFontStyle == 0)
{
mFontStyle = SUB_RENDER_STYLE_NONE;
setFontStyle(SUB_RENDER_STYLE_NONE);
}
else
{
setFontStyle(userSetFontStyle);
}
mPaint.setTextAlign(SkPaint::kCenter_Align);
mBackColor = TRANSPARENT_COLOR;
#if(CONFIG_OS_VERSION >= OPTION_OS_VERSION_ANDROID_5_0)
mTypeface = SkTypeface::CreateFromFile("/system/fonts/DroidSansFallbackAndroid44.ttf");
#else
mTypeface = SkTypeface::CreateFromFile("/system/fonts/DroidSansFallback.ttf");
#endif
mPaint.setTypeface(mTypeface);
mCharset = SUBTITLE_TEXT_FORMAT_GBK;
mTextBox = NULL;
mSubMode = 0;
mDispSubInfo = NULL;
mSubShowFlag = SUB_SHOW_INVALID;
}
}
//************************************************************************************************************//
//*********************************************************************************************************** //
CedarXSub::~CedarXSub()
{
if(mTypeface != NULL)
{
mTypeface->unref();
}
logd("CedarXSub::~CedarXSub1!\n");
if(mCanvas != NULL)
{
mCanvas->unref();
}
logd("CedarXSub::~CedarXSub2!\n");
if(mTextBox != NULL)
{
delete mTextBox;
}
logd("CedarXSub::~CedarXSub3!\n");
if (SurfaceControl::isValid(mSurfaceControl))
{
mSurfaceControl->clear();
}
logd("CedarXSub::~CedarXSub4!\n");
}
//************************************************************************************************************//
//*********************************************************************************************************** //
#if 0
int CedarXSub::startRenderRegion(int startx, int starty, int endx, int endy)
{
ANativeWindow_Buffer nativeWindowBuffer;
status_t err;
SkBitmap mBitmap;
sp<Surface> mSurface;
Region dirtyRegion;
Rect dirty;
dirty.left = startx;
dirty.top = starty;
dirty.right = endx;
dirty.bottom = endy;
//dirtyRegion.set(dirty);
mSurface = mSurfaceControl->getSurface();
err = mSurface->lock(&nativeWindowBuffer, &dirty);
logd("//////////////////////////////////////////////////////1");
if (err < 0)
{
logw("get surface information failed!\n");
return -1;
}
ssize_t bpr = nativeWindowBuffer.width * bytesPerPixel(nativeWindowBuffer.format);
mBitmap.setConfig(convertPixelFormat(nativeWindowBuffer.format), endx-startx, endy-starty, bpr);
if (nativeWindowBuffer.format == PIXEL_FORMAT_RGBX_8888)
{
mBitmap.setIsOpaque(true);
}
if (nativeWindowBuffer.width > 0 && nativeWindowBuffer.height > 0)
{
//bitmap.setPixels(info.bits+4*(mStarty*mScreenWidth+mStartx));
mBitmap.setPixels(nativeWindowBuffer.bits);
}
else
{
// be safe with an empty bitmap.
mBitmap.setPixels(NULL);
}
mCanvas->setBitmapDevice(mBitmap);
//mCanvas->setDevice(SkNEW_ARGS(SkDevice, (bitmap)));
//mCanvas->writePixels(bitmap,0,0,SkCanvas::Config8888::kNative_Premul_Config8888);
mSaveCount = mCanvas->save();
return NO_ERROR;
}
#endif
int CedarXSub::startRender()
{
#if(CONFIG_OS_VERSION == OPTION_OS_VERSION_ANDROID_4_2)
Surface::SurfaceInfo info;
status_t err;
SkBitmap mBitmap;
sp<Surface> mSurface;
mSurface = mSurfaceControl->getSurface();
err = mSurface->lock(&info, NULL);
if (err < 0)
{
logw("get surface information failed!\n");
return -1;
}
ssize_t bpr = info.s * bytesPerPixel(info.format);
mBitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, bpr);
if (info.format == PIXEL_FORMAT_RGBX_8888)
{
mBitmap.setIsOpaque(true);
}
if (info.w > 0 && info.h > 0)
{
//bitmap.setPixels(info.bits+4*(mStarty*mScreenWidth+mStartx));
mBitmap.setPixels(info.bits);
}
else
{
// be safe with an empty bitmap.
mBitmap.setPixels(NULL);
}
mCanvas->setBitmapDevice(mBitmap);
mSaveCount = mCanvas->save();
return NO_ERROR;
#else
ANativeWindow_Buffer nativeWindowBuffer;
status_t err;
SkBitmap mBitmap;
sp<Surface> mSurface;
mSurface = mSurfaceControl->getSurface();
err = mSurface->lock(&nativeWindowBuffer, NULL/*false*/);
if (err < 0)
{
logw("get surface information failed!\n");
return -1;
}
ssize_t bpr = nativeWindowBuffer.width * bytesPerPixel(nativeWindowBuffer.format);
mBitmap.setConfig(convertPixelFormat(nativeWindowBuffer.format),
nativeWindowBuffer.width,
nativeWindowBuffer.height, bpr);
/*
for(int k = 0; k < 1280 * 720; k ++)
{
((unsigned int *)outBuffer.bits)[k] = 8334543;
}
*/
if (nativeWindowBuffer.format == PIXEL_FORMAT_RGBX_8888)
{
mBitmap.setIsOpaque(true);
}
if (nativeWindowBuffer.width > 0 && nativeWindowBuffer.height > 0)
{
//bitmap.setPixels(info.bits+4*(mStarty*mScreenWidth+mStartx));
mBitmap.setPixels(nativeWindowBuffer.bits);
}
else
{
// be safe with an empty bitmap.
mBitmap.setPixels(NULL);
}
/*
static int num = 0;
char fname[128];
sprintf(fname, "/data/camera/fuqiang%03d.rgba", num);
num ++;
FILE *fp = fopen(fname, "w");
fwrite((void *)outBuffer.bits, outBuffer.width * outBuffer.height * bytesPerPixel(outBuffer.format), 1, fp);
fflush(fp);
fclose(fp);
*/
mCanvas->setBitmapDevice(mBitmap);
//mCanvas->writePixels(bitmap,0,0,SkCanvas::kNative_Premul_Config8888);
mSaveCount = mCanvas->save();
return NO_ERROR;
#endif
}
int CedarXSub::endRender()
{
status_t err;
sp<Surface> mSurface;
mSurface = mSurfaceControl->getSurface();
// detach the canvas from the surface
mCanvas->restoreToCount(mSaveCount);
mSaveCount = 0;
// unlock surface
err = mSurface->unlockAndPost();
if (err < 0)
{
logw("surface unlockAndPost Failed!\n");
return -1;
}
return NO_ERROR;
}
//************************************************************************************************************//
//*********************************************************************************************************** //
int CedarXSubTextBox::getTextVerInf(const char *text, size_t len, const SkPaint& paint,SkScalar* subTextHeight,SkScalar* subTextWidth,SkScalar* textBoxHeight, int textBoxStartx,
int textBoxEndx, int textBoxStarty, int textBoxEndy, int specialEffectFlag)
{
int nCount = 0;
SkScalar mTextHeight = 0;
const char* textStop;
SkScalar mScaledSpacing, height, mFontHeight;
SkPaint::FontMetrics metrics;
SkScalar marginWidth;
marginWidth = textBoxEndx - textBoxStartx + 1;
mFontHeight = paint.getFontMetrics(&metrics);
mScaledSpacing = SkScalarMul(mFontHeight, mFSpacingMul) + mFSpacingAdd;
height = textBoxEndy - textBoxStarty + 1;
textStop = text + len;
mTextHeight = mFontHeight;
if(fMode == CedarXSubTextBoxLineBreak_Mode)
{
nCount = countLines(text, textStop - text, paint, marginWidth, subTextWidth, specialEffectFlag);
SkASSERT(nCount > 0);
mTextHeight += mScaledSpacing * (nCount - 1);
}
*subTextHeight = mTextHeight;
*textBoxHeight = (SkScalar)(textBoxEndy-textBoxStarty);
return NO_ERROR;
}
//************************************************************************************************************//
//*********************************************************************************************************** //
int CedarXSub::needModifyBoxInf(SkScalar textBoxHeight)
{
int aglignMent= 0;
int offset = 0;
if(mTextHeight <= textBoxHeight)
{
return NO_ERROR; // not need modify text box vertical info
}
else
{
aglignMent = (mAlignment & 0xf0);
if(aglignMent == SUB_RENDER_VALIGN_TOP)
{
if((SkScalar)(mScreenHeight-mStarty) > mTextHeight)
{
mEndy = mStarty + mTextHeight;
if(mEndy >= mScreenHeight)
{
mEndy = mScreenHeight;
}
}
else
{
mEndy = mScreenHeight;
mStarty = mEndy - mTextHeight;
if(mStarty < 0)
{
mStarty = 0;
}
}
}
else if(aglignMent == SUB_RENDER_VALIGN_CENTER)
{
offset = (mTextHeight - textBoxHeight)/2;
mStarty -= offset;
mEndy += offset;
if(mStarty < 0)
{
mStarty = 0;
}
if(mEndy > mScreenHeight)
{
mEndy = mScreenHeight;
}
}
else if(aglignMent == SUB_RENDER_VALIGN_BOTTOM)
{
if((SkScalar)mEndy > mTextHeight)
{
mStarty = mEndy - mTextHeight;
if(mStarty < 0)
{
mStarty = 0;
}
}
else
{
mStarty = 0;
mEndy = mStarty + mTextHeight;
if(mEndy > mScreenHeight)
{
mEndy = mScreenHeight;
}
}
}
}
return NO_ERROR;
}
//************************************************************************************************************//
//*********************************************************************************************************** //
int CedarXSub::updatePara(sub_item_inf *sub_info, int initSetFontColor, int initSetFontSize, int initSetFontStyle, int Ypercent)
{
int len = 0;
int fontIndex = 0;
SkScalar textBoxHeight;
if(sub_info == NULL)
{
logw("input para error!\n");
return -1;
}
mSubMode = 0;
if(sub_info->subMode == 0)
{
mSubMode |= TEXT_SUBTITLE;
convertUniCode(sub_info);
}
else
{
mSubMode |= PIC_SUBTITLE;
generateBitmap(sub_info);
}
if(mSubMode & TEXT_SUBTITLE)
{
logv("CedarXSub::updatePara mText = %s\n",mText);
if(mTextBox == NULL)
{
mTextBox = new CedarXSubTextBox;
mTextAlign |= SUB_RENDER_HALIGN_CENTER;
mTextAlign |= SUB_RENDER_VALIGN_BOTTOM;
}
if(sub_info->subHasFontInfFlag == 1)
{
if((initSetFontSize==SUB_INIT_SET_FONT_INFO)&&(sub_info->fontSize>0))
{
#if 1
fontIndex = (sub_info->fontSize>>2)-2;
fontIndex = (fontIndex<0)? 0:fontIndex;
fontIndex = (fontIndex>16)? 16:fontIndex;
fontIndex += 16;
fontIndex = (fontIndex<25)? 25: fontIndex;
#else
fontIndex = sub_info->fontSize;
#endif
setFontSize(fontIndex);
}
if(mDispSubInfo->subEffectFlag==SUB_RENDER_EFFECT_KARAOKE)
{
if(sub_info->secondaryColor > 0)
{
setTextColor(sub_info->secondaryColor);
}
}
else
{
if((initSetFontColor==SUB_INIT_SET_FONT_INFO)&&(sub_info->primaryColor>0))
{
setTextColor(sub_info->primaryColor);
}
if((initSetFontStyle==SUB_INIT_SET_FONT_INFO) &&(sub_info->subStyle != SUB_RENDER_STYLE_NONE))
{
setFontStyle(sub_info->subStyle);
}
}
}
len = strlen((char*)mText);
#if 0
char fname[128];
sprintf(fname, "/data/camera/fuqiang1.txt");
FILE *fp = fopen(fname, "w");
fwrite((void *)mText, len, 1, fp);
fflush(fp);
fclose(fp);
#endif
mTextBox->getTextVerInf(mText,len,mPaint,&mTextHeight,&mTextWidth, &textBoxHeight, mStartx, mEndx, mStarty, mEndy, mDispSubInfo->subEffectFlag);
needModifyBoxInf(textBoxHeight);
setPosition(mStartx,mStarty -50);
mTextBox->subSetBox(0,0,SkIntToScalar(mEndx-mStartx),SkIntToScalar(mEndy-mStarty));
setTextAlign(mAlignment);
}
else
{
mPosY = (mScreenHeight-mMaxFontHeight)* (Ypercent) / 100;
logd("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mPosY = %d, mScreenHeight = %d, mMaxFontHeight = %d", mPosY, mScreenHeight, mMaxFontHeight);
/*
if(mPosY + mMaxHeight > mScreenHeight)
{
mPosY = mScreenHeight - mMaxHeight;
}
*/
mSurfaceControl->setPosition(mPosX,-mPosY);
}
if((mDispSubInfo->subEffectFlag==SUB_RENDER_EFFECT_NONE)||(mDispSubInfo->subEffectFlag==SUB_RENDER_EFFECT_KARAOKE))
{
startRender();
render();
endRender();
}
return NO_ERROR;
}
//************************************************************************************************************//
//*********************************************************************************************************** //
int CedarXSubRender::updateSubPara(sub_item_inf *sub_info)
{
sub_pre = sub_info;
int count = 0;
size_t size;
sub_item_inf *current;
sp<CedarXSub> cedarXSub;
int dispStartx = 0;
int dispStarty = 0;
int dispHeight = 0;
int align = 0;
int lastPosValidFlag = 0;
int startx = 0;
int starty = 0;
int endx = 0;
int endy = 0;
int lastDispx = 0;
int lastDispy = 0;
int newShowSubFlag = 0;
if(sub_info == NULL)
{
logw("Invalid sub information!\n");
return -1;
}
current = sub_info;
size = mCedarXSubs.size();
newShowSubFlag = 1;
while(current != NULL)
{
if(count > 0)
{
mCedarXSubs[count-1]->getTextBox(&startx, &starty, &endx, &endy, &lastDispx, &lastDispy);
}
if(count >= (int)size)
{
cedarXSub = new CedarXSub(0, mUserSetFontColor, mUserSetFontSize, mUserSetFontStyle, mUserSetYPercent);
/*create main cedarXSub*/
mCedarXSubs.add(cedarXSub);
}
if(mCedarXSubs[count]->getSubShowFlag() == SUB_SHOW_INVALID)
{
if(current == NULL)
{
logd("***********current is null **********");
}
logv("@@startx = %d, starty = %d, endx = %d, endx = %d,lastDispx = %d lastDispy = %d, newShowSubFlag = %d",
startx, starty, endx, endy, lastDispx, lastDispy, newShowSubFlag);
mCedarXSubs[count]->setSubInf(current, startx, starty, endx, endy, lastDispx, lastDispy, newShowSubFlag, mUserSetYPercent);
mCedarXSubs[count]->updatePara(current, mInitSetFontColor, mInitSetFontSize, mInitSetFontStyle, mUserSetYPercent);
current = (sub_item_inf *)current->nextSubItem;
newShowSubFlag = 0;
}
count++;
}
return NO_ERROR;
}
//************************************************************************************************************//
//************************************************************************************************************//
#ifdef __cplusplus
extern "C"
{
#endif
CedarXSubRender* gCedarXSubRender = NULL;
static bool checkCedarXSubRenderUnitialized()
{
if (gCedarXSubRender == NULL)
{
return true;
}
return false;
}
int SubRenderCreate()
{
logd("****************SubRenderCreate!****************\n");
if(gCedarXSubRender == NULL)
{
gCedarXSubRender = new CedarXSubRender();
logd("****************SubRenderCreate success!****************\n");
}
return NO_ERROR;
}
int SubRenderDestory()
{
logd("****************SubRenderDestory!****************\n");
if (checkCedarXSubRenderUnitialized())
{
return -1;
}
logd("****************SubRenderDestory1!****************\n");
delete gCedarXSubRender;
gCedarXSubRender = NULL;
logd("****************SubRenderDestory2!****************\n");
return NO_ERROR;
}
int SubRenderDraw(sub_item_inf *sub_info)
{
if (checkCedarXSubRenderUnitialized())
{
return -1;
}
logv("****************SubRenderDraw!****************\n");
return gCedarXSubRender->updateSubPara(sub_info);
}
int SubRenderShow()
{
if (checkCedarXSubRenderUnitialized())
{
return -1;
}
logv("****************SubRenderShow!****************\n");
return gCedarXSubRender->cedarxSubShow();
}
int SubRenderHide(unsigned int systemTime, unsigned int* hasSubShowFlag)
{
if (checkCedarXSubRenderUnitialized())
{
return -1;
}
logv("****************SubRenderHide!****************\n");
return gCedarXSubRender->cedarxSubHide(systemTime, hasSubShowFlag);
}
int SubRenderSetZorderTop()
{
if (checkCedarXSubRenderUnitialized())
{
return -1;
}
logv("****************SubRenderSetZorderTop!****************\n");
return gCedarXSubRender->cedarxSubSetZorderTop();
}
int SubRenderSetZorderBottom()
{
if (checkCedarXSubRenderUnitialized())
{
return -1;
}
logv("****************SubRenderSetZorderBottom!****************\n");
return gCedarXSubRender->cedarxSubSetZorderBottom();
}
#ifdef __cplusplus
}
#endif
} // namespace android