📄 plxgif.c
字号:
/***************************************************************************
*
* Pollex Mobile Platform
*
* Copyright (c) 2004 by Pollex Mobile Software Co., Ltd.
* All Rights Reserved
*
* Module :
*
* Purpose :
*
\**************************************************************************/
#include "MMI_features.h"
#include "gui.h"
#include "gdi_include.h"
#include "CommonScreens.h"
#include "PlxPublic.h"
typedef struct tag_Gif_Clip
{
long x1;
long y1;
long x2;
long y2;
}GIFCLIP;
typedef struct tag_Play_GIF
{
UI_image_type pData;
long dataLen;
long x;
long y;
long width;
long height;
long stretchW;
long stretchH;
int nFrame;
int curFrame;
unsigned long id;
GIFCLIP clip;
}GIFPLAY, *PGIFPLAY;
typedef struct tag_Gif_Block
{
PGIFPLAY pGifPlay;
int totalBlocks;
int items;
U16 timerID;
}GIFBLK, *PGIFBLK;
#define SIZE_ONCE_ALLOC 5
#define GIF_TIMER_ID 63517
#define GIF_TIMER_DELAY 500
static GIFBLK gifBlk = {0, 0, 0, 0};
/* 0, 0,
128, 160};*/
static int AddOneGif(UI_image_type pData, long dataLen, long x, long y, long w, long h, long stretchWidth, long stretchHeight);
static int RmOneGif();
static void GifTimerFunc(void);
static void PaintGifFrame(PGIFPLAY pGif, int nInc);
static PGIFPLAY GetGifFromHandle(HGIF hGif);
static unsigned long PlxAppGetTickCount(void);
//void PlxTrace(const char* fmt, ...);
/****************************************************************************
* Function PlxShowGif
* Purpose begin show a gif image
* Params
* Return >0 the gif handle, <=0 error
* Remarks
\****************************************************************************/
HGIF PlxShowGif(UI_image_type pData, long dataLen, long x, long y, long strectWidth, long stretchHeight)
{
PGIFPLAY pGif;
long width, height;
GDI_RESULT gdiRlt;
int nAddRet;
//PlxTrace("%s, %d : Get Gif width and height", __FILE__, __LINE__);
gdiRlt = gdi_image_gif_get_dimension(pData+8, (S32 *)&width, (S32 *)&height);
//PlxTrace("%s, %d : Get Gif width and height DONE!, width:%d, height:%d", __FILE__, __LINE__, width, height);
if (0 > gdiRlt)
{
return 0; //wrong gif data
}
nAddRet = AddOneGif(pData, dataLen, x, y, width, height, strectWidth, stretchHeight);
if (0 > nAddRet)
{
return 0; //add gif block error
}
pGif = gifBlk.pGifPlay + nAddRet - 1;
if (pGif->nFrame > 1)
{
if (0 == gifBlk.timerID)
{
pixtel_UI_start_timer(GIF_TIMER_DELAY, GifTimerFunc);
gifBlk.timerID = GIF_TIMER_ID;
}
}
pixtel_UI_get_clip((s32*)&pGif->clip.x1,(s32*) &pGif->clip.y1,
(s32*)&pGif->clip.x2,(s32*) &pGif->clip.y2);
//PlxTrace("%s, %d : Ready to draw a frame", __FILE__, __LINE__);
PaintGifFrame(pGif, 0);
//PlxTrace("%s, %d : draw frame DONE!", __FILE__, __LINE__);
return (HGIF)pGif->id;
}
/****************************************************************************
* Function PlxPaintGif
* Purpose repaint the gif
* Params
* Return
* Remarks
\****************************************************************************/
void PlxPaintGif(HGIF hGif, long x, long y)
{
PGIFPLAY pGifPlay;
pGifPlay = GetGifFromHandle(hGif);
if (0 == pGifPlay)
{
return;
}
if (x > 0)
{
pGifPlay->x = x;
}
if (y > 0)
{
pGifPlay->y = y;
}
PaintGifFrame(pGifPlay, 0);
}
/****************************************************************************
* Function PlxEndShowGif
* Purpose end the show of a gif
* Params
* Return
* Remarks
\****************************************************************************/
void PlxEndShowGif(HGIF hGif)
{
int i;
PGIFPLAY pGif;
for (i = 0; i < gifBlk.items; ++ i)
{
if ((unsigned long)hGif == (gifBlk.pGifPlay + i)->id)
{
pGif = gifBlk.pGifPlay + i;
break;
}
}
if (i >= gifBlk.items)
{
return;
}
for (; i < gifBlk.items; ++ i)
{
PlxAppMemcpy(pGif, pGif + 1, sizeof(GIFPLAY));
++ pGif;
}
-- gifBlk.items;
for (i = 0; i < gifBlk.items; ++ i)
{
if ((gifBlk.pGifPlay + i)->nFrame > 1)
{
break;
}
}
if (i >= gifBlk.items)
{
pixtel_UI_cancel_timer(GifTimerFunc);
gifBlk.timerID = 0;
}
if (0 == gifBlk.items)
{
if (NULL != gifBlk.pGifPlay)
{
PlxAppFree(gifBlk.pGifPlay);
gifBlk.pGifPlay = 0;
}
gifBlk.totalBlocks = 0;
}
}
/****************************************************************************
* Function PlxEndShowAllGifs
* Purpose end show all gifs
* Params
* Return
* Remarks
\****************************************************************************/
void PlxEndShowAllGifs(void)
{
pixtel_UI_cancel_timer(GifTimerFunc);
gifBlk.timerID = 0;
if (NULL != gifBlk.pGifPlay)
{
PlxAppFree(gifBlk.pGifPlay);
gifBlk.pGifPlay = 0;
}
gifBlk.totalBlocks = 0;
gifBlk.items = 0;
}
/****************************************************************************
* Function AddOneGif
* Purpose add one gif info
* Params
* Return
* Remarks
\****************************************************************************/
static int AddOneGif(UI_image_type pData, long dataLen, long x, long y, long w, long h, long stretchWidth, long stretchHeight)
{
PGIFPLAY pGifPlay;
void* pTemp;
if (gifBlk.items + 1 > gifBlk.totalBlocks)
{
pTemp = PlxAppRealloc(gifBlk.pGifPlay, (gifBlk.totalBlocks + SIZE_ONCE_ALLOC) * sizeof(GIFPLAY));
if (NULL == pTemp)
{
return -1; //memory error
}
gifBlk.pGifPlay = pTemp;
gifBlk.totalBlocks += SIZE_ONCE_ALLOC;
}
pGifPlay = gifBlk.pGifPlay + gifBlk.items;
pGifPlay->curFrame = 0;
pGifPlay->pData = pData;
pGifPlay->dataLen = dataLen;
pGifPlay->x = x;
pGifPlay->y = y;
pGifPlay->width = w;
pGifPlay->height = h;
pGifPlay->stretchW = stretchWidth;
pGifPlay->stretchH = stretchHeight;
PlxMakeImageSizeForMTK(&pGifPlay->x, &pGifPlay->y, w, h, &pGifPlay->stretchW, &pGifPlay->stretchH);
// pGifPlay->nFrame = pixtel_UI_image_n_frames(pData);
gdi_image_gif_get_frame_count((U8*)pData + 8, *((U32*)(pData + 2)), &pGifPlay->nFrame);
//PlxTrace("%s, %d : pGifPlay->nFrame = %d", __FILE__, __LINE__, pGifPlay->nFrame);
++ gifBlk.items;
pGifPlay->id = (unsigned long)((HGIF)PlxAppGetTickCount());
return gifBlk.items;
}
/****************************************************************************
* Function GifTimerFunc
* Purpose when playing gif, the timer callback func
* Params
* Return
* Remarks
\****************************************************************************/
static void GifTimerFunc(void)
{
int i;
PGIFPLAY pGif;
for (i = 0; i < gifBlk.items; i ++)
{
pGif = gifBlk.pGifPlay + i;
if (pGif->nFrame > 1)
{
PaintGifFrame(pGif, 1);
}
}
pixtel_UI_start_timer(GIF_TIMER_DELAY, GifTimerFunc);
}
/****************************************************************************
* Function PaintGifFrame
* Purpose paint one gif frame
* Params
* Return
* Remarks
\****************************************************************************/
static void PaintGifFrame(PGIFPLAY pGif, int nInc)
{
gdi_handle base_handle;
if (nInc > 0)
{
pGif->curFrame += nInc;
if (pGif->curFrame >= pGif->nFrame)
{
pGif->curFrame = 0;
}
}
pixtel_UI_push_clip();
pixtel_UI_set_clip(pGif->clip.x1, pGif->clip.y1, pGif->clip.x2, pGif->clip.y2);
gdi_layer_get_base_handle(&base_handle);
gdi_layer_push_and_set_active(base_handle);
gdi_image_gif_draw_resized(pGif->x, pGif->y, pGif->stretchW, pGif->stretchH, (U8 *)pGif->pData + 8,
(U32)pGif->dataLen, (U16)pGif->curFrame);
gdi_layer_pop_and_restore_active();
pixtel_UI_pop_clip();
pixtel_UI_BLT_double_buffer(pGif->x, pGif->y, pGif->x + pGif->width, pGif->y + pGif->height);
BROW_RepaintSpecialArea (pGif->x, pGif->y, pGif->x + pGif->stretchW - 1, pGif->y + pGif->stretchH - 1);
}
/****************************************************************************
* Function GetGifFromHandle
* Purpose get a gif item
* Params
* Return
* Remarks
\****************************************************************************/
static PGIFPLAY GetGifFromHandle(HGIF hGif)
{
int i;
PGIFPLAY pGif = 0;
for (i = 0; i < gifBlk.items; ++ i)
{
if ((gifBlk.pGifPlay + i)->id == (unsigned long)hGif)
{
pGif = gifBlk.pGifPlay + i;
break;
}
}
return pGif;
}
/****************************************************************************
* Function PlxAppGetTickCount
* Purpose get tick count
* Params
* Return
* Remarks
\****************************************************************************/
#ifdef MMI_ON_HARDWARE_P
typedef unsigned int kal_uint32;
void kal_get_time ( kal_uint32* ticks_ptr);
#endif
static unsigned long PlxAppGetTickCount(void)
{
unsigned long last_time;
#ifdef MMI_ON_HARDWARE_P
unsigned int last_ticks;
kal_get_time ( &last_ticks );
last_time = kal_ticks_to_milli_secs ( last_ticks );
return last_time;
#else
__declspec(dllimport) unsigned long _stdcall GetTickCount(void);
last_time = GetTickCount();
return last_time;
#endif
}
/****************************************************************************
* Function PlxMakeImageSizeForMTK
* Purpose make the size fit mtk's gif function
* Params
* Return TRUE size changed; FALSe not changed
* Remarks
\****************************************************************************/
BOOL PlxMakeImageSizeForMTK(long *x, long *y, long w, long h, long *stw, long *sth)
{
long w1, h1;
long x1, y1;
double rate, rw, rh;
w1 = *stw;
h1 = *sth;
x1 = *x;
y1 = *y;
if (w1 > w || h1 > h)
{
rw = (double)w1 / (double)w;
rh = (double)h1 / (double)h;
rate = rw < rh ? rw : rh;
if (rate >= 1)
{
*stw = w;
*sth = h;
return TRUE;
}
else
{
*stw = (long)(w * rate);
*sth = (long)(h * rate);
*x = x1 + (w1 - *stw) / 2;
*y = y1 + (h1 - *sth) / 2;
if(*stw <= 0)
*stw = 1;
if(*sth <= 0)
*sth = 1;
return TRUE;
}
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -