199 public static Typeface createFromFile(File path) {
200 return createFromFile(path.getAbsolutePath());
201 }
374 public String getAbsolutePath() {
375 if (isAbsolute()) {
376 return path;
377 }
378 String userDir = System.getProperty("user.dir");
379 return path.isEmpty() ? userDir : join(userDir, path);
380 }
209 public static Typeface createFromFile(String path) {
210 if (sFallbackFonts != null) {
211 FontFamily fontFamily = new FontFamily();
212 if (fontFamily.addFont(path)) {
213 FontFamily[] families = { fontFamily };
214 return createFromFamiliesWithDefault(families);
215 }
216 }
217 throw new RuntimeException("Font not found " + path);
218 }
241 public static Typeface createFromFamiliesWithDefault(FontFamily[] families) {
242 long[] ptrArray = new long[families.length + sFallbackFonts.length];
243 for (int i = 0; i < families.length; i++) {
244 ptrArray[i] = families[i].mNativePtr;
245 }
246 for (int i = 0; i < sFallbackFonts.length; i++) {
247 ptrArray[i + families.length] = sFallbackFonts[i].mNativePtr;
248 }
249 return new Typeface(nativeCreateFromArray(ptrArray));
250 }
77 { "nativeCreateFromArray", "([J)J", (void*)Typeface_createFromArray },
60 static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray) {
61 ScopedLongArrayRO families(env, familyArray);
62 return reinterpret_cast<jlong>(TypefaceImpl_createFromFamilies(families.get(), families.size()));
63 }
64
22
23
24
25
137 TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size) {
138 std::vector<FontFamily *>familyVec;
139 for (size_t i = 0; i < size; i++) {
140 FontFamily* family = reinterpret_cast<FontFamily*>(families[i]);
141 familyVec.push_back(family);
142 }
143 TypefaceImpl* result = new TypefaceImpl;
144 result->fFontCollection = new FontCollection(familyVec); <=====
145 if (size == 0) {
146 ALOGW("createFromFamilies creating empty collection");
147 result->fSkiaStyle = SkTypeface::kNormal;
148 } else {
149 const FontStyle defaultStyle;
150 FontFamily* firstFamily = reinterpret_cast<FontFamily*>(families[0]);
151 MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle).font;
152 if (mf != NULL) {
153 SkTypeface* skTypeface = reinterpret_cast<MinikinFontSkia*>(mf)->GetSkTypeface();
154 TODO
155
156 result->fSkiaStyle = skTypeface->style();
157 } else {
158 result->fSkiaStyle = SkTypeface::kNormal;
159 }
160 }
161 result->fBaseWeight = 400;
162 resolveStyle(result);
163 return result;
164 }
40 FontCollection::FontCollection(const vector<FontFamily*>& typefaces) :
41 mMaxChar(0) {
42 AutoMutex _l(gMinikinLock);
43 mId = sNextId++;
44 vector<uint32_t> lastChar;
45 size_t nTypefaces = typefaces.size();
46 #ifdef VERBOSE_DEBUG
47 ALOGD("nTypefaces = %d\n", nTypefaces);
48 #endif
49 const FontStyle defaultStyle;
50 for (size_t i = 0; i < nTypefaces; i++) {
51 FontFamily* family = typefaces[i];
52 MinikinFont* typeface = family->getClosestMatch(defaultStyle).font;
53 if (typeface == NULL) {
54 continue;
55 }
56 family->RefLocked();
57 FontInstance dummy;
58 mInstances.push_back(dummy);
59 FontInstance* instance = &mInstances.back();
60 instance->mFamily = family;
61 instance->mCoverage = new SparseBitSet;
62 #ifdef VERBOSE_DEBUG
63 ALOGD("closest match = %p, family size = %d\n", typeface, family->getNumFonts());
64 #endif
65 const uint32_t cmapTag = MinikinFont::MakeTag('c', 'm', 'a', 'p');
66 size_t cmapSize = 0;
67 bool ok = typeface->GetTable(cmapTag, NULL, &cmapSize);
68 UniquePtr<uint8_t[]> cmapData(new uint8_t[cmapSize]);
69 ok = typeface->GetTable(cmapTag, cmapData.get(), &cmapSize);
70 CmapCoverage::getCoverage(*instance->mCoverage, cmapData.get(), cmapSize);
71 #ifdef VERBOSE_DEBUG
72 ALOGD("font coverage length=%d, first ch=%x\n", instance->mCoverage->length(),
73 instance->mCoverage->nextSetBit(0));
74 #endif
75 mMaxChar = max(mMaxChar, instance->mCoverage->length());
76 lastChar.push_back(instance->mCoverage->nextSetBit(0));
77 }
78 nTypefaces = mInstances.size();
79 LOG_ALWAYS_FATAL_IF(nTypefaces == 0,
80 "Font collection must have at least one valid typeface");
81 size_t nPages = (mMaxChar + kPageMask) >> kLogCharsPerPage;
82 size_t offset = 0;
83 for (size_t i = 0; i < nPages; i++) {
84 Range dummy;
85 mRanges.push_back(dummy);
86 Range* range = &mRanges.back();
87 #ifdef VERBOSE_DEBUG
88 ALOGD("i=%d: range start = %d\n", i, offset);
89 #endif
90 range->start = offset;
91 for (size_t j = 0; j < nTypefaces; j++) {
92 if (lastChar[j] < (i + 1) << kLogCharsPerPage) {
93 const FontInstance* instance = &mInstances[j];
94 mInstanceVec.push_back(instance);
95 offset++;
96 uint32_t nextChar = instance->mCoverage->nextSetBit((i + 1) << kLogCharsPerPage);
97 #ifdef VERBOSE_DEBUG
98 ALOGD("nextChar = %d (j = %d)\n", nextChar, j);
99 #endif
100 lastChar[j] = nextChar;
101 }
102 }
103 range->end = offset;
104 }
105 }
106