1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.graphics.fonts; 18 19 import com.android.ide.common.rendering.api.LayoutLog; 20 import com.android.layoutlib.bridge.Bridge; 21 import com.android.layoutlib.bridge.impl.DelegateManager; 22 import com.android.tools.layoutlib.annotations.LayoutlibDelegate; 23 24 import android.annotation.NonNull; 25 import android.content.res.AssetManager; 26 27 import java.io.File; 28 import java.io.IOException; 29 import java.nio.ByteBuffer; 30 import java.nio.file.Files; 31 32 import libcore.util.NativeAllocationRegistry_Delegate; 33 34 /** 35 * Delegate implementing the native methods of android.graphics.fonts.Font$Builder 36 * <p> 37 * Through the layoutlib_create tool, the original native methods of Font$Builder have been 38 * replaced by calls to methods of the same name in this delegate class. 39 * <p> 40 * This class behaves like the original native implementation, but in Java, keeping previously 41 * native data into its own objects and mapping them to int that are sent back and forth between it 42 * and the original Font$Builder class. 43 * 44 * @see DelegateManager 45 */ 46 public class Font_Builder_Delegate { 47 protected static final DelegateManager<Font_Builder_Delegate> sBuilderManager = 48 new DelegateManager<>(Font_Builder_Delegate.class); 49 private static final DelegateManager<String> sAssetManager = 50 new DelegateManager<>(String.class); 51 private static long sFontFinalizer = -1; 52 private static long sAssetFinalizer = -1; 53 54 protected ByteBuffer mBuffer; 55 protected int mWeight; 56 protected boolean mItalic; 57 protected int mTtcIndex; 58 protected String filePath; 59 60 @LayoutlibDelegate nInitBuilder()61 /*package*/ static long nInitBuilder() { 62 return sBuilderManager.addNewDelegate(new Font_Builder_Delegate()); 63 } 64 65 @LayoutlibDelegate nGetNativeAsset( @onNull AssetManager am, @NonNull String path, boolean isAsset, int cookie)66 /*package*/ static long nGetNativeAsset( 67 @NonNull AssetManager am, @NonNull String path, boolean isAsset, int cookie) { 68 return sAssetManager.addNewDelegate(path); 69 } 70 71 @LayoutlibDelegate nGetAssetBuffer(long nativeAsset)72 /*package*/ static ByteBuffer nGetAssetBuffer(long nativeAsset) { 73 String fullPath = sAssetManager.getDelegate(nativeAsset); 74 if (fullPath == null) { 75 return null; 76 } 77 try { 78 byte[] byteArray = Files.readAllBytes(new File(fullPath).toPath()); 79 return ByteBuffer.wrap(byteArray); 80 } catch (IOException e) { 81 Bridge.getLog().error(LayoutLog.TAG_MISSING_ASSET, 82 "Error mapping font file " + fullPath, null, null, null); 83 return null; 84 } 85 } 86 87 @LayoutlibDelegate nGetReleaseNativeAssetFunc()88 /*package*/ static long nGetReleaseNativeAssetFunc() { 89 synchronized (Font_Builder_Delegate.class) { 90 if (sAssetFinalizer == -1) { 91 sAssetFinalizer = NativeAllocationRegistry_Delegate.createFinalizer( 92 sAssetManager::removeJavaReferenceFor); 93 } 94 } 95 return sAssetFinalizer; 96 } 97 98 @LayoutlibDelegate nAddAxis(long builderPtr, int tag, float value)99 /*package*/ static void nAddAxis(long builderPtr, int tag, float value) { 100 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, 101 "Font$Builder.nAddAxis is not supported.", null, null, null); 102 } 103 104 @LayoutlibDelegate nBuild(long builderPtr, ByteBuffer buffer, String filePath, int weight, boolean italic, int ttcIndex)105 /*package*/ static long nBuild(long builderPtr, ByteBuffer buffer, String filePath, int weight, 106 boolean italic, int ttcIndex) { 107 Font_Builder_Delegate font = sBuilderManager.getDelegate(builderPtr); 108 if (font != null) { 109 font.mBuffer = buffer; 110 font.mWeight = weight; 111 font.mItalic = italic; 112 font.mTtcIndex = ttcIndex; 113 font.filePath = filePath; 114 } 115 return builderPtr; 116 } 117 118 @LayoutlibDelegate nGetReleaseNativeFont()119 /*package*/ static long nGetReleaseNativeFont() { 120 synchronized (Font_Builder_Delegate.class) { 121 if (sFontFinalizer == -1) { 122 sFontFinalizer = NativeAllocationRegistry_Delegate.createFinalizer( 123 sBuilderManager::removeJavaReferenceFor); 124 } 125 } 126 return sFontFinalizer; 127 } 128 } 129