Add support for TrueType fonts

* Keeps original font system in place
* Uses the same API as original font system:
   - You can render only one line at a time
   - You can only use one font and color for one gr_text* call
* Caches all rendered text, with a string cache limited to 400
  entries, then it trucates to 250, which results in memory
  usage hovering around 5-10MB

Change-Id: I36107b9dcd8d57bae4486fce8b8f64e49ef3d906
Signed-off-by: Vojtech Bocek <vbocek@gmail.com>
This commit is contained in:
Vojtech Bocek
2014-09-07 15:01:56 +02:00
committed by Dees Troy
parent b4bd697f27
commit 76ee903d84
35 changed files with 938 additions and 122 deletions
+11
View File
@@ -59,6 +59,9 @@ endif
ifeq ($(TW_OEM_BUILD), true)
LOCAL_CFLAGS += -DTW_OEM_BUILD
endif
ifeq ($(TW_DISABLE_TTF), true)
LOCAL_CFLAGS += -DTW_DISABLE_TTF
endif
ifeq ($(DEVICE_RESOLUTION),)
$(warning ********************************************************************************)
@@ -104,6 +107,13 @@ ifeq ($(TW_CUSTOM_THEME),)
else
TWRP_THEME_LOC := $(TW_CUSTOM_THEME)
endif
ifeq ($(TW_DISABLE_TTF), true)
TWRP_REMOVE_FONT := rm -f $(TARGET_RECOVERY_ROOT_OUT)/res/fonts/*.ttf
else
TWRP_REMOVE_FONT := rm -f $(TARGET_RECOVERY_ROOT_OUT)/res/fonts/*.dat
endif
TWRP_RES_GEN := $(intermediates)/twrp
ifneq ($(TW_USE_TOOLBOX), true)
TWRP_SH_TARGET := /sbin/busybox
@@ -116,6 +126,7 @@ $(TWRP_RES_GEN):
cp -fr $(TWRP_RES_LOC)/* $(TARGET_RECOVERY_ROOT_OUT)/res/
cp -fr $(TWRP_THEME_LOC)/* $(TARGET_RECOVERY_ROOT_OUT)/res/
$(TWRP_COMMON_XML)
$(TWRP_REMOVE_FONT)
mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/sbin/
ln -sf $(TWRP_SH_TARGET) $(TARGET_RECOVERY_ROOT_OUT)/sbin/sh
ln -sf /sbin/pigz $(TARGET_RECOVERY_ROOT_OUT)/sbin/gzip
+1 -1
View File
@@ -177,7 +177,7 @@ GUIConsole::GUIConsole(xml_node<>* node) : GUIObject(node)
}
}
gr_getFontDetails(mFont, &mFontHeight, NULL);
mFontHeight = gr_getMaxFontHeight(mFont ? mFont->GetResource() : NULL);
SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
SetRenderPos(mConsoleX, mConsoleY);
return;
+1 -1
View File
@@ -14,7 +14,7 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Regular-20" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" />
<resource name="base" type="image" filename="background.jpg" />
<resource name="main_button" type="image" filename="button" />
<resource name="file_icon" type="image" filename="file" />
+1 -1
View File
@@ -14,7 +14,7 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Regular-20" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" />
<resource name="base" type="image" filename="background.jpg" />
<resource name="main_button" type="image" filename="button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Condensed-40" />
<resource name="mediumfont" type="font" filename="Roboto-Condensed-40" />
<resource name="filelist" type="font" filename="Roboto-Condensed-40" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Condensed-40" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Condensed-40" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Condensed-40" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="menu-button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Condensed-40" />
<resource name="mediumfont" type="font" filename="Roboto-Condensed-40" />
<resource name="filelist" type="font" filename="Roboto-Condensed-40" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Condensed-40" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Condensed-40" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Condensed-40" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="menu-button" />
<resource name="file_icon" type="image" filename="file" />
+1 -1
View File
@@ -14,7 +14,7 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Regular-20" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" />
<resource name="base" type="image" filename="background.jpg" />
<resource name="main_button" type="image" filename="button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Condensed-50" />
<resource name="mediumfont" type="font" filename="Roboto-Condensed-50" />
<resource name="filelist" type="font" filename="Roboto-Condensed-50" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="50" fallback="Roboto-Condensed-50" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="50" fallback="Roboto-Condensed-50" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="50" fallback="Roboto-Condensed-50" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="menu-button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Condensed-40" />
<resource name="mediumfont" type="font" filename="Roboto-Condensed-40" />
<resource name="filelist" type="font" filename="Roboto-Condensed-40" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Condensed-40" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Condensed-40" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Condensed-40" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="menu-button" />
<resource name="file_icon" type="image" filename="file" />
+1 -1
View File
@@ -14,7 +14,7 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Regular-30" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="30" fallback="Roboto-Regular-30" />
<resource name="base" type="image" filename="background.jpg" />
<resource name="main_button" type="image" filename="button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Condensed-12" />
<resource name="mediumfont" type="font" filename="Roboto-Condensed-12" />
<resource name="filelist" type="font" filename="Roboto-Condensed-12" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="12" fallback="Roboto-Condensed-12" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="12" fallback="Roboto-Condensed-12" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="12" fallback="Roboto-Condensed-12" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="menu-button" />
<resource name="file_icon" type="image" filename="file" />
+1 -1
View File
@@ -14,7 +14,7 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Regular-40" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Regular-40" />
<resource name="base" type="image" filename="background.jpg" />
<resource name="main_button" type="image" filename="button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Condensed-12" />
<resource name="mediumfont" type="font" filename="Roboto-Condensed-12" />
<resource name="filelist" type="font" filename="Roboto-Condensed-12" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="12" fallback="Roboto-Condensed-12" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="12" fallback="Roboto-Condensed-12" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="12" fallback="Roboto-Condensed-12" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="menu-button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Condensed-14" />
<resource name="mediumfont" type="font" filename="Roboto-Condensed-14" />
<resource name="filelist" type="font" filename="Roboto-Condensed-14" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="14" fallback="Roboto-Condensed-14" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="14" fallback="Roboto-Condensed-14" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="14" fallback="Roboto-Condensed-14" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="menu-button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Condensed-16" />
<resource name="mediumfont" type="font" filename="Roboto-Condensed-14" />
<resource name="filelist" type="font" filename="Roboto-Condensed-14" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="14" fallback="Roboto-Condensed-16" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="14" fallback="Roboto-Condensed-14" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="14" fallback="Roboto-Condensed-14" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="menu-button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Regular-20" />
<resource name="mediumfont" type="font" filename="Roboto-Regular-20" />
<resource name="filelist" type="font" filename="Roboto-Regular-20" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="menu-button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Regular-20" />
<resource name="mediumfont" type="font" filename="Roboto-Regular-20" />
<resource name="filelist" type="font" filename="Roboto-Regular-20" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="menu-button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Regular-20" />
<resource name="mediumfont" type="font" filename="Roboto-Regular-20" />
<resource name="filelist" type="font" filename="Roboto-Regular-25" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-25" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="qhd-menu-button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Condensed-30" />
<resource name="mediumfont" type="font" filename="Roboto-Condensed-30" />
<resource name="filelist" type="font" filename="Roboto-Condensed-30" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="30" fallback="Roboto-Condensed-30" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="30" fallback="Roboto-Condensed-30" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="30" fallback="Roboto-Condensed-30" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="menu-button" />
<resource name="file_icon" type="image" filename="file" />
+3 -3
View File
@@ -14,9 +14,9 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Condensed-30" />
<resource name="mediumfont" type="font" filename="Roboto-Condensed-30" />
<resource name="filelist" type="font" filename="Roboto-Condensed-30" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="30" fallback="Roboto-Condensed-30" />
<resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="30" fallback="Roboto-Condensed-30" />
<resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="30" fallback="Roboto-Condensed-30" />
<resource name="top_bar" type="image" filename="top-bar.jpg" />
<resource name="main_button" type="image" filename="menu-button" />
<resource name="file_icon" type="image" filename="file" />
+1 -1
View File
@@ -14,7 +14,7 @@
</include>
<resources>
<resource name="font" type="font" filename="Roboto-Condensed-16" />
<resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="16" fallback="Roboto-Condensed-16" />
<resource name="base" type="image" filename="background.jpg" />
<resource name="main_button" type="image" filename="button" />
<resource name="file_icon" type="image" filename="file" />
+1 -1
View File
@@ -333,7 +333,7 @@ GUIFileSelector::GUIFileSelector(xml_node<>* node) : GUIObject(node)
}
// Retrieve the line height
gr_getFontDetails(mFont ? mFont->GetResource() : NULL, &mFontHeight, NULL);
mFontHeight = gr_getMaxFontHeight(mFont ? mFont->GetResource() : NULL);
mLineHeight = mFontHeight;
mHeaderH = mFontHeight;
+1 -1
View File
@@ -139,7 +139,7 @@ GUIInput::GUIInput(xml_node<>* node)
attr = child->first_attribute("resource");
if (attr) {
mFont = PageManager::FindResource(attr->value());
gr_getFontDetails(mFont ? mFont->GetResource() : NULL, &mFontHeight, NULL);
mFontHeight = gr_getMaxFontHeight(mFont ? mFont->GetResource() : NULL);
}
}
+1 -1
View File
@@ -271,7 +271,7 @@ GUIListBox::GUIListBox(xml_node<>* node) : GUIObject(node)
}
// Retrieve the line height
gr_getFontDetails(mFont ? mFont->GetResource() : NULL, &mFontHeight, NULL);
mFontHeight = gr_getMaxFontHeight(mFont ? mFont->GetResource() : NULL);
mLineHeight = mFontHeight;
mHeaderH = mFontHeight;
+1 -1
View File
@@ -273,7 +273,7 @@ GUIPartitionList::GUIPartitionList(xml_node<>* node) : GUIObject(node)
}
// Retrieve the line height
gr_getFontDetails(mFont ? mFont->GetResource() : NULL, &mFontHeight, NULL);
mFontHeight = gr_getMaxFontHeight(mFont ? mFont->GetResource() : NULL);
mLineHeight = mFontHeight;
mHeaderH = mFontHeight;
+61 -6
View File
@@ -65,27 +65,82 @@ FontResource::FontResource(xml_node<>* node, ZipArchive* pZip)
: Resource(node, pZip)
{
std::string file;
xml_attribute<>* attr;
mFont = NULL;
if (!node)
return;
if (node->first_attribute("filename"))
file = node->first_attribute("filename")->value();
attr = node->first_attribute("filename");
if (!attr)
return;
if (ExtractResource(pZip, "fonts", file, ".dat", TMP_RESOURCE_NAME) == 0)
file = attr->value();
#ifndef TW_DISABLE_TTF
if(file.size() >= 4 && file.compare(file.size()-4, 4, ".ttf") == 0)
{
mFont = gr_loadFont(TMP_RESOURCE_NAME);
unlink(TMP_RESOURCE_NAME);
m_type = TYPE_TTF;
attr = node->first_attribute("size");
if(!attr)
return;
int size = atoi(attr->value());
int dpi = 300;
attr = node->first_attribute("dpi");
if(attr)
dpi = atoi(attr->value());
if (ExtractResource(pZip, "fonts", file, "", TMP_RESOURCE_NAME) == 0)
{
mFont = gr_ttf_loadFont(TMP_RESOURCE_NAME, size, dpi);
unlink(TMP_RESOURCE_NAME);
}
else
{
file = std::string("/res/fonts/") + file;
mFont = gr_ttf_loadFont(file.c_str(), size, dpi);
}
}
else
#endif
{
mFont = gr_loadFont(file.c_str());
m_type = TYPE_TWRP;
if(file.size() >= 4 && file.compare(file.size()-4, 4, ".ttf") == 0)
{
attr = node->first_attribute("fallback");
if (!attr)
return;
file = attr->value();
}
if (ExtractResource(pZip, "fonts", file, ".dat", TMP_RESOURCE_NAME) == 0)
{
mFont = gr_loadFont(TMP_RESOURCE_NAME);
unlink(TMP_RESOURCE_NAME);
}
else
{
mFont = gr_loadFont(file.c_str());
}
}
}
FontResource::~FontResource()
{
if(mFont)
{
#ifndef TW_DISABLE_TTF
if(m_type == TYPE_TTF)
gr_ttf_freeFont(mFont);
else
#endif
gr_freeFont(mFont);
}
}
ImageResource::ImageResource(xml_node<>* node, ZipArchive* pZip)
+9
View File
@@ -38,6 +38,14 @@ typedef enum {
class FontResource : public Resource
{
public:
enum Type
{
TYPE_TWRP,
#ifndef TW_DISABLE_TTF
TYPE_TTF,
#endif
};
FontResource(xml_node<>* node, ZipArchive* pZip);
virtual ~FontResource();
@@ -46,6 +54,7 @@ public:
protected:
void* mFont;
Type m_type;
};
class ImageResource : public Resource
+1 -1
View File
@@ -198,7 +198,7 @@ GUISliderValue::GUISliderValue(xml_node<>* node) : GUIObject(node)
}
}
gr_getFontDetails(mFont ? mFont->GetResource() : NULL, (unsigned*) &mFontHeight, NULL);
mFontHeight = gr_getMaxFontHeight(mFont ? mFont->GetResource() : NULL);
if(mShowCurr)
{
+1 -1
View File
@@ -97,7 +97,7 @@ GUIText::GUIText(xml_node<>* node)
mLastValue = parseText();
if (mLastValue != mText) mIsStatic = 0;
gr_getFontDetails(mFont ? mFont->GetResource() : NULL, (unsigned*) &mFontHeight, NULL);
mFontHeight = gr_getMaxFontHeight(mFont ? mFont->GetResource() : NULL);
return;
}
+10 -2
View File
@@ -107,8 +107,16 @@ ifneq ($(TW_WHITELIST_INPUT),)
LOCAL_CFLAGS += -DWHITELIST_INPUT=$(TW_WHITELIST_INPUT)
endif
LOCAL_SHARED_LIBRARIES += libz libc libcutils libjpeg
LOCAL_STATIC_LIBRARIES += libpng libpixelflinger_static
ifeq ($(TW_DISABLE_TTF), true)
LOCAL_CFLAGS += -DTW_DISABLE_TTF
else
LOCAL_SHARED_LIBRARIES += libft2
LOCAL_C_INCLUDES += external/freetype/include
LOCAL_SRC_FILES += truetype.c
endif
LOCAL_SHARED_LIBRARIES += libz libc libcutils libjpeg libpng
LOCAL_STATIC_LIBRARIES += libpixelflinger_static
LOCAL_MODULE_TAGS := eng
LOCAL_MODULE := libminuitwrp
+42 -59
View File
@@ -58,6 +58,7 @@
// #define PRINT_SCREENINFO 1 // Enables printing of screen info to log
typedef struct {
int type;
GGLSurface texture;
unsigned offset[97];
unsigned cheight;
@@ -392,6 +393,11 @@ int gr_measureEx(const char *s, void* font)
if (!fnt) fnt = gr_font;
#ifndef TW_DISABLE_TTF
if(fnt->type == FONT_TYPE_TTF)
return gr_ttf_measureEx(s, font);
#endif
while ((off = *s++))
{
off -= 32;
@@ -410,6 +416,11 @@ int gr_maxExW(const char *s, void* font, int max_width)
if (!fnt) fnt = gr_font;
#ifndef TW_DISABLE_TTF
if(fnt->type == FONT_TYPE_TTF)
return gr_ttf_maxExW(s, font, max_width);
#endif
while ((off = *s++))
{
off -= 32;
@@ -425,21 +436,6 @@ int gr_maxExW(const char *s, void* font, int max_width)
return total;
}
unsigned character_width(const char *s, void* pFont)
{
GRFont *font = (GRFont*) pFont;
unsigned off;
/* Handle default font */
if (!font) font = gr_font;
off = *s - 32;
if (off == 0)
return 0;
return font->offset[off+1] - font->offset[off];
}
int gr_textEx(int x, int y, const char *s, void* pFont)
{
GGLContext *gl = gr_context;
@@ -450,6 +446,11 @@ int gr_textEx(int x, int y, const char *s, void* pFont)
/* Handle default font */
if (!font) font = gr_font;
#ifndef TW_DISABLE_TTF
if(font->type == FONT_TYPE_TTF)
return gr_ttf_textExWH(gl, x, y, s, pFont, -1, -1);
#endif
gl->bindTexture(gl, &font->texture);
gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
@@ -480,6 +481,11 @@ int gr_textExW(int x, int y, const char *s, void* pFont, int max_width)
/* Handle default font */
if (!font) font = gr_font;
#ifndef TW_DISABLE_TTF
if(font->type == FONT_TYPE_TTF)
return gr_ttf_textExWH(gl, x, y, s, pFont, max_width, -1);
#endif
gl->bindTexture(gl, &font->texture);
gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
@@ -518,6 +524,11 @@ int gr_textExWH(int x, int y, const char *s, void* pFont, int max_width, int max
/* Handle default font */
if (!font) font = gr_font;
#ifndef TW_DISABLE_TTF
if(font->type == FONT_TYPE_TTF)
return gr_ttf_textExWH(gl, x, y, s, pFont, max_width, max_height);
#endif
gl->bindTexture(gl, &font->texture);
gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
@@ -549,34 +560,6 @@ int gr_textExWH(int x, int y, const char *s, void* pFont, int max_width, int max
return x;
}
int twgr_text(int x, int y, const char *s)
{
GGLContext *gl = gr_context;
GRFont *font = gr_font;
unsigned off;
unsigned cwidth = 0;
y -= font->ascent;
gl->bindTexture(gl, &font->texture);
gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
gl->enable(gl, GGL_TEXTURE_2D);
while((off = *s++)) {
off -= 32;
if (off < 96) {
cwidth = font->offset[off+1] - font->offset[off];
gl->texCoord2i(gl, (off * cwidth) - x, 0 - y);
gl->recti(gl, x, y, x + cwidth, y + font->cheight);
}
x += cwidth;
}
return x;
}
void gr_fill(int x, int y, int w, int h)
{
GGLContext *gl = gr_context;
@@ -682,33 +665,32 @@ void* gr_loadFont(const char* fontName)
ftex->stride = width;
ftex->data = (void*) bits;
ftex->format = GGL_PIXEL_FORMAT_A_8;
font->type = FONT_TYPE_TWRP;
font->cheight = height;
font->ascent = height - 2;
return (void*) font;
}
int gr_getFontDetails(void* font, unsigned* cheight, unsigned* maxwidth)
void gr_freeFont(void *font)
{
GRFont *f = font;
free(f->texture.data);
free(f);
}
int gr_getMaxFontHeight(void *font)
{
GRFont *fnt = (GRFont*) font;
if (!fnt) fnt = gr_font;
if (!fnt) return -1;
if (cheight) *cheight = fnt->cheight;
if (maxwidth)
{
int pos;
*maxwidth = 0;
for (pos = 0; pos < 96; pos++)
{
unsigned int width = fnt->offset[pos+1] - fnt->offset[pos];
if (width > *maxwidth)
{
*maxwidth = width;
}
}
}
return 0;
#ifndef TW_DISABLE_TTF
if(fnt->type == FONT_TYPE_TTF)
return gr_ttf_getMaxFontHeight(font);
#endif
return fnt->cheight;
}
static void gr_init_font(void)
@@ -746,6 +728,7 @@ static void gr_init_font(void)
ftex->stride = width;
ftex->data = (void*) bits;
ftex->format = GGL_PIXEL_FORMAT_A_8;
gr_font->type = FONT_TYPE_TWRP;
gr_font->cheight = height;
gr_font->ascent = height - 2;
return;
+18 -3
View File
@@ -20,6 +20,12 @@
typedef void* gr_surface;
typedef unsigned short gr_pixel;
#define FONT_TYPE_TWRP 0
#ifndef TW_DISABLE_TTF
#define FONT_TYPE_TTF 1
#endif
int gr_init(void);
void gr_exit(void);
@@ -35,16 +41,25 @@ void gr_fill(int x, int y, int w, int h);
int gr_textEx(int x, int y, const char *s, void* font);
int gr_textExW(int x, int y, const char *s, void* font, int max_width);
int gr_textExWH(int x, int y, const char *s, void* pFont, int max_width, int max_height);
int twgr_text(int x, int y, const char *s);
static inline int gr_text(int x, int y, const char *s) { return gr_textEx(x, y, s, NULL); }
int gr_measureEx(const char *s, void* font);
static inline int gr_measure(const char *s) { return gr_measureEx(s, NULL); }
int gr_maxExW(const char *s, void* font, int max_width);
int gr_getFontDetails(void* font, unsigned* cheight, unsigned* maxwidth);
static inline void gr_font_size(int *x, int *y) { gr_getFontDetails(NULL, (unsigned*) y, (unsigned*) x); }
int gr_getMaxFontHeight(void *font);
void* gr_loadFont(const char* fontName);
void gr_freeFont(void *font);
#ifndef TW_DISABLE_TTF
void *gr_ttf_loadFont(const char *filename, int size, int dpi);
void gr_ttf_freeFont(void *font);
int gr_ttf_textExWH(void *context, int x, int y, const char *s, void *pFont, int max_width, int max_height);
int gr_ttf_measureEx(const char *s, void *font);
int gr_ttf_maxExW(const char *s, void *font, int max_width);
int gr_ttf_getMaxFontHeight(void *font);
void gr_ttf_dump_stats(void);
#endif
void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy);
unsigned int gr_get_width(gr_surface surface);
+731
View File
@@ -0,0 +1,731 @@
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include "minui.h"
#include <cutils/hashmap.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include <pixelflinger/pixelflinger.h>
#include <pthread.h>
#define STRING_CACHE_MAX_ENTRIES 400
#define STRING_CACHE_TRUNCATE_ENTRIES 150
typedef struct
{
int size;
int dpi;
char *path;
} TrueTypeFontKey;
typedef struct
{
int type;
int refcount;
int size;
int dpi;
int max_height;
int base;
FT_Face face;
Hashmap *glyph_cache;
Hashmap *string_cache;
struct StringCacheEntry *string_cache_head;
struct StringCacheEntry *string_cache_tail;
pthread_mutex_t mutex;
TrueTypeFontKey *key;
} TrueTypeFont;
typedef struct
{
FT_BBox bbox;
FT_BitmapGlyph glyph;
} TrueTypeCacheEntry;
typedef struct
{
char *text;
int max_width;
} StringCacheKey;
struct StringCacheEntry
{
GGLSurface surface;
int rendered_len;
StringCacheKey *key;
struct StringCacheEntry *prev;
struct StringCacheEntry *next;
};
typedef struct StringCacheEntry StringCacheEntry;
typedef struct
{
FT_Library ft_library;
Hashmap *fonts;
pthread_mutex_t mutex;
} FontData;
static FontData font_data = {
.ft_library = NULL,
.fonts = NULL,
.mutex = PTHREAD_MUTEX_INITIALIZER,
};
#define MIN(X,Y) ((X) < (Y) ? (X) : (Y))
#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
// 32bit FNV-1a hash algorithm
// http://isthe.com/chongo/tech/comp/fnv/#FNV-1a
static const uint32_t FNV_prime = 16777619U;
static const uint32_t offset_basis = 2166136261U;
static uint32_t fnv_hash(void *data, uint32_t len)
{
uint8_t *d8 = data;
uint32_t *d32 = data;
uint32_t i, max;
uint32_t hash = offset_basis;
max = len/4;
// 32 bit data
for(i = 0; i < max; ++i)
{
hash ^= *d32++;
hash *= FNV_prime;
}
// last bits
for(i *= 4; i < len; ++i)
{
hash ^= (uint32_t) d8[i];
hash *= FNV_prime;
}
return hash;
}
static inline uint32_t fnv_hash_add(uint32_t cur_hash, uint32_t word)
{
cur_hash ^= word;
cur_hash *= FNV_prime;
return cur_hash;
}
static bool gr_ttf_string_cache_equals(void *keyA, void *keyB)
{
StringCacheKey *a = keyA;
StringCacheKey *b = keyB;
return a->max_width == b->max_width && strcmp(a->text, b->text) == 0;
}
static int gr_ttf_string_cache_hash(void *key)
{
StringCacheKey *k = key;
return fnv_hash(k->text, strlen(k->text));
}
static bool gr_ttf_font_cache_equals(void *keyA, void *keyB)
{
TrueTypeFontKey *a = keyA;
TrueTypeFontKey *b = keyB;
return (a->size == b->size) && (a->dpi == b->dpi) && !strcmp(a->path, b->path);
}
static int gr_ttf_font_cache_hash(void *key)
{
TrueTypeFontKey *k = key;
uint32_t hash = fnv_hash(k->path, strlen(k->path));
hash = fnv_hash_add(hash, k->size);
hash = fnv_hash_add(hash, k->dpi);
return hash;
}
void *gr_ttf_loadFont(const char *filename, int size, int dpi)
{
int error;
TrueTypeFont *res = NULL;
pthread_mutex_lock(&font_data.mutex);
if(font_data.fonts)
{
TrueTypeFontKey k = {
.size = size,
.dpi = dpi,
.path = (char*)filename
};
res = hashmapGet(font_data.fonts, &k);
if(res)
{
++res->refcount;
goto exit;
}
}
if(!font_data.ft_library)
{
error = FT_Init_FreeType(&font_data.ft_library);
if(error)
{
fprintf(stderr, "Failed to init libfreetype! %d\n", error);
goto exit;
}
}
FT_Face face;
error = FT_New_Face(font_data.ft_library, filename, 0, &face);
if(error)
{
fprintf(stderr, "Failed to load truetype face %s: %d\n", filename, error);
goto exit;
}
error = FT_Set_Char_Size(face, 0, size*16, dpi, dpi);
if(error)
{
fprintf(stderr, "Failed to set truetype face size to %d, dpi %d: %d\n", size, dpi, error);
FT_Done_Face(face);
goto exit;
}
res = malloc(sizeof(TrueTypeFont));
memset(res, 0, sizeof(TrueTypeFont));
res->type = FONT_TYPE_TTF;
res->size = size;
res->dpi = dpi;
res->face = face;
res->max_height = -1;
res->base = -1;
res->refcount = 1;
res->glyph_cache = hashmapCreate(32, hashmapIntHash, hashmapIntEquals);
res->string_cache = hashmapCreate(128, gr_ttf_string_cache_hash, gr_ttf_string_cache_equals);
pthread_mutex_init(&res->mutex, 0);
if(!font_data.fonts)
font_data.fonts = hashmapCreate(4, gr_ttf_font_cache_hash, gr_ttf_font_cache_equals);
TrueTypeFontKey *key = malloc(sizeof(TrueTypeFontKey));
memset(key, 0, sizeof(TrueTypeFontKey));
key->path = strdup(filename);
key->size = size;
key->dpi = dpi;
res->key = key;
hashmapPut(font_data.fonts, key, res);
exit:
pthread_mutex_unlock(&font_data.mutex);
return res;
}
static bool gr_ttf_freeFontCache(void *key, void *value, void *context)
{
TrueTypeCacheEntry *e = value;
FT_Done_Glyph((FT_Glyph)e->glyph);
free(e);
free(key);
return true;
}
static bool gr_ttf_freeStringCache(void *key, void *value, void *context)
{
StringCacheKey *k = key;
free(k->text);
free(k);
StringCacheEntry *e = value;
free(e->surface.data);
free(e);
return true;
}
void gr_ttf_freeFont(void *font)
{
pthread_mutex_lock(&font_data.mutex);
TrueTypeFont *d = font;
if(--d->refcount == 0)
{
hashmapRemove(font_data.fonts, d->key);
if(hashmapSize(font_data.fonts) == 0)
{
hashmapFree(font_data.fonts);
font_data.fonts = NULL;
}
free(d->key->path);
free(d->key);
FT_Done_Face(d->face);
hashmapForEach(d->string_cache, gr_ttf_freeStringCache, NULL);
hashmapFree(d->string_cache);
hashmapForEach(d->glyph_cache, gr_ttf_freeFontCache, NULL);
hashmapFree(d->glyph_cache);
pthread_mutex_destroy(&d->mutex);
free(d);
}
pthread_mutex_unlock(&font_data.mutex);
}
static TrueTypeCacheEntry *gr_ttf_glyph_cache_peek(TrueTypeFont *font, int char_index)
{
return hashmapGet(font->glyph_cache, &char_index);
}
static TrueTypeCacheEntry *gr_ttf_glyph_cache_get(TrueTypeFont *font, int char_index)
{
TrueTypeCacheEntry *res = hashmapGet(font->glyph_cache, &char_index);
if(!res)
{
int error = FT_Load_Glyph(font->face, char_index, FT_LOAD_RENDER);
if(error)
{
fprintf(stderr, "Failed to load glyph idx %d: %d\n", char_index, error);
return NULL;
}
FT_BitmapGlyph glyph;
error = FT_Get_Glyph(font->face->glyph, (FT_Glyph*)&glyph);
if(error)
{
fprintf(stderr, "Failed to copy glyph %d: %d\n", char_index, error);
return NULL;
}
res = malloc(sizeof(TrueTypeCacheEntry));
memset(res, 0, sizeof(TrueTypeCacheEntry));
res->glyph = glyph;
FT_Glyph_Get_CBox((FT_Glyph)glyph, FT_GLYPH_BBOX_PIXELS, &res->bbox);
int *key = malloc(sizeof(int));
*key = char_index;
hashmapPut(font->glyph_cache, key, res);
}
return res;
}
static int gr_ttf_copy_glyph_to_surface(GGLSurface *dest, FT_BitmapGlyph glyph, int offX, int offY, int base)
{
int y;
uint8_t *src_itr = glyph->bitmap.buffer;
uint8_t *dest_itr = dest->data;
if(glyph->bitmap.pixel_mode != FT_PIXEL_MODE_GRAY)
{
fprintf(stderr, "Unsupported pixel mode in FT_BitmapGlyph %d\n", glyph->bitmap.pixel_mode);
return -1;
}
dest_itr += (offY + base - glyph->top)*dest->stride + (offX + glyph->left);
for(y = 0; y < glyph->bitmap.rows; ++y)
{
memcpy(dest_itr, src_itr, glyph->bitmap.width);
src_itr += glyph->bitmap.pitch;
dest_itr += dest->stride;
}
return 0;
}
static int gr_ttf_render_text(TrueTypeFont *font, GGLSurface *surface, const char *text, int max_width)
{
TrueTypeFont *f = font;
TrueTypeCacheEntry *ent;
int max_len = 0, total_w = 0;
char c;
int i, x, diff, char_idx, prev_idx = 0;
int height, base;
FT_Vector delta;
uint8_t *data = NULL;
const char *text_itr = text;
while((c = *text_itr++))
{
char_idx = FT_Get_Char_Index(f->face, c);
ent = gr_ttf_glyph_cache_get(f, char_idx);
if(ent)
{
diff = ent->glyph->root.advance.x >> 16;
if(FT_HAS_KERNING(f->face) && prev_idx && char_idx)
{
FT_Get_Kerning(f->face, prev_idx, char_idx, FT_KERNING_DEFAULT, &delta);
diff += delta.x >> 6;
}
if(max_width != -1 && total_w + diff > max_width)
break;
total_w += diff;
}
prev_idx = char_idx;
++max_len;
}
if(font->max_height == -1)
gr_ttf_getMaxFontHeight(font);
if(font->max_height == -1)
return -1;
height = font->max_height;
data = malloc(total_w*height);
memset(data, 0, total_w*height);
x = 0;
prev_idx = 0;
surface->version = sizeof(*surface);
surface->width = total_w;
surface->height = height;
surface->stride = total_w;
surface->data = (void*)data;
surface->format = GGL_PIXEL_FORMAT_A_8;
for(i = 0; i < max_len; ++i)
{
char_idx = FT_Get_Char_Index(f->face, text[i]);
if(FT_HAS_KERNING(f->face) && prev_idx && char_idx)
{
FT_Get_Kerning(f->face, prev_idx, char_idx, FT_KERNING_DEFAULT, &delta);
x += delta.x >> 6;
}
ent = gr_ttf_glyph_cache_get(f, char_idx);
if(ent)
{
gr_ttf_copy_glyph_to_surface(surface, ent->glyph, x, 0, font->base);
x += ent->glyph->root.advance.x >> 16;
}
prev_idx = char_idx;
}
return max_len;
}
static StringCacheEntry *gr_ttf_string_cache_peek(TrueTypeFont *font, const char *text, int max_width)
{
StringCacheEntry *res;
StringCacheKey k = {
.text = (char*)text,
.max_width = max_width
};
return hashmapGet(font->string_cache, &k);
}
static StringCacheEntry *gr_ttf_string_cache_get(TrueTypeFont *font, const char *text, int max_width)
{
StringCacheEntry *res;
StringCacheKey k = {
.text = (char*)text,
.max_width = max_width
};
res = hashmapGet(font->string_cache, &k);
if(!res)
{
res = malloc(sizeof(StringCacheEntry));
memset(res, 0, sizeof(StringCacheEntry));
res->rendered_len = gr_ttf_render_text(font, &res->surface, text, max_width);
if(res->rendered_len < 0)
{
free(res);
return NULL;
}
StringCacheKey *new_key = malloc(sizeof(StringCacheKey));
memset(new_key, 0, sizeof(StringCacheKey));
new_key->max_width = max_width;
new_key->text = strdup(text);
res->key = new_key;
if(font->string_cache_tail)
{
res->prev = font->string_cache_tail;
res->prev->next = res;
}
else
font->string_cache_head = res;
font->string_cache_tail = res;
hashmapPut(font->string_cache, new_key, res);
}
else if(res->next)
{
// move this entry to the tail of the linked list
// if it isn't already there
if(res->prev)
res->prev->next = res->next;
res->next->prev = res->prev;
if(!res->prev)
font->string_cache_head = res->next;
res->next = NULL;
res->prev = font->string_cache_tail;
res->prev->next = res;
font->string_cache_tail = res;
// truncate old entries
if(hashmapSize(font->string_cache) >= STRING_CACHE_MAX_ENTRIES)
{
printf("Truncating string cache entries.\n");
int i;
StringCacheEntry *ent;
for(i = 0; i < STRING_CACHE_TRUNCATE_ENTRIES; ++i)
{
ent = font->string_cache_head;
font->string_cache_head = ent->next;
font->string_cache_head->prev = NULL;
hashmapRemove(font->string_cache, ent->key);
gr_ttf_freeStringCache(ent->key, ent, NULL);
}
}
}
return res;
}
int gr_ttf_measureEx(const char *s, void *font)
{
TrueTypeFont *f = font;
int res = -1;
pthread_mutex_lock(&f->mutex);
StringCacheEntry *e = gr_ttf_string_cache_get(font, s, -1);
if(e)
res = e->surface.width;
pthread_mutex_unlock(&f->mutex);
return res;
}
int gr_ttf_maxExW(const char *s, void *font, int max_width)
{
TrueTypeFont *f = font;
TrueTypeCacheEntry *ent;
int max_len = 0, total_w = 0;
char c;
int char_idx, prev_idx = 0;
FT_Vector delta;
StringCacheEntry *e;
pthread_mutex_lock(&f->mutex);
e = gr_ttf_string_cache_peek(font, s, max_width);
if(e)
{
max_len = e->rendered_len;
pthread_mutex_unlock(&f->mutex);
return max_len;
}
for(; (c = *s++); ++max_len)
{
char_idx = FT_Get_Char_Index(f->face, c);
if(FT_HAS_KERNING(f->face) && prev_idx && char_idx)
{
FT_Get_Kerning(f->face, prev_idx, char_idx, FT_KERNING_DEFAULT, &delta);
total_w += delta.x >> 6;
}
prev_idx = char_idx;
if(total_w > max_width)
break;
ent = gr_ttf_glyph_cache_get(f, char_idx);
if(!ent)
continue;
total_w += ent->glyph->root.advance.x >> 16;
}
pthread_mutex_unlock(&f->mutex);
return max_len > 0 ? max_len - 1 : 0;
}
int gr_ttf_textExWH(void *context, int x, int y, const char *s, void *pFont, int max_width, int max_height)
{
GGLContext *gl = context;
TrueTypeFont *font = pFont;
// not actualy max width, but max_width + x
if(max_width != -1)
{
max_width -= x;
if(max_width <= 0)
return 0;
}
pthread_mutex_lock(&font->mutex);
StringCacheEntry *e = gr_ttf_string_cache_get(font, s, max_width);
if(!e)
{
pthread_mutex_unlock(&font->mutex);
return -1;
}
int y_bottom = y + e->surface.height;
int res = e->rendered_len;
if(max_height != -1 && max_height < y_bottom)
{
y_bottom = max_height;
if(y_bottom <= y)
{
pthread_mutex_unlock(&font->mutex);
return 0;
}
}
gl->bindTexture(gl, &e->surface);
gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
gl->enable(gl, GGL_TEXTURE_2D);
gl->texCoord2i(gl, -x, -y);
gl->recti(gl, x, y, x + e->surface.width, y_bottom);
pthread_mutex_unlock(&font->mutex);
return res;
}
int gr_ttf_getMaxFontHeight(void *font)
{
int res;
TrueTypeFont *f = font;
pthread_mutex_lock(&f->mutex);
if(f->max_height == -1)
{
char c;
int char_idx;
int error;
FT_Glyph glyph;
FT_BBox bbox;
FT_BBox bbox_glyph;
TrueTypeCacheEntry *ent;
bbox.yMin = bbox_glyph.yMin = LONG_MAX;
bbox.yMax = bbox_glyph.yMax = LONG_MIN;
for(c = '!'; c <= '~'; ++c)
{
char_idx = FT_Get_Char_Index(f->face, c);
ent = gr_ttf_glyph_cache_peek(f, char_idx);
if(ent)
{
bbox.yMin = MIN(bbox.yMin, ent->bbox.yMin);
bbox.yMax = MAX(bbox.yMax, ent->bbox.yMax);
}
else
{
error = FT_Load_Glyph(f->face, char_idx, 0);
if(error)
continue;
error = FT_Get_Glyph(f->face->glyph, &glyph);
if(error)
continue;
FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &bbox_glyph);
bbox.yMin = MIN(bbox.yMin, bbox_glyph.yMin);
bbox.yMax = MAX(bbox.yMax, bbox_glyph.yMax);
FT_Done_Glyph(glyph);
}
}
if(bbox.yMin > bbox.yMax)
bbox.yMin = bbox.yMax = 0;
f->max_height = bbox.yMax - bbox.yMin;
f->base = bbox.yMax;
// FIXME: twrp fonts have some padding on top, I'll add it here
// Should be fixed in the themes
f->max_height += f->size / 4;
f->base += f->size / 4;
}
res = f->max_height;
pthread_mutex_unlock(&f->mutex);
return res;
}
static bool gr_ttf_dump_stats_count_string_cache(void *key, void *value, void *context)
{
int *string_cache_size = context;
StringCacheEntry *e = value;
*string_cache_size += e->surface.height*e->surface.width + sizeof(StringCacheEntry);
return true;
}
static bool gr_ttf_dump_stats_font(void *key, void *value, void *context)
{
TrueTypeFontKey *k = key;
TrueTypeFont *f = value;
int *total_string_cache_size = context;
int string_cache_size = 0;
pthread_mutex_lock(&f->mutex);
hashmapForEach(f->string_cache, gr_ttf_dump_stats_count_string_cache, &string_cache_size);
printf(" Font %s (size %d, dpi %d):\n"
" refcount: %d\n"
" max_height: %d\n"
" base: %d\n"
" glyph_cache: %d entries\n"
" string_cache: %d entries (%.2f kB)\n",
k->path, k->size, k->dpi,
f->refcount, f->max_height, f->base,
hashmapSize(f->glyph_cache),
hashmapSize(f->string_cache), ((double)string_cache_size)/1024);
pthread_mutex_unlock(&f->mutex);
*total_string_cache_size += string_cache_size;
return true;
}
void gr_ttf_dump_stats(void)
{
pthread_mutex_lock(&font_data.mutex);
printf("TrueType fonts system stats: ");
if(!font_data.fonts)
printf("no truetype fonts loaded.\n");
else
{
int total_string_cache_size = 0;
printf("%d fonts loaded.\n", hashmapSize(font_data.fonts));
hashmapForEach(font_data.fonts, gr_ttf_dump_stats_font, &total_string_cache_size);
printf(" Total string cache size: %.2f kB\n", ((double)total_string_cache_size)/1024);
}
pthread_mutex_unlock(&font_data.mutex);
}
+4
View File
@@ -40,6 +40,7 @@ RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libext2_e2p.so
RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libext2fs.so
RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libext2_profile.so
RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libext2_uuid.so
RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libpng.so
RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/liblog.so
RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libm.so
RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libstdc++.so
@@ -122,6 +123,9 @@ endif
ifneq ($(wildcard system/core/reboot/Android.mk),)
RELINK_SOURCE_FILES += $(TARGET_OUT_EXECUTABLES)/reboot
endif
ifneq ($(TW_DISABLE_TTF), true)
RELINK_SOURCE_FILES += $(TARGET_OUT_SHARED_LIBRARIES)/libft2.so
endif
TWRP_AUTOGEN := $(intermediates)/teamwin