1/*
2 * Copyright 2009 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 "SkFontLCDConfig.h"
9#include "SkOnce.h"
10
11static SkFontLCDConfig::LCDOrientation gLCDOrientation = SkFontLCDConfig::kHorizontal_LCDOrientation;
12static SkFontLCDConfig::LCDOrder gLCDOrder = SkFontLCDConfig::kRGB_LCDOrder;
13
14SkFontLCDConfig::LCDOrientation SkFontLCDConfig::GetSubpixelOrientation() {
15    return gLCDOrientation;
16}
17
18void SkFontLCDConfig::SetSubpixelOrientation(LCDOrientation orientation) {
19    gLCDOrientation = orientation;
20}
21
22SkFontLCDConfig::LCDOrder SkFontLCDConfig::GetSubpixelOrder() {
23    return gLCDOrder;
24}
25
26void SkFontLCDConfig::SetSubpixelOrder(LCDOrder order) {
27    gLCDOrder = order;
28}
29
30///////////////////////////////////////////////////////////////////////////////
31// Legacy wrappers : remove from SkFontHost when webkit switches to new API
32
33#include "SkFontHost.h"
34
35SkFontHost::LCDOrientation SkFontHost::GetSubpixelOrientation() {
36    return (SkFontHost::LCDOrientation)SkFontLCDConfig::GetSubpixelOrientation();
37}
38
39void SkFontHost::SetSubpixelOrientation(LCDOrientation orientation) {
40    SkFontLCDConfig::SetSubpixelOrientation((SkFontLCDConfig::LCDOrientation)orientation);
41}
42
43SkFontHost::LCDOrder SkFontHost::GetSubpixelOrder() {
44    return (SkFontHost::LCDOrder)SkFontLCDConfig::GetSubpixelOrder();
45}
46
47void SkFontHost::SetSubpixelOrder(LCDOrder order) {
48    SkFontLCDConfig::SetSubpixelOrder((SkFontLCDConfig::LCDOrder)order);
49}
50
51///////////////////////////////////////////////////////////////////////////////
52///////////////////////////////////////////////////////////////////////////////
53
54#include "SkFontStyle.h"
55
56SkFontStyle::SkFontStyle() {
57    fUnion.fU32 = 0;
58    fUnion.fR.fWeight = kNormal_Weight;
59    fUnion.fR.fWidth = kNormal_Width;
60    fUnion.fR.fSlant = kUpright_Slant;
61}
62
63SkFontStyle::SkFontStyle(int weight, int width, Slant slant) {
64    fUnion.fU32 = 0;
65    fUnion.fR.fWeight = SkPin32(weight, kThin_Weight, kBlack_Weight);
66    fUnion.fR.fWidth = SkPin32(width, kUltraCondensed_Width, kUltaExpanded_Width);
67    fUnion.fR.fSlant = SkPin32(slant, kUpright_Slant, kItalic_Slant);
68}
69
70#include "SkFontMgr.h"
71
72class SkEmptyFontStyleSet : public SkFontStyleSet {
73public:
74    virtual int count() SK_OVERRIDE { return 0; }
75    virtual void getStyle(int, SkFontStyle*, SkString*) SK_OVERRIDE {
76        SkDEBUGFAIL("SkFontStyleSet::getStyle called on empty set");
77    }
78    virtual SkTypeface* createTypeface(int index) SK_OVERRIDE {
79        SkDEBUGFAIL("SkFontStyleSet::createTypeface called on empty set");
80        return NULL;
81    }
82    virtual SkTypeface* matchStyle(const SkFontStyle&) SK_OVERRIDE {
83        return NULL;
84    }
85};
86
87SkFontStyleSet* SkFontStyleSet::CreateEmpty() {
88    return SkNEW(SkEmptyFontStyleSet);
89}
90
91///////////////////////////////////////////////////////////////////////////////
92
93class SkEmptyFontMgr : public SkFontMgr {
94protected:
95    virtual int onCountFamilies() SK_OVERRIDE {
96        return 0;
97    }
98    virtual void onGetFamilyName(int index, SkString* familyName) SK_OVERRIDE {
99        SkDEBUGFAIL("onGetFamilyName called with bad index");
100    }
101    virtual SkFontStyleSet* onCreateStyleSet(int index) SK_OVERRIDE {
102        SkDEBUGFAIL("onCreateStyleSet called with bad index");
103        return NULL;
104    }
105    virtual SkFontStyleSet* onMatchFamily(const char[]) SK_OVERRIDE {
106        return SkFontStyleSet::CreateEmpty();
107    }
108
109    virtual SkTypeface* onMatchFamilyStyle(const char[],
110                                           const SkFontStyle&) SK_OVERRIDE {
111        return NULL;
112    }
113    virtual SkTypeface* onMatchFaceStyle(const SkTypeface*,
114                                         const SkFontStyle&) SK_OVERRIDE {
115        return NULL;
116    }
117    virtual SkTypeface* onCreateFromData(SkData*, int) SK_OVERRIDE {
118        return NULL;
119    }
120    virtual SkTypeface* onCreateFromStream(SkStream*, int) SK_OVERRIDE {
121        return NULL;
122    }
123    virtual SkTypeface* onCreateFromFile(const char[], int) SK_OVERRIDE {
124        return NULL;
125    }
126    virtual SkTypeface* onLegacyCreateTypeface(const char [], unsigned) SK_OVERRIDE {
127        return NULL;
128    }
129};
130
131static SkFontStyleSet* emptyOnNull(SkFontStyleSet* fsset) {
132    if (NULL == fsset) {
133        fsset = SkFontStyleSet::CreateEmpty();
134    }
135    return fsset;
136}
137
138int SkFontMgr::countFamilies() {
139    return this->onCountFamilies();
140}
141
142void SkFontMgr::getFamilyName(int index, SkString* familyName) {
143    this->onGetFamilyName(index, familyName);
144}
145
146SkFontStyleSet* SkFontMgr::createStyleSet(int index) {
147    return emptyOnNull(this->onCreateStyleSet(index));
148}
149
150SkFontStyleSet* SkFontMgr::matchFamily(const char familyName[]) {
151    return emptyOnNull(this->onMatchFamily(familyName));
152}
153
154SkTypeface* SkFontMgr::matchFamilyStyle(const char familyName[],
155                                        const SkFontStyle& fs) {
156    return this->onMatchFamilyStyle(familyName, fs);
157}
158
159SkTypeface* SkFontMgr::matchFaceStyle(const SkTypeface* face,
160                                      const SkFontStyle& fs) {
161    return this->onMatchFaceStyle(face, fs);
162}
163
164SkTypeface* SkFontMgr::createFromData(SkData* data, int ttcIndex) {
165    if (NULL == data) {
166        return NULL;
167    }
168    return this->onCreateFromData(data, ttcIndex);
169}
170
171SkTypeface* SkFontMgr::createFromStream(SkStream* stream, int ttcIndex) {
172    if (NULL == stream) {
173        return NULL;
174    }
175    return this->onCreateFromStream(stream, ttcIndex);
176}
177
178SkTypeface* SkFontMgr::createFromFile(const char path[], int ttcIndex) {
179    if (NULL == path) {
180        return NULL;
181    }
182    return this->onCreateFromFile(path, ttcIndex);
183}
184
185SkTypeface* SkFontMgr::legacyCreateTypeface(const char familyName[],
186                                            unsigned styleBits) {
187    return this->onLegacyCreateTypeface(familyName, styleBits);
188}
189
190void set_up_default(SkFontMgr** singleton) {
191  *singleton = SkFontMgr::Factory();
192  // we never want to return NULL
193  if (NULL == *singleton) {
194      *singleton = SkNEW(SkEmptyFontMgr);
195  }
196}
197
198SkFontMgr* SkFontMgr::RefDefault() {
199    static SkFontMgr* gFM = NULL;
200    SK_DECLARE_STATIC_ONCE(once);
201    SkOnce(&once, set_up_default, &gFM);
202    return SkRef(gFM);
203}
204
205//////////////////////////////////////////////////////////////////////////
206
207#ifndef SK_FONTHOST_DOES_NOT_USE_FONTMGR
208
209#if 0
210static SkFontStyle TypefaceStyleBitsToFontStyle(SkTypeface::Style styleBits) {
211    SkFontStyle::Weight weight = (styleBits & SkTypeface::kBold) ?
212                                     SkFontStyle::kBold_Weight :
213                                     SkFontStyle::kNormal_Weight;
214    SkFontStyle::Width width = SkFontStyle::kNormal_Width;
215    SkFontStyle::Slant slant = (styleBits & SkTypeface::kItalic) ?
216                                     SkFontStyle::kUpright_Slant :
217                                     SkFontStyle::kItalic_Slant;
218    return SkFontStyle(weight, width, slant);
219}
220#endif
221
222SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
223                                       const char familyName[],
224                                       SkTypeface::Style style) {
225    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
226    if (familyFace) {
227        bool bold = style & SkTypeface::kBold;
228        bool italic = style & SkTypeface::kItalic;
229        SkFontStyle newStyle = SkFontStyle(bold ? SkFontStyle::kBold_Weight
230                                                : SkFontStyle::kNormal_Weight,
231                                           SkFontStyle::kNormal_Width,
232                                           italic ? SkFontStyle::kItalic_Slant
233                                                  : SkFontStyle::kUpright_Slant);
234        return fm->matchFaceStyle(familyFace, newStyle);
235    } else {
236        return fm->legacyCreateTypeface(familyName, style);
237    }
238}
239
240SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
241    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
242    return fm->createFromFile(path);
243}
244
245SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
246    SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
247    return fm->createFromStream(stream);
248}
249
250#endif
251