blob: 67eb5c191899442cd98012bf8ed515066a3a67c2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package com.taobao.weex.utils;
import android.content.Intent;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.net.Uri;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import com.taobao.weex.WXEnvironment;
import com.taobao.weex.WXSDKManager;
import com.taobao.weex.adapter.IWXHttpAdapter;
import com.taobao.weex.common.WXRequest;
import com.taobao.weex.common.WXResponse;
import com.taobao.weex.dom.WXStyle;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by sospartan on 7/13/16.
*/
public class TypefaceUtil {
public static final String FONT_CACHE_DIR_NAME = "font-family";
private final static String TAG = "TypefaceUtil";
private final static Map<String, FontDO> sCacheMap = new HashMap<>(); //Key: fontFamilyName
public static final String ACTION_TYPE_FACE_AVAILABLE = "type_face_available";
public static void putFontDO(FontDO fontDO) {
if (fontDO != null && !TextUtils.isEmpty(fontDO.getFontFamilyName())) {
sCacheMap.put(fontDO.getFontFamilyName(), fontDO);
}
}
public static FontDO getFontDO(String fontFamilyName) {
return sCacheMap.get(fontFamilyName);
}
public static void applyFontStyle(Paint paint, int style, int weight, String family) {
int oldStyle;
Typeface typeface = paint.getTypeface();
if (typeface == null) {
oldStyle = 0;
} else {
oldStyle = typeface.getStyle();
}
int want = 0;
if ((weight == Typeface.BOLD)
|| ((oldStyle & Typeface.BOLD) != 0 && weight == WXStyle.UNSET)) {
want |= Typeface.BOLD;
}
if ((style == Typeface.ITALIC)
|| ((oldStyle & Typeface.ITALIC) != 0 && style == WXStyle.UNSET)) {
want |= Typeface.ITALIC;
}
if (family != null) {
typeface = getOrCreateTypeface(family, want);
}
if (typeface != null) {
paint.setTypeface(Typeface.create(typeface, want));
} else {
paint.setTypeface(Typeface.defaultFromStyle(want));
}
}
public static Typeface getOrCreateTypeface(String family, int style) {
FontDO fontDo = sCacheMap.get(family);
if (fontDo != null && fontDo.getTypeface() != null) {
return fontDo.getTypeface();
}
return Typeface.create(family, style);
}
private static void loadFromAsset(FontDO fontDo,String path){
try {
Typeface typeface = Typeface.createFromAsset(WXEnvironment.getApplication().getAssets(), path);
if (typeface != null) {
if(WXEnvironment.isApkDebugable()) {
WXLogUtils.d(TAG, "load asset file success");
}
fontDo.setState(FontDO.STATE_SUCCESS);
fontDo.setTypeface(typeface);
} else {
WXLogUtils.e(TAG, "Font asset file not found " + fontDo.getUrl());
}
} catch (Exception e) {
WXLogUtils.e(TAG, e.toString());
}
}
public static void loadTypeface(final FontDO fontDo) {
if (fontDo != null && fontDo.getTypeface() == null &&
(fontDo.getState() == FontDO.STATE_FAILED || fontDo.getState() == FontDO.STATE_INIT)) {
fontDo.setState(FontDO.STATE_LOADING);
if (fontDo.getType() == FontDO.TYPE_LOCAL) {
Uri uri = Uri.parse(fontDo.getUrl());
loadFromAsset(fontDo,uri.getPath().substring(1));//exclude slash
} else if (fontDo.getType() == FontDO.TYPE_NETWORK) {
final String url = fontDo.getUrl();
final String fontFamily = fontDo.getFontFamilyName();
final String fileName = url.replace('/', '_').replace(':', '_');
File dir = new File(getFontCacheDir());
if(!dir.exists()){
dir.mkdirs();
}
final String fullPath = dir.getAbsolutePath()+ File.separator +fileName;
if (!loadLocalFontFile(fullPath, fontFamily)) {
downloadFontByNetwork(url, fullPath, fontFamily);
}
} else if (fontDo.getType() == FontDO.TYPE_FILE) {
boolean result = loadLocalFontFile(fontDo.getUrl(), fontDo.getFontFamilyName());
if (!result) {
fontDo.setState(FontDO.STATE_FAILED);
}
}
}
}
private static void downloadFontByNetwork(final String url, final String fullPath, final String fontFamily) {
IWXHttpAdapter adapter = WXSDKManager.getInstance().getIWXHttpAdapter();
if (adapter == null) {
WXLogUtils.e(TAG, "downloadFontByNetwork() IWXHttpAdapter == null");
return;
}
WXRequest request = new WXRequest();
request.url = url;
request.method = "GET";
adapter.sendRequest(request, new IWXHttpAdapter.OnHttpListener() {
@Override
public void onHttpStart() {
if(WXEnvironment.isApkDebugable()) {
WXLogUtils.d(TAG, "downloadFontByNetwork begin url:" + url);
}
}
@Override
public void onHeadersReceived(int statusCode, Map<String, List<String>> headers) {
}
@Override
public void onHttpUploadProgress(int uploadProgress) {
}
@Override
public void onHttpResponseProgress(int loadedLength) {
}
@Override
public void onHttpFinish(WXResponse response) {
int statusCode = 0;
if (!TextUtils.isEmpty(response.statusCode)) {
try {
statusCode = Integer.parseInt(response.statusCode);
} catch (NumberFormatException e) {
statusCode = 0;
WXLogUtils.e(TAG, "IWXHttpAdapter onHttpFinish statusCode:" + response.statusCode);
}
}
boolean result;
if (statusCode >= 200 && statusCode <= 299 && response.originalData != null) {
result = WXFileUtils.saveFile(fullPath, response.originalData, WXEnvironment.getApplication());
if (result) {
result = loadLocalFontFile(fullPath, fontFamily);
} else {
if(WXEnvironment.isApkDebugable()) {
WXLogUtils.d(TAG, "downloadFontByNetwork() onHttpFinish success, but save file failed.");
}
}
} else {
result = false;
}
if (!result) {
FontDO fontDO = sCacheMap.get(fontFamily);
if (fontDO != null) {
fontDO.setState(FontDO.STATE_FAILED);
}
}
}
});
}
private static boolean loadLocalFontFile(String path, String fontFamily) {
if (TextUtils.isEmpty(path) || TextUtils.isEmpty(fontFamily)) {
return false;
}
try {
File file = new File(path);
if (!file.exists()) {
return false;
}
Typeface typeface = Typeface.createFromFile(path);
if (typeface != null) {
FontDO fontDo = sCacheMap.get(fontFamily);
if (fontDo != null) {
fontDo.setState(FontDO.STATE_SUCCESS);
fontDo.setTypeface(typeface);
if(WXEnvironment.isApkDebugable()) {
WXLogUtils.d(TAG, "load local font file success");
}
Intent intent = new Intent(ACTION_TYPE_FACE_AVAILABLE);
intent.putExtra("fontFamily", fontFamily);
LocalBroadcastManager.getInstance(WXEnvironment.getApplication()).sendBroadcast(intent);
return true;
}
} else {
WXLogUtils.e(TAG, "load local font file failed, can't create font.");
}
} catch (Exception e) {
WXLogUtils.e(TAG, e.toString());
}
return false;
}
private static String getFontCacheDir() {
return WXEnvironment.getDiskCacheDir(WXEnvironment.getApplication()) + "/" + FONT_CACHE_DIR_NAME;
}
}