上篇文章准备了opengl渲染图像的环境。这片文章要做的是把freetype加载到程序中,并可以从路径中加载字体。
编译Android平台上的freetype
https://www.cnblogs.com/freedreamnight/p/14930341.html这篇文章写的十分详细,要注意的是,他这里用的是静态库,我自己使用的是动态库,只需要删除–enable-static这个参数就行了。
集成freetype到项目中
在项目app/src/main/cpp,把头文件放入对应的目录,其实不用在意,只要在CMakeLists.txt中能找到对应的目录就行了。
修改CMakeList.txt
这里申明一个freetype的第三方库,后面在链接的时候,添加上GLESv2和EGL,还有自己的freetype。这里还有一个重要的依赖“andorid”,这个这个其实是上一篇中ANativeWindow_fromSurface函数所在的位置。
add_library(freetype SHARED IMPORTED)
set_target_properties(freetype
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/freetype/lib/android/${ANDROID_ABI}/libfreetype.so)
include_directories(
${CMAKE_SOURCE_DIR}/freetype/include )
target_link_libraries( # Specifies the target library.
native-lib
android
GLESv2 EGL
freetype
# Links the target library to the log library
# included in the NDK.
${log-lib} )
添加freetype头文件
上篇文章中忘记说头文件的事情,这里把所有依赖的头文件全部列出来。
#include <EGL/egl.h>
#include <GLES3/gl3.h>
#include <android/native_window_jni.h>
#include <android/asset_manager_jni.h>
#include <android/asset_manager.h>
#include "ft2build.h"
#include FT_FREETYPE_H
加载字体文件
在android体系中,已经不再允许读取当前app沙盒以外的文件了,所以,freetype只能从内存中读取字体,这里还是利用AssetsManager从native c++层读取文件,在kotlin中,创建以下函数,然后让ide自己创建对应的native c++函数
external fun initAsserts(assertManager: AssetManager?)
在onCreate函数中添加initAsserts的调用语句
initAsserts(getApplicationContext().resources.assets)
native c++层就可以调用freetype加载字体了,值得注意的是这里的arial.ttf,需要放在android项目中的assets目录,如果项目中没有则需要自己添加一个(不能是普通目录叫做assets,需要把目录类型改成assets)。这里arial.ttf字体文件,可以从网上下载到,或者在系统中拷贝一下就行。
AAssetManager *g_pAssetManager = AAssetManager_fromJava(env, assert_manager);
FT_Library ft;
if (FT_Init_FreeType(&ft))
printf("ERROR::FREETYPE: Could not init FreeType Library");
FT_Face face;
if(g_pAssetManager){
AAsset* fontAsset = AAssetManager_open(g_pAssetManager, "arial.ttf", AASSET_MODE_UNKNOWN);
if (fontAsset)
{
size_t assetLength = AAsset_getLength(fontAsset);
char* buffer = (char*) malloc(assetLength);
AAsset_read(fontAsset, buffer, assetLength);
AAsset_close(fontAsset);
FT_New_Memory_Face(ft,(const FT_Byte *)buffer,assetLength,0,&face);
}
}