【问题标题】:Where do I point my freetype font loader to?我应该将我的 freetype 字体加载器指向哪里?
【发布时间】:2016-06-30 15:10:03
【问题描述】:

我已成功将我的字体放到我的 apk 的 assets/ 文件夹中的 apk 上。我目前正在尝试让 Freetype 库查看文件夹中的 Arial.ttf,但找不到它。

APK 结构:

apk/
    AndroidManifest.xml
    assets/
        Arial.ttf
    classes.dex
    lib/
    META-INF/
    res/
    resources.arsc

加载字体:

FT_Face face;
if (FT_New_Face(ft, "/assets/Arial.ttf", 0, &face)) // TODO: get font locally
    __android_log_print(ANDROID_LOG_INFO, "SetupGlyphs", "ERROR::FREETYPE: Failed to load font.");

【问题讨论】:

    标签: android android-ndk freetype freetype2


    【解决方案1】:

    资产是开发机器上的文件。它们是设备上的文件。它们是 APK 的 ZIP 存档中的条目。

    在 Java 代码中(很可能),您需要将资产(从 AssetManager)复制到文件系统上的本地文件,然后让您的本机代码使用该本地文件系统副本。

    例如,此活动将 PDF 从资产复制到内部存储,以便能够使用 FileProvider 和第三方 PDF 查看器查看它:

    /***
      Copyright (c) 2013 CommonsWare, LLC
      Licensed under the Apache License, Version 2.0 (the "License"); you may not
      use this file except in compliance with the License. You may obtain a copy
      of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
      by applicable law or agreed to in writing, software distributed under the
      License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
      OF ANY KIND, either express or implied. See the License for the specific
      language governing permissions and limitations under the License.
    
      From _The Busy Coder's Guide to Android Development_
        https://commonsware.com/Android
     */
    
    package com.commonsware.android.cp.v4file;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.content.res.AssetManager;
    import android.os.Bundle;
    import android.support.v4.content.FileProvider;
    import android.util.Log;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    public class FilesCPDemo extends Activity {
      private static final String AUTHORITY="com.commonsware.android.cp.v4file";
    
      @Override
      public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
    
        File f=new File(getFilesDir(), "test.pdf");
    
        if (!f.exists()) {
          AssetManager assets=getResources().getAssets();
    
          try {
            copy(assets.open("test.pdf"), f);
          }
          catch (IOException e) {
            Log.e("FileProvider", "Exception copying from assets", e);
          }
        }
    
        Intent i=
            new Intent(Intent.ACTION_VIEW,
                       FileProvider.getUriForFile(this, AUTHORITY, f));
    
        i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivity(i);
        finish();
      }
    
      static private void copy(InputStream in, File dst) throws IOException {
        FileOutputStream out=new FileOutputStream(dst);
        byte[] buf=new byte[1024];
        int len;
    
        while ((len=in.read(buf)) > 0) {
          out.write(buf, 0, len);
        }
    
        in.close();
        out.close();
      }
    }
    

    在您的情况下,您应该在启动需要该字体的 JNI 代码之前完成这项工作。而且,由于路径可能因设备或用户而异,请将字体路径传递给您的 JNI 代码,而不是尝试在 C/C++ 中对其进行硬编码。

    【讨论】:

    • 所以,我已经在清单中设置了 FileProvider 数据,但是在查找我的确切文件时遇到了一些问题。我使用new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "Arial.ttf"); 来尝试查找字体,但这不起作用,当我将assets/ 添加到第一个参数时也不起作用。我的路径还包括<external-path name="assets" path="assets/"/>,这可能是问题,我不知道。我应该在哪里寻找字体文件?
    • @iHowell:“我已经在清单中设置了 FileProvider 数据”——这对于我的示例应用程序来说更是如此。大多数情况下,我指出我如何查看我是否已经在onCreate() 中拥有该文件,如果没有,我从资产中copy() 它。您不需要FileProvider,但我的示例应用程序需要。 “我应该在哪里寻找字体文件?” - 无论您将其复制到何处。就我而言,它是getFilesDir() 中的一个文件,正如您在onCreate() 方法中看到的那样。
    • 当我说,我应该在哪里寻找它时,我的意思是我找不到原始资产。我的资产文件夹中的那个。我收到 java.io.FileNotFoundException: /storage/emulated/0/Arial.ttf: open failed: EACCES (Permission denied) 错误。
    • @iHowell:那File 指向external storage,你需要WRITE_EXTERNAL_STORAGE 权限,并处理Android 6.0 的运行时权限。这就是为什么我的示例应用使用了getFilesDir(),即internal storage,并且不需要任何权限。
    • 哦。我认为getFilesDir() 是您在示例中的其他地方实现的方法。谢谢。
    猜你喜欢
    • 2010-12-06
    • 2015-03-06
    • 1970-01-01
    • 2012-07-09
    • 2017-03-30
    • 2010-09-19
    • 2015-03-11
    • 2017-05-11
    • 2020-12-29
    相关资源
    最近更新 更多