draft xcinema to be replacement for GUI_ANIME

Signed-off-by: Sergey Isakov <isakov-sl@bk.ru>
This commit is contained in:
Sergey Isakov 2020-04-14 19:52:13 +03:00
parent 807e36c427
commit c32de7f2d2
11 changed files with 281 additions and 80 deletions

View File

@ -98,7 +98,12 @@ CONST CHAR16 **RecoveryPlists = NULL;
// QPI // QPI
BOOLEAN SetTable132 = FALSE; BOOLEAN SetTable132 = FALSE;
#if XCINEMA
// it is a part of Theme
#else
GUI_ANIME *GuiAnime = NULL; GUI_ANIME *GuiAnime = NULL;
#endif
//EG_PIXEL SelectionBackgroundPixel = { 0xef, 0xef, 0xef, 0xff }; //define in lib.h //EG_PIXEL SelectionBackgroundPixel = { 0xef, 0xef, 0xef, 0xff }; //define in lib.h
const INTN BCSMargin = 11; const INTN BCSMargin = 11;
BOOLEAN DayLight; BOOLEAN DayLight;
@ -3463,7 +3468,10 @@ XTheme::GetThemeTagSettings (void* DictP)
ScrollBarDecorationsHeight = 5; ScrollBarDecorationsHeight = 5;
ScrollScrollDecorationsHeight = 7; ScrollScrollDecorationsHeight = 7;
Font = FONT_LOAD; //not default Font = FONT_LOAD; //not default
#if XCINEMA
#else
GuiAnime = NULL; GuiAnime = NULL;
#endif
// if NULL parameter, quit after setting default values, this is embedded theme // if NULL parameter, quit after setting default values, this is embedded theme
@ -3727,9 +3735,75 @@ XTheme::GetThemeTagSettings (void* DictP)
Dict2 = GetProperty (Dict, "Proportional"); Dict2 = GetProperty (Dict, "Proportional");
Proportional = IsPropertyTrue (Dict2); Proportional = IsPropertyTrue (Dict2);
} }
#if XCINEMA
Dict = GetProperty (DictPointer, "Anime");
if (Dict != NULL) {
INTN i, Count = GetTagCount (Dict);
for (i = 0; i < Count; i++) {
FILM *NewFilm = new FILM();
if (EFI_ERROR (GetElement (Dict, i, &Dict3))) {
continue;
}
if (Dict3 == NULL) {
break;
}
Dict2 = GetProperty (Dict3, "ID");
NewFilm->Id = (UINTN)GetPropertyInteger (Dict2, 1); //default=main screen
Dict2 = GetProperty (Dict3, "Path");
if (Dict2 != NULL && (Dict2->type == kTagTypeString) && Dict2->string) {
NewFilm->Path.takeValueFrom(Dict2->string);
}
Dict2 = GetProperty (Dict3, "Frames");
NewFilm->NumFrames = (UINTN)GetPropertyInteger (Dict2, 0);
Dict2 = GetProperty (Dict3, "FrameTime");
NewFilm->FrameTime = (UINTN)GetPropertyInteger (Dict2, 50); //default will be 50ms
Dict2 = GetProperty (Dict3, "ScreenEdgeX");
if (Dict2 != NULL && (Dict2->type == kTagTypeString) && Dict2->string) {
if (AsciiStrCmp (Dict2->string, "left") == 0) {
NewFilm->ScreenEdgeHorizontal = SCREEN_EDGE_LEFT;
} else if (AsciiStrCmp (Dict2->string, "right") == 0) {
NewFilm->ScreenEdgeHorizontal = SCREEN_EDGE_RIGHT;
}
}
Dict2 = GetProperty (Dict3, "ScreenEdgeY");
if (Dict2 != NULL && (Dict2->type == kTagTypeString) && Dict2->string) {
if (AsciiStrCmp (Dict2->string, "top") == 0) {
NewFilm->ScreenEdgeVertical = SCREEN_EDGE_TOP;
} else if (AsciiStrCmp (Dict2->string, "bottom") == 0) {
NewFilm->ScreenEdgeVertical = SCREEN_EDGE_BOTTOM;
}
}
//default values are centre
Dict2 = GetProperty (Dict3, "DistanceFromScreenEdgeX%");
NewFilm->FilmX = GetPropertyInteger (Dict2, INITVALUE);
Dict2 = GetProperty (Dict3, "DistanceFromScreenEdgeY%");
NewFilm->FilmY = GetPropertyInteger (Dict2, INITVALUE);
Dict2 = GetProperty (Dict3, "NudgeX");
NewFilm->NudgeX = GetPropertyInteger (Dict2, INITVALUE);
Dict2 = GetProperty (Dict3, "NudgeY");
NewFilm->NudgeY = GetPropertyInteger (Dict2, INITVALUE);
Dict2 = GetProperty (Dict3, "Once");
NewFilm->RunOnce = IsPropertyTrue (Dict2);
ThemeX.Cinema.AddFilm(NewFilm);
// delete NewFilm; //looks like already deleted
}
}
#else
Dict = GetProperty (DictPointer, "Anime"); Dict = GetProperty (DictPointer, "Anime");
if (Dict != NULL) { if (Dict != NULL) {
INTN i, Count = GetTagCount (Dict); INTN i, Count = GetTagCount (Dict);
@ -3823,7 +3897,7 @@ XTheme::GetThemeTagSettings (void* DictP)
} }
} }
} }
#endif
//not sure if it needed //not sure if it needed
if (BackgroundName.isEmpty()) { if (BackgroundName.isEmpty()) {
BackgroundName.takeValueFrom("background"); BackgroundName.takeValueFrom("background");
@ -3971,12 +4045,14 @@ InitTheme(BOOLEAN UseThemeDefinedInNVRam, EFI_TIME *Time)
Rnd = ((Time != NULL) && (ThemesNum != 0)) ? Time->Second % ThemesNum : 0; Rnd = ((Time != NULL) && (ThemesNum != 0)) ? Time->Second % ThemesNum : 0;
//TODO remake GuiAnime //TODO remake GuiAnime
#if !XCINEMA
while (GuiAnime != NULL) { while (GuiAnime != NULL) {
GUI_ANIME *NextAnime = GuiAnime->Next; GUI_ANIME *NextAnime = GuiAnime->Next;
// DBG("free anime %d\n", GuiAnime->ID); // DBG("free anime %d\n", GuiAnime->ID);
FreeAnime (GuiAnime); FreeAnime (GuiAnime);
GuiAnime = NextAnime; GuiAnime = NextAnime;
} }
#endif
// DBG("...done\n"); // DBG("...done\n");
ThemeX.GetThemeTagSettings(NULL); ThemeX.GetThemeTagSettings(NULL);

View File

@ -95,7 +95,8 @@ public:
EG_RECT FilmPlace; EG_RECT FilmPlace;
#if XCINEMA #if XCINEMA
FILM *FilmX; FILM *FilmC;
XImage FilmPlaceImage;
#else #else
EG_IMAGE **Film; EG_IMAGE **Film;
#endif #endif
@ -130,7 +131,7 @@ public:
AnimeRun(0), Once(0), LastDraw(0), CurrentFrame(0), AnimeRun(0), Once(0), LastDraw(0), CurrentFrame(0),
Frames(0), FrameTime(0), Frames(0), FrameTime(0),
#if XCINEMA #if XCINEMA
FilmX(), FilmC(), FilmPlaceImage(),
#else #else
Film(0), Film(0),
#endif #endif
@ -143,7 +144,7 @@ public:
AnimeRun(0), Once(0), LastDraw(0), CurrentFrame(0), AnimeRun(0), Once(0), LastDraw(0), CurrentFrame(0),
Frames(0), FrameTime(0), Frames(0), FrameTime(0),
#if XCINEMA #if XCINEMA
FilmX(), FilmC(), FilmPlaceImage(),
#else #else
Film(0), Film(0),
#endif #endif
@ -155,7 +156,7 @@ public:
Once(0), LastDraw(0), CurrentFrame(0), Once(0), LastDraw(0), CurrentFrame(0),
Frames(0), FrameTime(0), Frames(0), FrameTime(0),
#if XCINEMA #if XCINEMA
FilmX(), FilmC(), FilmPlaceImage(),
#else #else
Film(0), Film(0),
#endif #endif
@ -172,7 +173,7 @@ public:
AnimeRun(0), Once(0), LastDraw(0), CurrentFrame(0), AnimeRun(0), Once(0), LastDraw(0), CurrentFrame(0),
Frames(0), FrameTime(0), Frames(0), FrameTime(0),
#if XCINEMA #if XCINEMA
FilmX(), FilmC(), FilmPlaceImage(),
#else #else
Film(0), Film(0),
#endif #endif

View File

@ -53,13 +53,12 @@ extern BOOLEAN DayLight;
textFaces textFace[4]; //0-help 1-message 2-menu 3-test, far future it will be infinite list with id textFaces textFace[4]; //0-help 1-message 2-menu 3-test, far future it will be infinite list with id
NSVGparser *mainParser = NULL; //it must be global variable
EFI_STATUS XTheme::ParseSVGXIcon(void *parser, INTN Id, const XString& IconNameX, XImage* Image) EFI_STATUS XTheme::ParseSVGXIcon(INTN Id, const XString& IconNameX, XImage* Image)
{ {
EFI_STATUS Status = EFI_NOT_FOUND; EFI_STATUS Status = EFI_NOT_FOUND;
NSVGimage *SVGimage; NSVGimage *SVGimage;
NSVGparser *p = (NSVGparser *)parser; NSVGparser *p = (NSVGparser *)SVGParser;
NSVGrasterizer* rast = nsvgCreateRasterizer(); NSVGrasterizer* rast = nsvgCreateRasterizer();
SVGimage = p->image; SVGimage = p->image;
NSVGshape *shape; NSVGshape *shape;
@ -237,6 +236,7 @@ EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer)
{ {
EFI_STATUS Status; EFI_STATUS Status;
NSVGimage *SVGimage; NSVGimage *SVGimage;
NSVGparser *mainParser = (NSVGparser*)SVGParser;
Icons.Empty(); Icons.Empty();
@ -274,20 +274,20 @@ EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer)
} }
Status = EFI_NOT_FOUND; Status = EFI_NOT_FOUND;
if (!DayLight) { if (!DayLight) {
Status = ParseSVGXIcon(mainParser, BUILTIN_ICON_BACKGROUND, "Background_night"_XS, &BigBack); Status = ParseSVGXIcon(BUILTIN_ICON_BACKGROUND, "Background_night"_XS, &BigBack);
} }
if (EFI_ERROR(Status)) { if (EFI_ERROR(Status)) {
Status = ParseSVGXIcon(mainParser, BUILTIN_ICON_BACKGROUND, "Background"_XS, &BigBack); Status = ParseSVGXIcon(BUILTIN_ICON_BACKGROUND, "Background"_XS, &BigBack);
} }
DBG(" Background parsed [%lld, %lld]\n", BigBack.GetWidth(), BigBack.GetHeight()); //Background parsed [1067, 133] DBG(" Background parsed [%lld, %lld]\n", BigBack.GetWidth(), BigBack.GetHeight()); //Background parsed [1067, 133]
// --- Make Banner // --- Make Banner
Banner.setEmpty(); //for the case of theme switch Banner.setEmpty(); //for the case of theme switch
Status = EFI_NOT_FOUND; Status = EFI_NOT_FOUND;
if (!DayLight) { if (!DayLight) {
Status = ParseSVGXIcon(mainParser, BUILTIN_ICON_BANNER, "Banner_night"_XS, &Banner); Status = ParseSVGXIcon(BUILTIN_ICON_BANNER, "Banner_night"_XS, &Banner);
} }
if (EFI_ERROR(Status)) { if (EFI_ERROR(Status)) {
Status = ParseSVGXIcon(mainParser, BUILTIN_ICON_BANNER, "Banner"_XS, &Banner); Status = ParseSVGXIcon(BUILTIN_ICON_BANNER, "Banner"_XS, &Banner);
} }
DBG("Banner parsed\n"); DBG("Banner parsed\n");
BanHeight = (int)(Banner.GetHeight() * Scale + 1.f); BanHeight = (int)(Banner.GetHeight() * Scale + 1.f);
@ -300,14 +300,14 @@ EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer)
continue; continue;
} }
Icon* NewIcon = new Icon(i, false); //initialize without embedded Icon* NewIcon = new Icon(i, false); //initialize without embedded
Status = ParseSVGXIcon(mainParser, i, NewIcon->Name, &NewIcon->Image); Status = ParseSVGXIcon(i, NewIcon->Name, &NewIcon->Image);
if (EFI_ERROR(Status) && if (EFI_ERROR(Status) &&
(i >= BUILTIN_ICON_VOL_INTERNAL_HFS) && (i >= BUILTIN_ICON_VOL_INTERNAL_HFS) &&
(i <= BUILTIN_ICON_VOL_INTERNAL_REC)) { (i <= BUILTIN_ICON_VOL_INTERNAL_REC)) {
NewIcon->Image = GetIcon(BUILTIN_ICON_VOL_INTERNAL); //copy existing NewIcon->Image = GetIcon(BUILTIN_ICON_VOL_INTERNAL); //copy existing
} }
// DBG("parse %s status %s\n", NewIcon->Name.c_str(), strerror(Status)); // DBG("parse %s status %s\n", NewIcon->Name.c_str(), strerror(Status));
Status = ParseSVGXIcon(mainParser, i, NewIcon->Name + "_night"_XS, &NewIcon->ImageNight); Status = ParseSVGXIcon(i, NewIcon->Name + "_night"_XS, &NewIcon->ImageNight);
// DBG("...night status %s\n", strerror(Status)); // DBG("...night status %s\n", strerror(Status));
if (EFI_ERROR(Status) && if (EFI_ERROR(Status) &&
(i >= BUILTIN_ICON_VOL_INTERNAL_HFS) && (i >= BUILTIN_ICON_VOL_INTERNAL_HFS) &&
@ -329,10 +329,10 @@ EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer)
//selection for bootcamp style //selection for bootcamp style
Status = EFI_NOT_FOUND; Status = EFI_NOT_FOUND;
if (!DayLight) { if (!DayLight) {
Status = ParseSVGXIcon(mainParser, BUILTIN_ICON_SELECTION, "selection_indicator_night"_XS, &SelectionImages[4]); Status = ParseSVGXIcon(BUILTIN_ICON_SELECTION, "selection_indicator_night"_XS, &SelectionImages[4]);
} }
if (EFI_ERROR(Status)) { if (EFI_ERROR(Status)) {
Status = ParseSVGXIcon(mainParser, BUILTIN_ICON_SELECTION, "selection_indicator"_XS, &SelectionImages[4]); Status = ParseSVGXIcon(BUILTIN_ICON_SELECTION, "selection_indicator"_XS, &SelectionImages[4]);
} }
//buttons //buttons
@ -343,6 +343,9 @@ EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer)
//SelectionImages[i].Draw(i*100, 0); //SelectionImages[i].Draw(i*100, 0);
//} //}
#if XCINEMA
//nothing to do?
#else
//banner animation //banner animation
GUI_ANIME *Anime = (__typeof__(Anime))AllocateZeroPool (sizeof(GUI_ANIME)); GUI_ANIME *Anime = (__typeof__(Anime))AllocateZeroPool (sizeof(GUI_ANIME));
Anime->ID = 1; //main screen Anime->ID = 1; //main screen
@ -355,7 +358,7 @@ EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer)
Anime->NudgeX = INITVALUE; Anime->NudgeX = INITVALUE;
Anime->NudgeY = INITVALUE; Anime->NudgeY = INITVALUE;
GuiAnime = Anime; GuiAnime = Anime;
#endif
// nsvgDeleteRasterizer(rast); // nsvgDeleteRasterizer(rast);
TypeSVG = TRUE; TypeSVG = TRUE;
@ -371,10 +374,26 @@ EFI_STATUS XTheme::ParseSVGXTheme(CONST CHAR8* buffer)
return Status; return Status;
} }
#if XCINEMA
EFI_STATUS XTheme::LoadSvgFrame(INTN i, OUT XImage* XFrame)
{
EFI_STATUS Status = EFI_NOT_FOUND;
XString XFrameName("frame_"_XS);
XFrameName += SPrintf("%04lld", i+1);
Status = ParseSVGXIcon(BUILTIN_ICON_ANIME, XFrameName, XFrame);
if (EFI_ERROR(Status)) {
DBG("frame '%s' not loaded, status=%s\n", XFrameName.c_str(), strerror(Status));
}
return Status;
}
#else
EG_IMAGE * LoadSvgFrame(INTN i) EG_IMAGE * LoadSvgFrame(INTN i)
{ {
// EG_IMAGE *Frame = NULL; // EG_IMAGE *Frame = NULL;
XImage XFrame; XImage XFrame;
// NSVGparser *mainParser = (NSVGparser*)ThemeX.SVGParser;
EFI_STATUS Status; EFI_STATUS Status;
// CHAR8 FrameName[64]; // CHAR8 FrameName[64];
XString XFrameName("frame_"_XS); XString XFrameName("frame_"_XS);
@ -383,13 +402,13 @@ EG_IMAGE * LoadSvgFrame(INTN i)
XFrameName += SPrintf("%04lld", i+1); //I need exactly 4 symbols with leading zero XFrameName += SPrintf("%04lld", i+1); //I need exactly 4 symbols with leading zero
// printf(FrameName, 63, "frame_%lld", i+1); // printf(FrameName, 63, "frame_%lld", i+1);
Status = ThemeX.ParseSVGXIcon(mainParser, BUILTIN_ICON_ANIME, XFrameName, &XFrame); Status = ThemeX.ParseSVGXIcon(BUILTIN_ICON_ANIME, XFrameName, &XFrame);
if (EFI_ERROR(Status)) { if (EFI_ERROR(Status)) {
DBG("icon '%s' not loaded, status=%s\n", XFrameName.c_str(), strerror(Status)); DBG("icon '%s' not loaded, status=%s\n", XFrameName.c_str(), strerror(Status));
} }
return XFrame.ToEGImage(); return XFrame.ToEGImage();
} }
#endif
// it is not draw, it is render and mainly used in egRenderText // it is not draw, it is render and mainly used in egRenderText
// which is used in icns.cpp as an icon replacement if no image found, looks like not used // which is used in icns.cpp as an icon replacement if no image found, looks like not used
// in menu.cpp 3 places // in menu.cpp 3 places

View File

@ -29,22 +29,22 @@
VOID REFIT_MENU_SCREEN::UpdateFilm() VOID REFIT_MENU_SCREEN::UpdateFilm()
{ {
// here we propose each screen has own link to a Film // here we propose each screen has own link to a Film
UINT64 Now = AsmReadTsc(); INT64 Now = AsmReadTsc();
if (LastDraw == 0) { if (LastDraw == 0) {
//save background into last frame //save background into special place
FilmPlaceImage.GetArea(FilmC->FilmPlace);
} }
if (TimeDiff(LastDraw, Now) < FrameTime) return; if (TimeDiff(LastDraw, Now) < (UINTN)FilmC->FrameTime) return;
XImage *Frame = nullptr; // a link to frame needed
// EFI_STATUS Status = ThemeX.Cinema.GetFrame(CurrentFrame); XImage Frame = FilmC->GetImage(); //take current image
EFI_STATUS Status = FilmX->GetFrame(CurrentFrame, Frame); //get a pointer to existing frame if (!Frame.isEmpty()) {
if (!EFI_ERROR(Status) && Frame != nullptr) { Frame.DrawOnBack(FilmC->FilmPlace.XPos, FilmC->FilmPlace.YPos, FilmPlaceImage);
Frame->Draw(FilmPlace.XPos, FilmPlace.YPos);
} }
FilmX->Advance(CurrentFrame); //next frame no matter if previous was not found FilmC->Advance(); //next frame no matter if previous was not found
if (CurrentFrame == 0) { //first loop finished if (FilmC->Finished()) { //first loop finished
AnimeRun = !Once; //will stop anime AnimeRun = !FilmC->RunOnce; //will stop anime if it set as RunOnce
} }
LastDraw = Now; LastDraw = Now;
} }
@ -59,13 +59,60 @@ FILM* XCinema::GetFilm(INTN Id)
return nullptr; return nullptr;
} }
EFI_STATUS FILM::GetFrame(IN INTN Index, OUT XImage *Image) void XCinema::AddFilm(FILM* NewFilm)
{
Cinema.AddReference(NewFilm, true);
}
static XImage NullImage;
const XImage& FILM::GetImage(INTN Index) const
{ {
for (size_t i = 0; i < Frames.size(); ++i) { for (size_t i = 0; i < Frames.size(); ++i) {
if (Frames[i].Index == Index) { if (Frames[i].Id == Index) {
Image = &Frames[i].Image; return Frames[i].getImage();
return EFI_SUCCESS; }
}
return NullImage;
}
const XImage& FILM::GetImage() const
{
for (size_t i = 0; i < Frames.size(); ++i) {
if (Frames[i].Id == CurrentFrame) {
return Frames[i].getImage();
}
}
return NullImage;
}
void FILM::AddFrame(XImage* Frame, INTN Index)
{
IndexedImage* NewFrame = new IndexedImage(Index);
NewFrame->setImage(*Frame);
Frames.AddReference(NewFrame, true);
if (Index > LastIndex) {
LastIndex = Index;
}
}
void FILM::GetFrames(XTheme& TheTheme, const XStringW& Path)
{
EFI_FILE *ThemeDir = TheTheme.ThemeDir;
EFI_STATUS Status;
for (INTN Index = 0; Index < NumFrames; Index++) {
XImage NewImage;
Status = EFI_NOT_FOUND;
if (TheTheme.TypeSVG) {
Status = TheTheme.LoadSvgFrame(Index, &NewImage);
} else {
XStringW Name = SWPrintf("%ls\\%ls_%03lld.png", Path.wc_str(), Path.wc_str(), Index);
if (FileExists(ThemeDir, Name.wc_str())) {
Status = NewImage.LoadXImage(ThemeDir, Name);
}
}
if (!EFI_ERROR(Status)) {
AddFrame(&NewImage, Index);
} }
} }
return EFI_NOT_FOUND;
} }

View File

@ -17,42 +17,50 @@ extern "C" {
#include "../cpp_foundation/XStringW.h" #include "../cpp_foundation/XStringW.h"
#include "../libeg/libeg.h" #include "../libeg/libeg.h"
#include "XImage.h" #include "XImage.h"
#include "XTheme.h"
typedef struct FRAME { class XTheme;
INTN Index;
XImage Image;
} FRAME;
class FILM class FILM
{ {
public: public:
bool RunOnce; //I see no reason to make they protected
INTN Id; //ScreenID, enumeration value but keep it to be int for extensibility bool RunOnce;
protected: INTN Id; //ScreenID, enumeration value but keep it to be int for extensibility
INTN NumFrames; //set by user in Theme.plist or in Theme.svg
INTN FrameTime; //usually 50, 100, 200 ms
INTN FilmX, FilmY; //relative
INTN ScreenEdgeHorizontal;
INTN ScreenEdgeVertical;
INTN NudgeX, NudgeY;
XStringW Path; //user defined name for folder and files Path/Path_002.png etc
INTN FrameTime; //usually 50, 100, 200 ms protected:
XString Path; //user defined name for folder and files Path/Path_002.png etc XObjArray<IndexedImage> Frames; //Frames can be not sorted
XObjArray<FRAME> Frames; //Frames can be not sorted
INTN LastIndex; // it is not Frames.size(), it is last index inclusive, so frames 0,1,2,5,8 be LastIndex = 8 INTN LastIndex; // it is not Frames.size(), it is last index inclusive, so frames 0,1,2,5,8 be LastIndex = 8
EG_RECT FilmPlace; INTN CurrentFrame; // must be unique for each film
// INTN CurrentFrame; // like a static value will be increased between 0..LastIndex, no it's a part of Screen
public: public:
FILM(): RunOnce(false), Id(0), FrameTime(0), Path(), Frames(), LastIndex(0), FilmPlace() EG_RECT FilmPlace; // Screen has several Films each in own place
{}
FILM(INTN Id) : RunOnce(false), Id(Id), FrameTime(0), Path(), Frames(), public:
LastIndex(0), FilmPlace() {} FILM() {}
FILM(INTN Id) : RunOnce(false), Id(Id)
{}
~FILM() {} ~FILM() {}
const XImage& GetImage(INTN Index); const XImage& GetImage(INTN Index) const;
void AddFrame(const FRAME& Frame, INTN Index); const XImage& GetImage() const;
void AddFrame(XImage* Frame, INTN Index); //IndexedImage will be created
size_t Size() { return Frames.size(); } size_t Size() { return Frames.size(); }
INTN LastFrame() { return LastIndex; } INTN LastFrameID() { return LastIndex; }
void GetFilm(const XStringW& Path); //read from Theme bool Finished() { return CurrentFrame == 0; }
void SetPlace(const EG_RECT& Rect); void GetFrames(XTheme& TheTheme, const XStringW& Path); //read image sequence from Theme/Path/
void Advance(INTN& Current) { ++Current %= (LastIndex + 1); } void SetPlace(const EG_RECT& Rect) { FilmPlace = Rect; }
EFI_STATUS GetFrame(IN INTN Index, OUT XImage *Frame); //usually Index=CurrentFrame void Advance() { ++CurrentFrame %= (LastIndex + 1); }
EFI_STATUS GetFrame(OUT XImage *Frame); void Reset() { CurrentFrame = 0; }
// EFI_STATUS GetFrame(IN INTN Index, OUT XImage *Frame); //usually Index=CurrentFrame
// EFI_STATUS GetFrame(OUT XImage *Frame);
}; };
@ -62,6 +70,7 @@ public:
// then it should contain Screen->ID for each film // then it should contain Screen->ID for each film
// but for next future we want to have other animated images in addition to screen->titleimage // but for next future we want to have other animated images in addition to screen->titleimage
// so let it be frames arrays each with own purpose (Id) // so let it be frames arrays each with own purpose (Id)
//
// XTheme contains Cinema which is an array of FILMs // XTheme contains Cinema which is an array of FILMs
// Each Screen contains a pointer to a FILM. And moreover titleFilm, or BackgroundFilm or even entryFilm // Each Screen contains a pointer to a FILM. And moreover titleFilm, or BackgroundFilm or even entryFilm
// Next problem is a timeout between frames. // Next problem is a timeout between frames.
@ -70,7 +79,7 @@ public:
// if yes then update. Static index? // if yes then update. Static index?
// //
// in the far future I'll plan to make dynamic SVG: parse SVGIcon with a variable argument // in the far future I'll plan to make dynamic SVG: parse SVGIcon with a variable argument
// and then rasterize it. Real SVG contains constants only so it will be dynamicSVG. // and then rasterize it. Real SVG contains constants only so it will be new dynamicSVG.
// then Entry->Image should be reparsed each time it created or contains flag to update every frameTime // then Entry->Image should be reparsed each time it created or contains flag to update every frameTime
class XCinema class XCinema
@ -78,14 +87,12 @@ class XCinema
protected: protected:
XObjArray<FILM> Cinema; XObjArray<FILM> Cinema;
public: public:
XCinema() {} XCinema() {}
~XCinema() {} ~XCinema() {}
FILM* GetFilm(INTN Id); FILM* GetFilm(INTN Id);
void AddFilm(const FILM& NewFilm, INTN Id); void AddFilm(FILM* NewFilm);
}; };

View File

@ -55,7 +55,7 @@ public:
XImage(UINTN W, UINTN H); XImage(UINTN W, UINTN H);
XImage(EG_IMAGE* egImage); XImage(EG_IMAGE* egImage);
XImage(const XImage& Image, float scale = 0.f); //the constructor can accept 0 scale as 1.f XImage(const XImage& Image, float scale = 0.f); //the constructor can accept 0 scale as 1.f
~XImage(); virtual ~XImage();
XImage& operator= (const XImage& other); XImage& operator= (const XImage& other);
@ -116,4 +116,22 @@ protected:
UINT8 Smooth(const UINT8* p, int a01, int a10, int a21, int a12, float dx, float dy, float scale); UINT8 Smooth(const UINT8* p, int a01, int a10, int a21, int a12, float dx, float dy, float scale);
}; };
class IndexedImage
{
public:
INTN Id;
protected:
XImage Image;
public:
INTN getIndex() { return Id; }
void setIndex(INTN Index) { Id = Index; }
const XImage& getImage() const { return Image; }
void setImage(const XImage& Sample) { Image = Sample; }
IndexedImage() : Id(0), Image() {}
IndexedImage(INTN ID) : Id(ID), Image() {}
~IndexedImage() {}
};
#endif //__XSTRINGW_H__ #endif //__XSTRINGW_H__

View File

@ -238,7 +238,7 @@ void XTheme::Init()
BadgeScale = 4; // TODO now we have float scale = BadgeScale/16 BadgeScale = 4; // TODO now we have float scale = BadgeScale/16
ThemeDesignWidth = 0xFFFF; ThemeDesignWidth = 0xFFFF;
ThemeDesignHeight = 0xFFFF; ThemeDesignHeight = 0xFFFF;
BannerPosX = 0xFFFF; // the value out of range [0,1000] BannerPosX = 0xFFFF; // the value out of range [0,1000] means default
BannerPosY = 0xFFFF; BannerPosY = 0xFFFF;
BannerEdgeHorizontal = 0; BannerEdgeHorizontal = 0;
BannerEdgeVertical = 0; BannerEdgeVertical = 0;
@ -580,14 +580,7 @@ void XTheme::ClearScreen() //and restore background and banner
if (!Banner.isEmpty()) { if (!Banner.isEmpty()) {
Background.Compose(BannerPlace.XPos, BannerPlace.YPos, Banner, true); Background.Compose(BannerPlace.XPos, BannerPlace.YPos, Banner, true);
} }
Background.DrawWithoutCompose(0, 0, UGAWidth, UGAHeight); Background.DrawWithoutCompose(0, 0, UGAWidth, UGAHeight);
// Background.Draw(0,0,0,true);
//then draw banner
// if (!Banner.isEmpty()) {
// Banner.Draw(BannerPlace.XPos, BannerPlace.YPos, Scale);
// }
} }
#if 0 #if 0

View File

@ -122,7 +122,7 @@ public:
#if XCINEMA #if XCINEMA
XCinema Cinema; XCinema Cinema;
#endif #endif
void *SVGParser;
//fill the theme //fill the theme
// const XImage& GetIcon(const char* Name); // const XImage& GetIcon(const char* Name);
// const XImage& GetIcon(const CHAR16* Name); // const XImage& GetIcon(const CHAR16* Name);
@ -150,8 +150,9 @@ public:
EFI_STATUS GetThemeTagSettings(void* DictPointer); EFI_STATUS GetThemeTagSettings(void* DictPointer);
void parseTheme(void* p, const char** dict); //in nano project void parseTheme(void* p, const char** dict); //in nano project
EFI_STATUS ParseSVGXTheme(const CHAR8* buffer); // in VectorTheme EFI_STATUS ParseSVGXTheme(const CHAR8* buffer); // in VectorTheme
EFI_STATUS ParseSVGXIcon(void *p, INTN Id, const XString& IconNameX, XImage* Image); EFI_STATUS ParseSVGXIcon(INTN Id, const XString& IconNameX, XImage* Image);
void* LoadTheme(const CHAR16 *TestTheme); //return TagPtr why? void* LoadTheme(const CHAR16 *TestTheme); //return TagPtr why?
EFI_STATUS LoadSvgFrame(INTN i, OUT XImage* XFrame); // for animation
//screen operations //screen operations
void ClearScreen(); void ClearScreen();

View File

@ -572,6 +572,6 @@ struct NSVGrasterizer
}; };
extern NSVGfontChain *fontsDB; extern NSVGfontChain *fontsDB;
extern struct NSVGparser *mainParser; //extern struct NSVGparser *mainParser;
#endif #endif

View File

@ -350,7 +350,10 @@ extern CHAR16 *OEMPath;
extern EFI_FILE *OemThemeDir; extern EFI_FILE *OemThemeDir;
//extern BOOLEAN MainAnime; //extern BOOLEAN MainAnime;
#if XCINEMA
#else
extern GUI_ANIME *GuiAnime; extern GUI_ANIME *GuiAnime;
#endif
extern REFIT_VOLUME *SelfVolume; extern REFIT_VOLUME *SelfVolume;
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -481,13 +481,49 @@ INTN HybridRepositioning(INTN Edge, INTN Value, INTN ImageDimension, INTN Screen
#if XCINEMA #if XCINEMA
BOOLEAN REFIT_MENU_SCREEN::GetAnime() BOOLEAN REFIT_MENU_SCREEN::GetAnime()
{ {
FilmX = ThemeX.Cinema.GetFilm(ID); FilmC = ThemeX.Cinema.GetFilm(ID);
return FilmX != nullptr; return FilmC != nullptr;
} }
VOID REFIT_MENU_SCREEN::InitAnime() VOID REFIT_MENU_SCREEN::InitAnime()
{ {
//something if (FilmC && (FilmC->FilmX >=0) && (FilmC->FilmX <=100) &&
(FilmC->FilmY >=0) && (FilmC->FilmY <=100)) {
// Check if screen size being used is different from theme origination size.
// If yes, then recalculate the animation placement % value.
// This is necessary because screen can be a different size, but anim is not scaled.
XImage FirstFrame = FilmC->GetImage(FilmC->LastFrameID()); //can not be absent
INTN CWidth = FirstFrame.GetWidth();
INTN CHeight = FirstFrame.GetHeight();
FilmC->FilmPlace.XPos = HybridRepositioning(FilmC->ScreenEdgeHorizontal, FilmC->FilmX, CWidth, UGAWidth, ThemeX.ThemeDesignWidth );
FilmC->FilmPlace.YPos = HybridRepositioning(FilmC->ScreenEdgeVertical, FilmC->FilmY, CHeight, UGAHeight, ThemeX.ThemeDesignHeight);
// Does the user want to fine tune the placement?
FilmC->FilmPlace.XPos = CalculateNudgePosition(FilmC->FilmPlace.XPos, FilmC->NudgeX, CWidth, UGAWidth);
FilmC->FilmPlace.YPos = CalculateNudgePosition(FilmC->FilmPlace.YPos, FilmC->NudgeY, CHeight, UGAHeight);
FilmC->FilmPlace.Width = CWidth;
FilmC->FilmPlace.Height = CHeight;
DBG("recalculated Film position [%lld, %lld]\n", FilmC->FilmPlace.XPos, FilmC->FilmPlace.YPos);
} else {
// We are here if there is no anime, or if we use oldstyle placement values
// For both these cases, FilmPlace will be set after banner/menutitle positions are known
FilmPlace.XPos = 0;
FilmPlace.YPos = 0;
FilmPlace.Width = 0;
FilmPlace.Height = 0;
}
if (FilmC != NULL && FilmC->NumFrames != 0) {
DBG(" Anime seems OK, init it\n");
AnimeRun = TRUE;
FilmC->Reset();
LastDraw = 0;
} else {
// DBG("not run anime\n");
AnimeRun = FALSE;
}
} }
#else #else