correct font handling

Signed-off-by: SergeySlice <sergey.slice@gmail.com>
This commit is contained in:
SergeySlice 2020-03-29 10:14:14 +03:00
parent e59f205afc
commit 38319f70bc
4 changed files with 82 additions and 112 deletions

View File

@ -48,22 +48,25 @@ extern VOID
WaitForKeyPress(CHAR16 *Message);
extern void DumpFloat2 (CONST char* s, float* t, int N);
#if !USE_XTHEME
extern EG_IMAGE *BackgroundImage;
extern EG_IMAGE *Banner;
extern EG_IMAGE *BigBack;
extern INTN BanHeight;
extern INTN row0TileSize;
extern INTN row1TileSize;
extern INTN FontWidth;
//extern INTN FontWidth;
#endif
extern UINTN NumFrames;
extern UINTN FrameTime;
extern BOOLEAN DayLight;
textFaces textFace[4]; //0-help 1-message 2-menu 3-test
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
#if USE_XTHEME
EFI_STATUS ParseSVGXIcon(NSVGparser *p, INTN Id, CONST CHAR8 *IconName, float Scale, OUT XImage& Image)
EFI_STATUS ParseSVGXIcon(NSVGparser *p, INTN Id, XString& IconNameX, float Scale, OUT XImage& Image)
{
EFI_STATUS Status = EFI_NOT_FOUND;
NSVGimage *SVGimage;
@ -73,6 +76,7 @@ EFI_STATUS ParseSVGXIcon(NSVGparser *p, INTN Id, CONST CHAR8 *IconName, float S
NSVGgroup *group;
NSVGimage *IconImage;
NSVGshape *shapeNext, *shapesTail = NULL, *shapePrev;
CONST CHAR8 *IconName = IconNameX.c_str();
NSVGparser* p2 = nsvg__createParser();
IconImage = p2->image;
@ -719,102 +723,6 @@ EG_IMAGE * LoadSvgFrame(INTN i)
return Frame;
}
#if 0
VOID RenderSVGfont(NSVGfont *fontSVG, UINT32 color)
{
// EFI_STATUS Status;
float FontScale;
NSVGparser *p;
NSVGrasterizer *rast;
INTN i;
if (!fontSVG) {
return;
}
//free old font
if (FontImage != NULL) {
egFreeImage (FontImage);
FontImage = NULL;
}
INTN Height = FontHeight + 4;
// DBG("load font %s\n", fontSVG->fontFamily);
if (fontSVG->unitsPerEm < 1.f) {
fontSVG->unitsPerEm = 1000.f;
}
float fH = fontSVG->bbox[3] - fontSVG->bbox[1];
if (fH == 0.f) {
fH = fontSVG->unitsPerEm;
}
FontScale = (float)FontHeight / fH;
DBG("font scale %ls\n", FontScale);
FontWidth = (int)(fontSVG->horizAdvX * FontScale);
INTN Width = FontWidth * (AsciiPageSize + GlobalConfig.CodepageSize);
FontImage = egCreateImage(Width, Height, TRUE);
p = nsvg__createParser();
if (!p) {
return;
}
// p->font = fontSVG;
p->image->height = (float)Height;
p->image->width = (float)Width;
NSVGtext* text = (NSVGtext*)AllocateZeroPool(sizeof(NSVGtext));
if (!text) {
return;
}
text->fontSize = (float)FontHeight;
text->font = fontSVG;
text->fontColor = color;
// DBG("RenderSVGfont: fontID=%s\n", text->font->id);
// DBG("RenderSVGfont: family=%s\n", text->font->fontFamily);
//add to head
text->next = p->text;
p->text = text;
//for each letter rasterize glyph into FontImage
//0..0xC0 == AsciiPageSize
// cyrillic 0x410..0x450 at 0xC0
float x = 0.f;
float y = fontSVG->bbox[1] * FontScale;; //(float)Height;
p->isText = TRUE;
for (i = 0; i < AsciiPageSize; i++) {
addLetter(p, i, x, y, FontScale, color);
x += (float)FontWidth;
}
x = AsciiPageSize * FontWidth;
for (i = GlobalConfig.Codepage; i < GlobalConfig.Codepage+GlobalConfig.CodepageSize; i++) {
addLetter(p, i, x, y, FontScale, color);
x += (float)FontWidth;
}
p->image->realBounds[0] = fontSVG->bbox[0] * FontScale;
p->image->realBounds[1] = fontSVG->bbox[1] * FontScale;
p->image->realBounds[2] = fontSVG->bbox[2] * FontScale + x; //last bound
p->image->realBounds[3] = fontSVG->bbox[3] * FontScale;
//We made an image, then rasterize it
rast = nsvgCreateRasterizer();
nsvgRasterize(rast, p->image, 0, 0, 1.0f, 1.0f, (UINT8*)FontImage->PixelData, (int)Width, (int)Height, (int)(Width*4));
#if 0 //DEBUG_FONT
//save font as png yyyyy
UINT8 *FileData = NULL;
UINTN FileDataLength = 0U;
EFI_UGA_PIXEL *ImagePNG = (EFI_UGA_PIXEL *)FontImage->PixelData;
unsigned lode_return =
eglodepng_encode(&FileData, &FileDataLength, (CONST UINT8*)ImagePNG, (UINTN)FontImage->Width, (UINTN)FontImage->Height);
if (!lode_return) {
egSaveFile(SelfRootDir, L"\\FontSVG.png", FileData, FileDataLength);
}
#endif
nsvgDeleteRasterizer(rast);
// nsvg__deleteParser(p);
return;
}
#endif
// it is not draw, it is render and mainly used in egRenderText
// which is used in icns.cpp as an icon rplacement if no image found, looks like not used
// in menu.cpp 3 places

View File

@ -37,7 +37,7 @@
#ifndef __LIBEG_LIBEG_H__
#define __LIBEG_LIBEG_H__
#define USE_XTHEME 0
#define USE_XTHEME 1
#ifdef __cplusplus
extern "C" {

View File

@ -56,7 +56,7 @@
EG_IMAGE *FontImage = NULL;
INTN FontWidth = 9;
INTN FontWidth = 9; //local variable
INTN FontHeight = 18;
INTN TextHeight = 19;
NSVGfontChain *fontsDB = NULL;
@ -89,6 +89,7 @@ VOID egMeasureText(IN CONST CHAR16 *Text, OUT INTN *Width, OUT INTN *Height)
}
#endif
//should be rewritten to use XImage and XStringW
EG_IMAGE * egLoadFontImage(IN BOOLEAN UseEmbedded, IN INTN Rows, IN INTN Cols)
{
EG_IMAGE *NewImage = NULL, *NewFontImage;
@ -96,12 +97,21 @@ EG_IMAGE * egLoadFontImage(IN BOOLEAN UseEmbedded, IN INTN Rows, IN INTN Cols)
EG_PIXEL *PixelPtr, FirstPixel;
BOOLEAN isKorean = (gLanguage == korean);
CHAR16 *fontFilePath = NULL;
CONST CHAR16 *commonFontDir = L"EFI\\CLOVER\\font";
CONST CHAR16 *commonFontDir = L"EFI\\CLOVER\\font";
if (IsEmbeddedTheme() && !isKorean) { //or initial screen before theme init
NewImage = egDecodePNG(ACCESS_EMB_DATA(emb_font_data), ACCESS_EMB_SIZE(emb_font_data), TRUE);
MsgLog("Using embedded font: %s\n", NewImage ? "Success" : "Error");
} else {
#if USE_XTHEME
if (!ThemeX.TypeSVG) {
NewImage = egLoadImage(ThemeDir, isKorean ? L"FontKorean.png" : ThemeX.FontFileName.data(), TRUE);
MsgLog("Loading font from ThemeDir: %s\n", NewImage ? "Success" : "Error");
} else {
MsgLog("Using SVG font\n");
return FontImage;
}
#else
if (!GlobalConfig.TypeSVG) {
NewImage = egLoadImage(ThemeDir, isKorean ? L"FontKorean.png" : GlobalConfig.FontFileName, TRUE);
MsgLog("Loading font from ThemeDir: %s\n", NewImage ? "Success" : "Error");
@ -109,11 +119,17 @@ EG_IMAGE * egLoadFontImage(IN BOOLEAN UseEmbedded, IN INTN Rows, IN INTN Cols)
MsgLog("Using SVG font\n");
return FontImage;
}
#endif
}
if (!NewImage) {
//then take from common font folder
#if USE_XTHEME
fontFilePath = PoolPrint(L"%s\\%s", commonFontDir, isKorean ? L"FontKorean.png" : ThemeX.FontFileName.data());
#else
fontFilePath = PoolPrint(L"%s\\%s", commonFontDir, isKorean ? L"FontKorean.png" : GlobalConfig.FontFileName);
#endif
NewImage = egLoadImage(SelfRootDir, fontFilePath, TRUE);
//else use embedded
if (!NewImage) {
@ -145,7 +161,12 @@ EG_IMAGE * egLoadFontImage(IN BOOLEAN UseEmbedded, IN INTN Rows, IN INTN Cols)
FontWidth = ImageWidth / Cols;
FontHeight = ImageHeight / Rows;
#if USE_XTHEME
TextHeight = FontHeight + (int)(TEXT_YMARGIN * 2 * ThemeX.Scale);
#else
TextHeight = FontHeight + (int)(TEXT_YMARGIN * 2 * GlobalConfig.Scale);
#endif
FirstPixel = *PixelPtr;
for (y = 0; y < Rows; y++) {
for (j = 0; j < FontHeight; j++) {
@ -158,8 +179,13 @@ EG_IMAGE * egLoadFontImage(IN BOOLEAN UseEmbedded, IN INTN Rows, IN INTN Cols)
(PixelPtr->r == FirstPixel.r)
) {
PixelPtr->a = 0;
#if USE_XTHEME
} else if (ThemeX.DarkEmbedded) {
*PixelPtr = SemiWhitePixel;
#else
} else if (GlobalConfig.DarkEmbedded) {
*PixelPtr = SemiWhitePixel;
#endif
}
NewFontImage->PixelData[Ypos + x] = *PixelPtr++;
}
@ -175,12 +201,18 @@ VOID PrepareFont()
{
EG_PIXEL *p;
INTN Width, Height;
TextHeight = FontHeight + (int)(TEXT_YMARGIN * 2 * GlobalConfig.Scale);
if (GlobalConfig.TypeSVG) {
// FontImage = RenderSVGfont();
#if USE_XTHEME
TextHeight = FontHeight + (int)(TEXT_YMARGIN * 2 * ThemeX.Scale);
if (ThemeX.TypeSVG) {
return;
}
#else
TextHeight = FontHeight + (int)(TEXT_YMARGIN * 2 * GlobalConfig.Scale);
if (GlobalConfig.TypeSVG) {
// FontImage = RenderSVGfont();
return;
}
#endif
if (FontImage) {
egFreeImage(FontImage);
@ -190,10 +222,12 @@ VOID PrepareFont()
if (gLanguage == korean) {
FontImage = egLoadFontImage(FALSE, 10, 28);
if (FontImage) {
// FontHeight = 16; //delete?
#if USE_XTHEME
ThemeX.CharWidth = 22;
#else
GlobalConfig.CharWidth = 22;
// FontWidth = GlobalConfig.CharWidth; //delete?
// TextHeight = FontHeight + TEXT_YMARGIN * 2;
#endif
MsgLog("Using Korean font matrix\n");
return;
} else {
@ -209,6 +243,20 @@ VOID PrepareFont()
}
if (FontImage) {
#if USE_XTHEME
if (ThemeX.Font == FONT_GRAY) {
//invert the font. embedded is dark
p = FontImage->PixelData;
for (Height = 0; Height < FontImage->Height; Height++){
for (Width = 0; Width < FontImage->Width; Width++, p++){
p->b ^= 0xFF;
p->g ^= 0xFF;
p->r ^= 0xFF;
//p->a = 0xFF; //huh!
}
}
}
#else
if (GlobalConfig.Font == FONT_GRAY) {
//invert the font. embedded is dark
p = FontImage->PixelData;
@ -221,6 +269,7 @@ VOID PrepareFont()
}
}
}
#endif
// TextHeight = FontHeight + TEXT_YMARGIN * 2;
DBG("Font %d prepared WxH=%lldx%lld CharWidth=%lld\n", GlobalConfig.Font, FontWidth, FontHeight, GlobalConfig.CharWidth);
@ -297,7 +346,12 @@ INTN egRenderText(IN CONST CHAR16 *Text, IN OUT EG_IMAGE *CompImage,
// clip the text
#if USE_XTHEME
TextLength = Text.size();
#else
TextLength = StrLen(Text);
#endif
if (!FontImage) {
// GlobalConfig.Font = FONT_ALFA;
PrepareFont();
@ -332,10 +386,17 @@ INTN egRenderText(IN CONST CHAR16 *Text, IN OUT EG_IMAGE *CompImage,
c = Text[i];
#endif
if (gLanguage != korean) {
c1 = (((c >= GlobalConfig.Codepage) ? (c - (GlobalConfig.Codepage - AsciiPageSize)) : c) & 0xff); //International letters
#if USE_XTHEME
c1 = (((c >= ThemeX.Codepage) ? (c - (ThemeX.Codepage - AsciiPageSize)) : c) & 0xff); //International letters
c = c1;
if (ThemeX.Proportional) {
#else
c1 = (((c >= GlobalConfig.Codepage) ? (c - (GlobalConfig.Codepage - AsciiPageSize)) : c) & 0xff); //International letters
c = c1;
if (GlobalConfig.Proportional) {
#endif
if (c0 <= 0x20) { // space before or at buffer edge
LeftSpace = 2;
} else {

View File

@ -504,8 +504,9 @@ EFI_STATUS InitializeUnicodeCollationProtocol (VOID);
#define LAYOUT_X_EDGE (20)
#define BAR_WIDTH (16)
extern INTN FontWidth;
extern INTN FontHeight;
// local variables
//extern INTN FontWidth;
//extern INTN FontHeight;
extern INTN TextHeight;
extern INTN row0TileSize;
extern INTN row1TileSize;