1/*
2 * Copyright 2011 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkAdvancedTypefaceMetrics.h"
9#include "SkFontDescriptor.h"
10#include "SkFontHost.h"
11#include "SkStream.h"
12#include "SkTypeface.h"
13
14SK_DEFINE_INST_COUNT(SkTypeface)
15
16//#define TRACE_LIFECYCLE
17
18#ifdef TRACE_LIFECYCLE
19    static int32_t gTypefaceCounter;
20#endif
21
22SkTypeface::SkTypeface(Style style, SkFontID fontID, bool isFixedPitch)
23    : fUniqueID(fontID), fStyle(style), fIsFixedPitch(isFixedPitch) {
24#ifdef TRACE_LIFECYCLE
25    SkDebugf("SkTypeface: create  %p fontID %d total %d\n",
26             this, fontID, ++gTypefaceCounter);
27#endif
28}
29
30SkTypeface::~SkTypeface() {
31#ifdef TRACE_LIFECYCLE
32    SkDebugf("SkTypeface: destroy %p fontID %d total %d\n",
33             this, fUniqueID, --gTypefaceCounter);
34#endif
35}
36
37///////////////////////////////////////////////////////////////////////////////
38
39SkTypeface* SkTypeface::GetDefaultTypeface(Style style) {
40    // we keep a reference to this guy for all time, since if we return its
41    // fontID, the font cache may later on ask to resolve that back into a
42    // typeface object.
43    static const uint32_t FONT_STYLE_COUNT = 4;
44    static SkTypeface* gDefaultTypefaces[FONT_STYLE_COUNT];
45    SkASSERT((unsigned)style < FONT_STYLE_COUNT);
46
47    // mask off any other bits to avoid a crash in SK_RELEASE
48    style = (Style)(style & 0x03);
49
50    if (NULL == gDefaultTypefaces[style]) {
51        gDefaultTypefaces[style] =
52        SkFontHost::CreateTypeface(NULL, NULL, style);
53    }
54    return gDefaultTypefaces[style];
55}
56
57SkTypeface* SkTypeface::RefDefault(Style style) {
58    return SkRef(GetDefaultTypeface(style));
59}
60
61uint32_t SkTypeface::UniqueID(const SkTypeface* face) {
62    if (NULL == face) {
63        face = GetDefaultTypeface();
64    }
65    return face->uniqueID();
66}
67
68bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) {
69    return SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb);
70}
71
72///////////////////////////////////////////////////////////////////////////////
73
74SkTypeface* SkTypeface::CreateFromName(const char name[], Style style) {
75    if (NULL == name) {
76        return RefDefault(style);
77    }
78    return SkFontHost::CreateTypeface(NULL, name, style);
79}
80
81SkTypeface* SkTypeface::CreateFromTypeface(const SkTypeface* family, Style s) {
82    if (family && family->style() == s) {
83        family->ref();
84        return const_cast<SkTypeface*>(family);
85    }
86    return SkFontHost::CreateTypeface(family, NULL, s);
87}
88
89SkTypeface* SkTypeface::CreateFromStream(SkStream* stream) {
90    return SkFontHost::CreateTypefaceFromStream(stream);
91}
92
93SkTypeface* SkTypeface::CreateFromFile(const char path[]) {
94    return SkFontHost::CreateTypefaceFromFile(path);
95}
96
97///////////////////////////////////////////////////////////////////////////////
98
99void SkTypeface::serialize(SkWStream* wstream) const {
100    bool isLocal = false;
101    SkFontDescriptor desc(this->style());
102    this->onGetFontDescriptor(&desc, &isLocal);
103
104    desc.serialize(wstream);
105    if (isLocal) {
106        int ttcIndex;   // TODO: write this to the stream?
107        SkAutoTUnref<SkStream> rstream(this->openStream(&ttcIndex));
108        if (rstream.get()) {
109            size_t length = rstream->getLength();
110            wstream->writePackedUInt(length);
111            wstream->writeStream(rstream, length);
112        } else {
113            wstream->writePackedUInt(0);
114        }
115    } else {
116        wstream->writePackedUInt(0);
117    }
118}
119
120SkTypeface* SkTypeface::Deserialize(SkStream* stream) {
121    SkFontDescriptor desc(stream);
122    size_t length = stream->readPackedUInt();
123    if (length > 0) {
124        void* addr = sk_malloc_flags(length, 0);
125        if (addr) {
126            SkAutoTUnref<SkMemoryStream> localStream(SkNEW(SkMemoryStream));
127            localStream->setMemoryOwned(addr, length);
128
129            if (stream->read(addr, length) == length) {
130                return SkTypeface::CreateFromStream(localStream.get());
131            } else {
132                // Failed to read the full font data, so fall through and try to create from name.
133                // If this is because of EOF, all subsequent reads from the stream will be EOF.
134                // If this is because of a stream error, the stream is in an error state,
135                // do not attempt to skip any remaining bytes.
136            }
137        } else {
138            // failed to allocate, so just skip and create-from-name
139            stream->skip(length);
140        }
141    }
142
143    return SkTypeface::CreateFromName(desc.getFamilyName(), desc.getStyle());
144}
145
146///////////////////////////////////////////////////////////////////////////////
147
148int SkTypeface::countTables() const {
149    return this->onGetTableTags(NULL);
150}
151
152int SkTypeface::getTableTags(SkFontTableTag tags[]) const {
153    return this->onGetTableTags(tags);
154}
155
156size_t SkTypeface::getTableSize(SkFontTableTag tag) const {
157    return this->onGetTableData(tag, 0, ~0U, NULL);
158}
159
160size_t SkTypeface::getTableData(SkFontTableTag tag, size_t offset, size_t length,
161                                void* data) const {
162    return this->onGetTableData(tag, offset, length, data);
163}
164
165SkStream* SkTypeface::openStream(int* ttcIndex) const {
166    int ttcIndexStorage;
167    if (NULL == ttcIndex) {
168        // So our subclasses don't need to check for null param
169        ttcIndex = &ttcIndexStorage;
170    }
171    return this->onOpenStream(ttcIndex);
172}
173
174int SkTypeface::charsToGlyphs(const void* chars, Encoding encoding,
175                              uint16_t glyphs[], int glyphCount) const {
176    if (glyphCount <= 0) {
177        return 0;
178    }
179    if (NULL == chars || (unsigned)encoding > kUTF32_Encoding) {
180        if (glyphs) {
181            sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
182        }
183        return 0;
184    }
185    return this->onCharsToGlyphs(chars, encoding, glyphs, glyphCount);
186}
187
188int SkTypeface::countGlyphs() const {
189    return this->onCountGlyphs();
190}
191
192int SkTypeface::getUnitsPerEm() const {
193    // should we try to cache this in the base-class?
194    return this->onGetUPEM();
195}
196
197SkTypeface::LocalizedStrings* SkTypeface::createFamilyNameIterator() const {
198    return this->onCreateFamilyNameIterator();
199}
200
201void SkTypeface::getFamilyName(SkString* name) const {
202    bool isLocal = false;
203    SkFontDescriptor desc(this->style());
204    this->onGetFontDescriptor(&desc, &isLocal);
205    name->set(desc.getFamilyName());
206}
207
208SkAdvancedTypefaceMetrics* SkTypeface::getAdvancedTypefaceMetrics(
209                                SkAdvancedTypefaceMetrics::PerGlyphInfo info,
210                                const uint32_t* glyphIDs,
211                                uint32_t glyphIDsCount) const {
212    return this->onGetAdvancedTypefaceMetrics(info, glyphIDs, glyphIDsCount);
213}
214
215SkTypeface* SkTypeface::refMatchingStyle(Style style) const {
216    return this->onRefMatchingStyle(style);
217}
218
219///////////////////////////////////////////////////////////////////////////////
220///////////////////////////////////////////////////////////////////////////////
221
222int SkTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
223                                uint16_t glyphs[], int glyphCount) const {
224    SkDebugf("onCharsToGlyphs unimplemented\n");
225    if (glyphs && glyphCount > 0) {
226        sk_bzero(glyphs, glyphCount * sizeof(glyphs[0]));
227    }
228    return 0;
229}
230