truetype: convert to STL map for handling fonts

In Android 10, libcutils is deprecating the hash functions. This
patchset moves to use the STL map to handle storing related
truetype objects.

This patchset moves the truetype functions to it's own static
class and moves the declarations to a header file. I also removed
statistics functions that were not called from anywhere.

Change-Id: I1679df4c7e844c01e3a2cbdaf5117bb09df2a5f3
diff --git a/minuitwrp/truetype.cpp b/minuitwrp/truetype.cpp
index 3dffbe4..de92715 100755
--- a/minuitwrp/truetype.cpp
+++ b/minuitwrp/truetype.cpp
@@ -163,19 +163,17 @@
 {
 	TrueTypeCacheEntry *e = (TrueTypeCacheEntry *)value;
 	FT_Done_Glyph((FT_Glyph)e->glyph);
-	free(e);
+	delete e;
 	return true;
 }
 
-bool twrpTruetype::gr_ttf_freeStringCache(void *key, void *value, void *context __unused) {
+void twrpTruetype::gr_ttf_freeStringCache(void *key, void *value, void *context __unused) {
 	StringCacheKey *k = (StringCacheKey *)key;
-	delete k->text;
 	delete k;
 
 	StringCacheEntry *e = (StringCacheEntry *)value;
-	delete e->surface.data;
+	free(e->surface.data);
 	delete e;
-	return true;
 }
 
 void twrpTruetype::gr_ttf_freeFont(void *font) {
@@ -191,13 +189,13 @@
 
 		StringCacheMap::iterator stringCacheEntryIt = d->string_cache.begin();
 		while (stringCacheEntryIt != d->string_cache.end()) {
-			gr_ttf_freeStringCache(stringCacheEntryIt->second->key, stringCacheEntryIt->second, NULL);
+			gr_ttf_freeStringCache(stringCacheEntryIt->second->key, stringCacheEntryIt->second, nullptr);
 			stringCacheEntryIt = d->string_cache.erase(stringCacheEntryIt);
 		}
 
 		TrueTypeCacheEntryMap::iterator ttcIt = d->glyph_cache.begin();
 		while(ttcIt != d->glyph_cache.end()) {
-			gr_ttf_freeFontCache(ttcIt->second, NULL);
+			gr_ttf_freeFontCache(ttcIt->second, nullptr);
 			ttcIt = d->glyph_cache.erase(ttcIt);
 		}
 
@@ -230,7 +228,7 @@
 		if(error)
 		{
 			fprintf(stderr, "Failed to load glyph idx %d: %d\n", char_index, error);
-			return NULL;
+			return nullptr;
 		}
 
 		FT_BitmapGlyph glyph;
@@ -238,7 +236,7 @@
 		if(error)
 		{
 			fprintf(stderr, "Failed to copy glyph %d: %d\n", char_index, error);
-			return NULL;
+			return nullptr;
 		}
 
 		res = new TrueTypeCacheEntry;
@@ -332,7 +330,7 @@
 }
 
 // returns number of bytes from const char *text rendered to fit max_width, not number of UTF8 characters!
-int twrpTruetype::gr_ttf_render_text(TrueTypeFont *font, GGLSurface *surface, const char *text, int max_width) {
+int twrpTruetype::gr_ttf_render_text(TrueTypeFont *font, GGLSurface *surface, const std::string text, int max_width) {
 	TrueTypeFont *f = font;
 	TrueTypeCacheEntry *ent;
 	int bytes_rendered = 0, total_w = 0;
@@ -342,11 +340,11 @@
 	int height;
 	FT_Vector delta;
 	uint8_t *data = NULL;
-	const char *text_itr = text;
+	const char *text_itr = text.c_str();
 	int *char_idxs;
 	int char_idxs_len = 0;
 
-	char_idxs = new int[strlen(text)];
+	char_idxs = new int[text.length()];
 
 	while(*text_itr)
 	{
@@ -387,8 +385,8 @@
 
 	height = font->max_height;
 
-	data = new uint8_t[total_w * height];
-	x = 0;
+	data = (uint8_t *)malloc(total_w*height);
+    memset(data, 0, total_w*height);	x = 0;
 	prev_idx = 0;
 
 	surface->version = sizeof(*surface);
@@ -422,10 +420,10 @@
 }
 
 StringCacheEntry* twrpTruetype::gr_ttf_string_cache_peek(TrueTypeFont *font, 
-	const char *text, 
+	const std::string text, 
 	__attribute__((unused)) int max_width) {
 		StringCacheKey k = {
-			.text = (char*)text,
+			.text = text,
 			.max_width = max_width
 		};
 		StringCacheMap::iterator stringCacheItr = font->string_cache.find(k);
@@ -437,50 +435,49 @@
 		}
 }
 
-StringCacheEntry* twrpTruetype::gr_ttf_string_cache_get(TrueTypeFont *font, const char *text, int max_width) {
+void twrpTruetype::gr_ttf_string_cache_truncate(TrueTypeFont *font) {
+	StringCacheMap::iterator stringCacheItr;
+
+	if (font->string_cache.size() == STRING_CACHE_MAX_ENTRIES) {
+		StringCacheEntry *truncateEntry = nullptr;
+		stringCacheItr = font->string_cache.begin();
+		int deleteCtr = 0;
+		while (stringCacheItr != font->string_cache.end() || deleteCtr == (STRING_CACHE_MAX_ENTRIES - 1)) {
+			truncateEntry = stringCacheItr->second;
+			gr_ttf_freeStringCache(truncateEntry->key, truncateEntry, nullptr);
+			stringCacheItr = font->string_cache.erase(stringCacheItr);
+			deleteCtr++;
+		}
+	}
+}
+
+StringCacheEntry* twrpTruetype::gr_ttf_string_cache_get(TrueTypeFont *font, const std::string text, int max_width) {
 	StringCacheEntry *res = nullptr;
+	StringCacheMap::iterator stringCacheItr;
 
 	StringCacheKey k = {
-		.text = (char*)text,
+		.text = text,
 		.max_width = max_width
 	};
 
-	StringCacheMap::iterator stringCacheItr = font->string_cache.find(k);
-	if (stringCacheItr == font->string_cache.end())
-	{
+	stringCacheItr = font->string_cache.find(k);
+	if (stringCacheItr == font->string_cache.end()) {
 		res = new StringCacheEntry;
 		res->rendered_bytes = gr_ttf_render_text(font, &res->surface, text, max_width);
-		if(res->rendered_bytes < 0)
-		{
+		if(res->rendered_bytes < 0) {
 			delete res;
 			return nullptr;
 		}
 
 		StringCacheKey *new_key = new StringCacheKey;
 		new_key->max_width = max_width;
-		new_key->text = strdup(text);
+		new_key->text = text;
 		res->key = new_key;
-		font->string_cache[k] = res; 
+		font->string_cache[*new_key] = res; 
 	}
 	else
 	{
 		res = stringCacheItr->second;
-
-		// truncate old entries
-		if (font->string_cache.size() >= STRING_CACHE_MAX_ENTRIES)
-		{
-			StringCacheEntry *ent;
-			for(int i = 0; i < STRING_CACHE_TRUNCATE_ENTRIES; ++i)
-			{
-				StringCacheMap::iterator stringTruncCacheItr = font->string_cache.find(k);
-
-				if (stringTruncCacheItr != font->string_cache.end()) {
-					ent = stringTruncCacheItr->second;
-					gr_ttf_freeStringCache(ent->key, ent, nullptr);
-					font->string_cache.erase(stringTruncCacheItr);
-				}
-			}
-		}
 	}
 	return res;
 }
@@ -490,6 +487,7 @@
 	int res = -1;
 
 	pthread_mutex_lock(&f->mutex);
+	gr_ttf_string_cache_truncate(f);
 	StringCacheEntry *e = gr_ttf_string_cache_get(f, s, -1);
 	if(e)
 		res = e->surface.width;
@@ -511,15 +509,13 @@
 	pthread_mutex_lock(&f->mutex);
 
 	e = gr_ttf_string_cache_peek(f, s, max_width);
-	if(e)
-	{
+	if (e) {
 		max_bytes = e->rendered_bytes;
 		pthread_mutex_unlock(&f->mutex);
 		return max_bytes;
 	}
 
-	while(*s)
-	{
+	while(*s) {
 		utf_bytes = utf8_to_unicode(s, &unicode);
 		s += utf_bytes;
 
@@ -567,8 +563,7 @@
 	pthread_mutex_lock(&font->mutex);
 
 	StringCacheEntry *e = gr_ttf_string_cache_get(font, s, max_width);
-	if(!e)
-	{
+	if (!e) {
 		pthread_mutex_unlock(&font->mutex);
 		return -1;
 	}
@@ -584,8 +579,8 @@
 	string_surface_rotated.stride  = string_surface_rotated.width;
 	string_surface_rotated.format  = e->surface.format;
 	// e->surface.format is GGL_PIXEL_FORMAT_A_8 (grayscale)
-	string_surface_rotated.data = new GGLubyte[string_surface_rotated.stride * string_surface_rotated.height * 1];
-	surface_ROTATION_transform((gr_surface) &string_surface_rotated, (const gr_surface) &e->surface, 1);
+ 	string_surface_rotated.data    = (GGLubyte*) malloc(string_surface_rotated.stride * string_surface_rotated.height * 1);
+ 	surface_ROTATION_transform((gr_surface) &string_surface_rotated, (const gr_surface) &e->surface, 1);
 #endif
 
 	int y_bottom = y + e->surface.height;
@@ -631,10 +626,9 @@
 	gl->disable(gl, GGL_TEXTURE_2D);
 
 #if TW_ROTATION != 0
-	delete [] string_surface_rotated.data;
+	free(string_surface_rotated.data);
 #endif
-
-	pthread_mutex_unlock(&font->mutex);
+	pthread_mutex_unlock(&font->mutex);;
 	return res;
 }
 
diff --git a/minuitwrp/truetype.hpp b/minuitwrp/truetype.hpp
index e0d7a2f..3ae2090 100755
--- a/minuitwrp/truetype.hpp
+++ b/minuitwrp/truetype.hpp
@@ -1,121 +1,118 @@
-/*

-		Copyright 2013 to 2020 TeamWin

-		TWRP is free software: you can redistribute it and/or modify

-		it under the terms of the GNU General Public License as published by

-		the Free Software Foundation, either version 3 of the License, or

-		(at your option) any later version.

-

-		TWRP is distributed in the hope that it will be useful,

-		but WITHOUT ANY WARRANTY; without even the implied warranty of

-		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

-		GNU General Public License for more details.

-

-		You should have received a copy of the GNU General Public License

-		along with TWRP.  If not, see <http://www.gnu.org/licenses/>.

-*/

-

-#ifndef _TWRP_TRUETYPE_HPP

-#define _TWRP_TRUETYPE_HPP

-

-#include <map>

-#include <ft2build.h>

-#include FT_FREETYPE_H

-#include FT_GLYPH_H

-#include <pixelflinger/pixelflinger.h>

-#include "minui.h"

-

-struct TrueTypeFontKey {

-    int size;

-    int dpi;

-    char *path;

-

-    bool operator<(const TrueTypeFontKey &ttfk) const {

-        return size < ttfk.size || (size == ttfk.size && dpi < ttfk.dpi) || (size == ttfk.size && dpi == ttfk.dpi 

-        && std::strcmp(path, ttfk.path) < 0) || (size == ttfk.size && std::strcmp(path, ttfk.path) > 0);

-    }

-};

-

-typedef struct TrueTypeFontKey TrueTypeFontKey;

-

-typedef struct {

-    FT_BBox bbox;

-    FT_BitmapGlyph glyph;

-} TrueTypeCacheEntry;

-

-struct StringCacheKey {

-    char *text;

-    int max_width;

-

-    bool operator<(const StringCacheKey &sck) const {

-        return max_width < sck.max_width || (max_width == sck.max_width 

-        && std::strcmp(text, sck.text) < 0) || (max_width == sck.max_width && std::strcmp(text, sck.text) > 0);

-    }

-};

-

-typedef struct StringCacheKey StringCacheKey;

-

-typedef struct StringCacheEntry {

-    GGLSurface surface;

-    int rendered_bytes; // number of bytes from C string rendered, not number of UTF8 characters!

-    StringCacheKey *key;

-} StringCacheEntry;

-

-typedef struct {

-    int type;

-    int refcount;

-    int size;

-    int dpi;

-    int max_height;

-    int base;

-    FT_Face face;

-    std::map<int, TrueTypeCacheEntry*> glyph_cache;

-    std::map<StringCacheKey, StringCacheEntry*> string_cache;

-    pthread_mutex_t mutex;

-    TrueTypeFontKey *key;

-} TrueTypeFont;

-

-typedef struct {

-    FT_Library ft_library;

-    std::map<TrueTypeFontKey, TrueTypeFont*> fonts;

-    pthread_mutex_t mutex;

-} FontData;

-

-typedef std::map<StringCacheKey, StringCacheEntry*> StringCacheMap;

-typedef std::map<int, TrueTypeCacheEntry*> TrueTypeCacheEntryMap;

-typedef std::map<TrueTypeFontKey, TrueTypeFont*> TrueTypeFontMap;

-

-#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;

-

-#define STRING_CACHE_MAX_ENTRIES 400

-#define STRING_CACHE_TRUNCATE_ENTRIES 150

-

-class twrpTruetype {

-public:

-    twrpTruetype();

-    static int utf8_to_unicode(const char* pIn, unsigned int *pOut);

-    static void* gr_ttf_loadFont(const char *filename, int size, int dpi);

-    static void* gr_ttf_scaleFont(void *font, int max_width, int measured_width);

-    static bool gr_ttf_freeStringCache(void *key, void *value, void *context __unused);

-    static void gr_ttf_freeFont(void *font);

-    static TrueTypeCacheEntry* gr_ttf_glyph_cache_peek(TrueTypeFont *font, int char_index);

-    static TrueTypeCacheEntry* gr_ttf_glyph_cache_get(TrueTypeFont *font, int char_index);

-    static int gr_ttf_copy_glyph_to_surface(GGLSurface *dest, FT_BitmapGlyph glyph, int offX, int offY, int base);

-    static void gr_ttf_calcMaxFontHeight(TrueTypeFont *f);

-    static int gr_ttf_render_text(TrueTypeFont *font, GGLSurface *surface, const char *text, int max_width);

-    static StringCacheEntry* gr_ttf_string_cache_peek(TrueTypeFont *font, const char *text, __attribute__((unused)) int max_width);

-    static StringCacheEntry* gr_ttf_string_cache_get(TrueTypeFont *font, const char *text, int max_width);

-    static int gr_ttf_measureEx(const char *s, void *font);

-    static int gr_ttf_maxExW(const char *s, void *font, int max_width);

-    static int gr_ttf_textExWH(void *context, int x, int y,

-                    const char *s, void *pFont,

-                    int max_width, int max_height,

-                    const gr_surface gr_draw_surface);

-    static int gr_ttf_getMaxFontHeight(void *font);

-};

-#endif // _TWRP_TRUETYPE_HPP

+/*
+		Copyright 2013 to 2020 TeamWin
+		TWRP is free software: you can redistribute it and/or modify
+		it under the terms of the GNU General Public License as published by
+		the Free Software Foundation, either version 3 of the License, or
+		(at your option) any later version.
+
+		TWRP is distributed in the hope that it will be useful,
+		but WITHOUT ANY WARRANTY; without even the implied warranty of
+		MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+		GNU General Public License for more details.
+
+		You should have received a copy of the GNU General Public License
+		along with TWRP.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _TWRP_TRUETYPE_HPP
+#define _TWRP_TRUETYPE_HPP
+
+#include <map>
+#include <string>
+#include <ft2build.h>
+#include <pthread.h>
+#include FT_FREETYPE_H
+#include FT_GLYPH_H
+#include <pixelflinger/pixelflinger.h>
+#include "minui.h"
+
+typedef struct TrueTypeFontKey {
+    int size;
+    int dpi;
+    char *path;
+} TrueTypeFontKey;
+
+inline bool operator<(const TrueTypeFontKey &ttfkLeft, const TrueTypeFontKey &ttfkRight) {
+    return std::tie(ttfkLeft.size, ttfkLeft.dpi, *ttfkLeft.path) < std::tie(ttfkRight.size, ttfkRight.dpi, *ttfkRight.path);
+}
+
+typedef struct {
+    FT_BBox bbox;
+    FT_BitmapGlyph glyph;
+} TrueTypeCacheEntry;
+
+typedef struct StringCacheKey {
+    int max_width;
+    std::string text;
+} StringCacheKey;
+
+inline bool operator<(const StringCacheKey &sckLeft, const StringCacheKey &sckRight)  {
+    return std::tie(sckLeft.text, sckLeft.max_width) < std::tie(sckRight.text, sckRight.max_width);
+}
+
+typedef struct StringCacheEntry {
+    GGLSurface surface;
+    int rendered_bytes; // number of bytes from C string rendered, not number of UTF8 characters!
+    StringCacheKey *key;
+} StringCacheEntry;
+
+typedef struct {
+    int type;
+    int refcount;
+    int size;
+    int dpi;
+    int max_height;
+    int base;
+    FT_Face face;
+    std::map<int, TrueTypeCacheEntry*> glyph_cache;
+    std::map<StringCacheKey, StringCacheEntry*> string_cache;
+    pthread_mutex_t mutex;
+    TrueTypeFontKey *key;
+} TrueTypeFont;
+
+typedef struct {
+    FT_Library ft_library;
+    std::map<TrueTypeFontKey, TrueTypeFont*> fonts;
+    pthread_mutex_t mutex;
+} FontData;
+
+typedef std::map<StringCacheKey, StringCacheEntry*> StringCacheMap;
+typedef std::map<int, TrueTypeCacheEntry*> TrueTypeCacheEntryMap;
+typedef std::map<TrueTypeFontKey, TrueTypeFont*> TrueTypeFontMap;
+
+#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;
+
+#define STRING_CACHE_MAX_ENTRIES 400
+#define STRING_CACHE_TRUNCATE_ENTRIES 150
+
+class twrpTruetype {
+public:
+    twrpTruetype();
+    static int utf8_to_unicode(const char* pIn, unsigned int *pOut);
+    static void* gr_ttf_loadFont(const char *filename, int size, int dpi);
+    static void* gr_ttf_scaleFont(void *font, int max_width, int measured_width);
+    static void gr_ttf_freeStringCache(void *key, void *value, void *context __unused);
+    static void gr_ttf_freeFont(void *font);
+    static TrueTypeCacheEntry* gr_ttf_glyph_cache_peek(TrueTypeFont *font, int char_index);
+    static TrueTypeCacheEntry* gr_ttf_glyph_cache_get(TrueTypeFont *font, int char_index);
+    static int gr_ttf_copy_glyph_to_surface(GGLSurface *dest, FT_BitmapGlyph glyph, int offX, int offY, int base);
+    static void gr_ttf_calcMaxFontHeight(TrueTypeFont *f);
+    static int gr_ttf_render_text(TrueTypeFont *font, GGLSurface *surface, const std::string text, int max_width);
+    static StringCacheEntry* gr_ttf_string_cache_peek(TrueTypeFont *font, const std::string text, __attribute__((unused)) int max_width);
+    static StringCacheEntry* gr_ttf_string_cache_get(TrueTypeFont *font, const std::string text, int max_width);
+    static int gr_ttf_measureEx(const char *s, void *font);
+    static int gr_ttf_maxExW(const char *s, void *font, int max_width);
+    static int gr_ttf_textExWH(void *context, int x, int y,
+                    const char *s, void *pFont,
+                    int max_width, int max_height,
+                    const gr_surface gr_draw_surface);
+    static int gr_ttf_getMaxFontHeight(void *font);
+    static void gr_ttf_string_cache_truncate(TrueTypeFont *font);
+};
+#endif // _TWRP_TRUETYPE_HPP