TypefaceImpl.cpp revision 1a73f732f91e97c9c66b808c245ddda36a10e987
1a033630e805c407080221e20b236b6054f324670Raph Levien/* 2a033630e805c407080221e20b236b6054f324670Raph Levien * Copyright (C) 2013 The Android Open Source Project 3a033630e805c407080221e20b236b6054f324670Raph Levien * 4a033630e805c407080221e20b236b6054f324670Raph Levien * Licensed under the Apache License, Version 2.0 (the "License"); 5a033630e805c407080221e20b236b6054f324670Raph Levien * you may not use this file except in compliance with the License. 6a033630e805c407080221e20b236b6054f324670Raph Levien * You may obtain a copy of the License at 7a033630e805c407080221e20b236b6054f324670Raph Levien * 8a033630e805c407080221e20b236b6054f324670Raph Levien * http://www.apache.org/licenses/LICENSE-2.0 9a033630e805c407080221e20b236b6054f324670Raph Levien * 10a033630e805c407080221e20b236b6054f324670Raph Levien * Unless required by applicable law or agreed to in writing, software 11a033630e805c407080221e20b236b6054f324670Raph Levien * distributed under the License is distributed on an "AS IS" BASIS, 12a033630e805c407080221e20b236b6054f324670Raph Levien * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a033630e805c407080221e20b236b6054f324670Raph Levien * See the License for the specific language governing permissions and 14a033630e805c407080221e20b236b6054f324670Raph Levien * limitations under the License. 15a033630e805c407080221e20b236b6054f324670Raph Levien */ 16a033630e805c407080221e20b236b6054f324670Raph Levien 17a033630e805c407080221e20b236b6054f324670Raph Levien/** 18a033630e805c407080221e20b236b6054f324670Raph Levien * This is the implementation of the Typeface object. Historically, it has 19a033630e805c407080221e20b236b6054f324670Raph Levien * just been SkTypeface, but we are migrating to Minikin. For the time 20a033630e805c407080221e20b236b6054f324670Raph Levien * being, that choice is hidden under the USE_MINIKIN compile-time flag. 21a033630e805c407080221e20b236b6054f324670Raph Levien */ 22a033630e805c407080221e20b236b6054f324670Raph Levien 231a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#define LOG_TAG "TypefaceImpl" 241a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 251a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien#include "jni.h" // for jlong, remove when being passed proper type 261a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 27a033630e805c407080221e20b236b6054f324670Raph Levien#include "SkStream.h" 28a033630e805c407080221e20b236b6054f324670Raph Levien#include "SkTypeface.h" 29a033630e805c407080221e20b236b6054f324670Raph Levien 30a033630e805c407080221e20b236b6054f324670Raph Levien#ifdef USE_MINIKIN 31a033630e805c407080221e20b236b6054f324670Raph Levien#include <vector> 32a033630e805c407080221e20b236b6054f324670Raph Levien#include <minikin/FontCollection.h> 33a033630e805c407080221e20b236b6054f324670Raph Levien#include <minikin/FontFamily.h> 34a033630e805c407080221e20b236b6054f324670Raph Levien#include <minikin/Layout.h> 35a033630e805c407080221e20b236b6054f324670Raph Levien#include "MinikinSkia.h" 36a033630e805c407080221e20b236b6054f324670Raph Levien#endif 37a033630e805c407080221e20b236b6054f324670Raph Levien 38a033630e805c407080221e20b236b6054f324670Raph Levien#include "TypefaceImpl.h" 39b9c58ab617c257dbece105167b21e94faad67320Leon Scroggins III#include "Utils.h" 40a033630e805c407080221e20b236b6054f324670Raph Levien 41a033630e805c407080221e20b236b6054f324670Raph Leviennamespace android { 42a033630e805c407080221e20b236b6054f324670Raph Levien 43a033630e805c407080221e20b236b6054f324670Raph Levien#ifdef USE_MINIKIN 44a033630e805c407080221e20b236b6054f324670Raph Levien 45a033630e805c407080221e20b236b6054f324670Raph Levien// Any weight greater than or equal to this is considered "bold" for 46a033630e805c407080221e20b236b6054f324670Raph Levien// legacy API. 47a033630e805c407080221e20b236b6054f324670Raph Levienstatic const int kBoldThreshold = 6; 48a033630e805c407080221e20b236b6054f324670Raph Levien 49a033630e805c407080221e20b236b6054f324670Raph Levienstatic FontStyle styleFromSkiaStyle(SkTypeface::Style skiaStyle) { 50a033630e805c407080221e20b236b6054f324670Raph Levien int weight = (skiaStyle & SkTypeface::kBold) != 0 ? 7 : 4; 51a033630e805c407080221e20b236b6054f324670Raph Levien bool italic = (skiaStyle & SkTypeface::kItalic) != 0; 52a033630e805c407080221e20b236b6054f324670Raph Levien return FontStyle(weight, italic); 53a033630e805c407080221e20b236b6054f324670Raph Levien} 54a033630e805c407080221e20b236b6054f324670Raph Levien 55a033630e805c407080221e20b236b6054f324670Raph LevienTypefaceImpl* gDefaultTypeface; 56a033630e805c407080221e20b236b6054f324670Raph Levienpthread_once_t gDefaultTypefaceOnce = PTHREAD_ONCE_INIT; 57a033630e805c407080221e20b236b6054f324670Raph Levien 58a033630e805c407080221e20b236b6054f324670Raph Levien// TODO: this currently builds a font collection from hardcoded paths. 59a033630e805c407080221e20b236b6054f324670Raph Levien// It will get replaced by an implementation that parses the XML files. 60a033630e805c407080221e20b236b6054f324670Raph Levienstatic FontCollection *makeFontCollection() { 61a033630e805c407080221e20b236b6054f324670Raph Levien std::vector<FontFamily *>typefaces; 62a033630e805c407080221e20b236b6054f324670Raph Levien const char *fns[] = { 63a033630e805c407080221e20b236b6054f324670Raph Levien "/system/fonts/Roboto-Regular.ttf", 64a033630e805c407080221e20b236b6054f324670Raph Levien "/system/fonts/Roboto-Italic.ttf", 65a033630e805c407080221e20b236b6054f324670Raph Levien "/system/fonts/Roboto-BoldItalic.ttf", 66a033630e805c407080221e20b236b6054f324670Raph Levien "/system/fonts/Roboto-Light.ttf", 67a033630e805c407080221e20b236b6054f324670Raph Levien "/system/fonts/Roboto-Thin.ttf", 68a033630e805c407080221e20b236b6054f324670Raph Levien "/system/fonts/Roboto-Bold.ttf", 69a033630e805c407080221e20b236b6054f324670Raph Levien "/system/fonts/Roboto-ThinItalic.ttf", 70a033630e805c407080221e20b236b6054f324670Raph Levien "/system/fonts/Roboto-LightItalic.ttf" 71a033630e805c407080221e20b236b6054f324670Raph Levien }; 72a033630e805c407080221e20b236b6054f324670Raph Levien 73a033630e805c407080221e20b236b6054f324670Raph Levien FontFamily *family = new FontFamily(); 74a033630e805c407080221e20b236b6054f324670Raph Levien for (size_t i = 0; i < sizeof(fns)/sizeof(fns[0]); i++) { 75a033630e805c407080221e20b236b6054f324670Raph Levien const char *fn = fns[i]; 76a033630e805c407080221e20b236b6054f324670Raph Levien SkTypeface *skFace = SkTypeface::CreateFromFile(fn); 77a033630e805c407080221e20b236b6054f324670Raph Levien MinikinFont *font = new MinikinFontSkia(skFace); 78a033630e805c407080221e20b236b6054f324670Raph Levien family->addFont(font); 79a033630e805c407080221e20b236b6054f324670Raph Levien } 80a033630e805c407080221e20b236b6054f324670Raph Levien typefaces.push_back(family); 81a033630e805c407080221e20b236b6054f324670Raph Levien 82a033630e805c407080221e20b236b6054f324670Raph Levien family = new FontFamily(); 83a033630e805c407080221e20b236b6054f324670Raph Levien const char *fn = "/system/fonts/NotoSansDevanagari-Regular.ttf"; 84a033630e805c407080221e20b236b6054f324670Raph Levien SkTypeface *skFace = SkTypeface::CreateFromFile(fn); 85a033630e805c407080221e20b236b6054f324670Raph Levien MinikinFont *font = new MinikinFontSkia(skFace); 86a033630e805c407080221e20b236b6054f324670Raph Levien family->addFont(font); 87a033630e805c407080221e20b236b6054f324670Raph Levien typefaces.push_back(family); 88a033630e805c407080221e20b236b6054f324670Raph Levien 89a033630e805c407080221e20b236b6054f324670Raph Levien return new FontCollection(typefaces); 90a033630e805c407080221e20b236b6054f324670Raph Levien} 91a033630e805c407080221e20b236b6054f324670Raph Levien 92a033630e805c407080221e20b236b6054f324670Raph Levienstatic void getDefaultTypefaceOnce() { 93a033630e805c407080221e20b236b6054f324670Raph Levien Layout::init(); 94a033630e805c407080221e20b236b6054f324670Raph Levien gDefaultTypeface = new TypefaceImpl; 95a033630e805c407080221e20b236b6054f324670Raph Levien gDefaultTypeface->fFontCollection = makeFontCollection(); 96a033630e805c407080221e20b236b6054f324670Raph Levien gDefaultTypeface->fStyle = FontStyle(); 97a033630e805c407080221e20b236b6054f324670Raph Levien} 98a033630e805c407080221e20b236b6054f324670Raph Levien 99a033630e805c407080221e20b236b6054f324670Raph LevienTypefaceImpl* TypefaceImpl_resolveDefault(TypefaceImpl* src) { 100a033630e805c407080221e20b236b6054f324670Raph Levien if (src == NULL) { 101a033630e805c407080221e20b236b6054f324670Raph Levien pthread_once(&gDefaultTypefaceOnce, getDefaultTypefaceOnce); 102a033630e805c407080221e20b236b6054f324670Raph Levien return gDefaultTypeface; 103a033630e805c407080221e20b236b6054f324670Raph Levien } else { 104a033630e805c407080221e20b236b6054f324670Raph Levien return src; 105a033630e805c407080221e20b236b6054f324670Raph Levien } 106a033630e805c407080221e20b236b6054f324670Raph Levien} 107a033630e805c407080221e20b236b6054f324670Raph Levien 108a033630e805c407080221e20b236b6054f324670Raph LevienTypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style) { 109a033630e805c407080221e20b236b6054f324670Raph Levien TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(src); 110a033630e805c407080221e20b236b6054f324670Raph Levien TypefaceImpl* result = new TypefaceImpl; 111a033630e805c407080221e20b236b6054f324670Raph Levien if (result != 0) { 112a033630e805c407080221e20b236b6054f324670Raph Levien result->fFontCollection = resolvedFace->fFontCollection; 113a033630e805c407080221e20b236b6054f324670Raph Levien result->fStyle = styleFromSkiaStyle(style); 114a033630e805c407080221e20b236b6054f324670Raph Levien } 115a033630e805c407080221e20b236b6054f324670Raph Levien return result; 116a033630e805c407080221e20b236b6054f324670Raph Levien} 117a033630e805c407080221e20b236b6054f324670Raph Levien 118a033630e805c407080221e20b236b6054f324670Raph Levienstatic TypefaceImpl* createFromSkTypeface(SkTypeface* typeface) { 119a033630e805c407080221e20b236b6054f324670Raph Levien MinikinFont* minikinFont = new MinikinFontSkia(typeface); 120a033630e805c407080221e20b236b6054f324670Raph Levien std::vector<FontFamily *> typefaces; 121a033630e805c407080221e20b236b6054f324670Raph Levien FontFamily* family = new FontFamily(); 122a033630e805c407080221e20b236b6054f324670Raph Levien family->addFont(minikinFont); 123a033630e805c407080221e20b236b6054f324670Raph Levien typefaces.push_back(family); 124a033630e805c407080221e20b236b6054f324670Raph Levien TypefaceImpl* result = new TypefaceImpl; 125a033630e805c407080221e20b236b6054f324670Raph Levien result->fFontCollection = new FontCollection(typefaces); 126a033630e805c407080221e20b236b6054f324670Raph Levien result->fStyle = FontStyle(); // TODO: improve 127a033630e805c407080221e20b236b6054f324670Raph Levien return result; 128a033630e805c407080221e20b236b6054f324670Raph Levien} 129a033630e805c407080221e20b236b6054f324670Raph Levien 130a033630e805c407080221e20b236b6054f324670Raph LevienTypefaceImpl* TypefaceImpl_createFromName(const char* name, SkTypeface::Style style) { 131a033630e805c407080221e20b236b6054f324670Raph Levien // TODO: should create a font collection with all styles corresponding to 132a033630e805c407080221e20b236b6054f324670Raph Levien // the name 133a033630e805c407080221e20b236b6054f324670Raph Levien SkTypeface* face = SkTypeface::CreateFromName(name, style); 134a033630e805c407080221e20b236b6054f324670Raph Levien return createFromSkTypeface(face); 135a033630e805c407080221e20b236b6054f324670Raph Levien} 136a033630e805c407080221e20b236b6054f324670Raph Levien 137a033630e805c407080221e20b236b6054f324670Raph LevienTypefaceImpl* TypefaceImpl_createFromFile(const char* filename) { 138a033630e805c407080221e20b236b6054f324670Raph Levien SkTypeface* face = SkTypeface::CreateFromFile(filename); 139a033630e805c407080221e20b236b6054f324670Raph Levien return createFromSkTypeface(face); 140a033630e805c407080221e20b236b6054f324670Raph Levien} 141a033630e805c407080221e20b236b6054f324670Raph Levien 142a033630e805c407080221e20b236b6054f324670Raph LevienTypefaceImpl* TypefaceImpl_createFromAsset(Asset* asset) { 143b9c58ab617c257dbece105167b21e94faad67320Leon Scroggins III SkStream* stream = new AssetStreamAdaptor(asset, 144b9c58ab617c257dbece105167b21e94faad67320Leon Scroggins III AssetStreamAdaptor::kYes_OwnAsset, 145b9c58ab617c257dbece105167b21e94faad67320Leon Scroggins III AssetStreamAdaptor::kYes_HasMemoryBase); 146a033630e805c407080221e20b236b6054f324670Raph Levien SkTypeface* face = SkTypeface::CreateFromStream(stream); 147a033630e805c407080221e20b236b6054f324670Raph Levien // SkTypeFace::CreateFromStream calls ref() on the stream, so we 148a033630e805c407080221e20b236b6054f324670Raph Levien // need to unref it here or it won't be freed later on 149a033630e805c407080221e20b236b6054f324670Raph Levien stream->unref(); 150a033630e805c407080221e20b236b6054f324670Raph Levien return createFromSkTypeface(face); 151a033630e805c407080221e20b236b6054f324670Raph Levien} 152a033630e805c407080221e20b236b6054f324670Raph Levien 1531a73f732f91e97c9c66b808c245ddda36a10e987Raph LevienTypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size) { 1541a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien ALOGD("createFromFamilies size=%d", size); 1551a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien std::vector<FontFamily *>familyVec; 1561a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien for (size_t i = 0; i < size; i++) { 1571a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien FontFamily* family = reinterpret_cast<FontFamily*>(families[i]); 1581a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien familyVec.push_back(family); 1591a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien } 1601a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien TypefaceImpl* result = new TypefaceImpl; 1611a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien result->fFontCollection = new FontCollection(familyVec); 1621a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien result->fStyle = FontStyle(); // TODO: improve 1631a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien return result; 1641a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien} 1651a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 166a033630e805c407080221e20b236b6054f324670Raph Levienvoid TypefaceImpl_unref(TypefaceImpl* face) { 167a033630e805c407080221e20b236b6054f324670Raph Levien delete face; 168a033630e805c407080221e20b236b6054f324670Raph Levien} 169a033630e805c407080221e20b236b6054f324670Raph Levien 170a033630e805c407080221e20b236b6054f324670Raph Levienint TypefaceImpl_getStyle(TypefaceImpl* face) { 171a033630e805c407080221e20b236b6054f324670Raph Levien FontStyle style = face->fStyle; 172a033630e805c407080221e20b236b6054f324670Raph Levien int result = style.getItalic() ? SkTypeface::kItalic : 0; 173a033630e805c407080221e20b236b6054f324670Raph Levien if (style.getWeight() >= kBoldThreshold) { 174a033630e805c407080221e20b236b6054f324670Raph Levien result |= SkTypeface::kBold; 175a033630e805c407080221e20b236b6054f324670Raph Levien } 176a033630e805c407080221e20b236b6054f324670Raph Levien return result; 177a033630e805c407080221e20b236b6054f324670Raph Levien} 178a033630e805c407080221e20b236b6054f324670Raph Levien 179a033630e805c407080221e20b236b6054f324670Raph Levien#else // USE_MINIKIN 180a033630e805c407080221e20b236b6054f324670Raph Levien 181a033630e805c407080221e20b236b6054f324670Raph Levien/* Just use SkTypeface instead. */ 182a033630e805c407080221e20b236b6054f324670Raph Levien 183a033630e805c407080221e20b236b6054f324670Raph Levientypedef SkTypeface TypefaceImpl; 184a033630e805c407080221e20b236b6054f324670Raph Levien 185a033630e805c407080221e20b236b6054f324670Raph LevienTypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style) { 186a033630e805c407080221e20b236b6054f324670Raph Levien return SkTypeface::CreateFromTypeface(src, style); 187a033630e805c407080221e20b236b6054f324670Raph Levien} 188a033630e805c407080221e20b236b6054f324670Raph Levien 189a033630e805c407080221e20b236b6054f324670Raph LevienTypefaceImpl* TypefaceImpl_createFromName(const char* name, SkTypeface::Style style) { 190a033630e805c407080221e20b236b6054f324670Raph Levien return SkTypeface::CreateFromName(name, style); 191a033630e805c407080221e20b236b6054f324670Raph Levien} 192a033630e805c407080221e20b236b6054f324670Raph Levien 193a033630e805c407080221e20b236b6054f324670Raph LevienTypefaceImpl* TypefaceImpl_createFromFile(const char* filename) { 194a033630e805c407080221e20b236b6054f324670Raph Levien return SkTypeface::CreateFromFile(filename); 195a033630e805c407080221e20b236b6054f324670Raph Levien} 196a033630e805c407080221e20b236b6054f324670Raph Levien 197a033630e805c407080221e20b236b6054f324670Raph LevienTypefaceImpl* TypefaceImpl_createFromAsset(Asset* asset) { 198b9c58ab617c257dbece105167b21e94faad67320Leon Scroggins III SkStream* stream = new AssetStreamAdaptor(asset, 199b9c58ab617c257dbece105167b21e94faad67320Leon Scroggins III AssetStreamAdaptor::kYes_OwnAsset, 200b9c58ab617c257dbece105167b21e94faad67320Leon Scroggins III AssetStreamAdaptor::kYes_HasMemoryBase); 201a033630e805c407080221e20b236b6054f324670Raph Levien SkTypeface* face = SkTypeface::CreateFromStream(stream); 202a033630e805c407080221e20b236b6054f324670Raph Levien // SkTypeFace::CreateFromStream calls ref() on the stream, so we 203a033630e805c407080221e20b236b6054f324670Raph Levien // need to unref it here or it won't be freed later on 204a033630e805c407080221e20b236b6054f324670Raph Levien stream->unref(); 205a033630e805c407080221e20b236b6054f324670Raph Levien 206a033630e805c407080221e20b236b6054f324670Raph Levien return face; 207a033630e805c407080221e20b236b6054f324670Raph Levien} 208a033630e805c407080221e20b236b6054f324670Raph Levien 2091a73f732f91e97c9c66b808c245ddda36a10e987Raph LevienTypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size) { 2101a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien // Should never be called in non-Minikin builds 2111a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien return 0; 2121a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien} 2131a73f732f91e97c9c66b808c245ddda36a10e987Raph Levien 214a033630e805c407080221e20b236b6054f324670Raph Levienvoid TypefaceImpl_unref(TypefaceImpl* face) { 215a033630e805c407080221e20b236b6054f324670Raph Levien SkSafeUnref(face); 216a033630e805c407080221e20b236b6054f324670Raph Levien} 217a033630e805c407080221e20b236b6054f324670Raph Levien 218a033630e805c407080221e20b236b6054f324670Raph Levienint TypefaceImpl_getStyle(TypefaceImpl* face) { 219a033630e805c407080221e20b236b6054f324670Raph Levien return face->style(); 220a033630e805c407080221e20b236b6054f324670Raph Levien} 221a033630e805c407080221e20b236b6054f324670Raph Levien 222a033630e805c407080221e20b236b6054f324670Raph Levien#endif // USE_MINIKIN 223a033630e805c407080221e20b236b6054f324670Raph Levien 224a033630e805c407080221e20b236b6054f324670Raph Levien} 225