blob: 6ea9f51d00865decd7b02c18bf4076386cfc7094 [file] [log] [blame]
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed 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.
#ifndef COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_PORTS_SKFONTMGR_COBALT_H_
#define COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_PORTS_SKFONTMGR_COBALT_H_
#include <map>
#include <string>
#include <vector>
#include "base/containers/small_map.h"
#include "base/hash_tables.h"
#include "base/memory/scoped_vector.h"
#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.h"
#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontUtil_cobalt.h"
#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkStream_cobalt.h"
#include "SkFontMgr.h"
#include "SkTArray.h"
#include "SkTypeface.h"
// This class, which is thread-safe, is Cobalt's implementation of SkFontMgr. It
// is responsible for the creation of remote typefaces and for, given a set of
// constraints, providing Cobalt with its best matching local typeface.
//
// When a remote typeface's raw data is downloaded from the web, it is provided
// to the font manager, which returns a typeface created from that data.
//
// For local typefaces, the font manager uses Cobalt-specific and
// system-specific configuration files to generate named font families and
// fallback font families. Cobalt uses named families when it needs a typeface
// for a family with a specific name. It utilizes fallback families when none
// of the listed named families supported a given character. In that case,
// the manager finds the best match among the fallback families that can provide
// a glyph for that character.
//
// For both named families and fallback families, after the manager locates the
// best matching family, the determination of the specific typeface to use is
// left to the family. The manager provides the family with the requested style
// and the family returns the typeface that best fits that style.
class SkFontMgr_Cobalt : public SkFontMgr {
public:
typedef std::vector<SkFontStyleSet_Cobalt*> StyleSetArray;
typedef std::map<int, StyleSetArray> PriorityStyleSetArrayMap;
SkFontMgr_Cobalt(const char* cobalt_font_config_directory,
const char* cobalt_font_files_directory,
const char* system_font_config_directory,
const char* system_font_files_directory,
const SkTArray<SkString, true>& default_fonts);
// Purges all font caching in Skia and the local stream manager.
void PurgeCaches();
// NOTE: This returns NULL if a match is not found.
SkTypeface* MatchFaceName(const char face_name[]);
protected:
// From SkFontMgr
virtual int onCountFamilies() const SK_OVERRIDE;
virtual void onGetFamilyName(int index,
SkString* family_name) const SK_OVERRIDE;
// NOTE: This returns NULL if there is no accessible style set at the index.
virtual SkFontStyleSet_Cobalt* onCreateStyleSet(int index) const SK_OVERRIDE;
// NOTE: This returns NULL if there is no family match.
virtual SkFontStyleSet_Cobalt* onMatchFamily(const char family_name[]) const
SK_OVERRIDE;
// NOTE: This always returns a non-NULL value. If the family name cannot be
// found, then the best match among the default family is returned.
virtual SkTypeface* onMatchFamilyStyle(
const char family_name[], const SkFontStyle& style) const SK_OVERRIDE;
// NOTE: This always returns a non-NULL value. If no match can be found, then
// the best match among the default family is returned.
virtual SkTypeface* onMatchFamilyStyleCharacter(
const char family_name[], const SkFontStyle& style, const char bcp47[],
SkUnichar character) const SK_OVERRIDE;
// NOTE: This returns NULL if a match is not found.
virtual SkTypeface* onMatchFaceStyle(const SkTypeface* family_member,
const SkFontStyle& font_style) const
SK_OVERRIDE;
// NOTE: This returns NULL if the typeface cannot be created.
virtual SkTypeface* onCreateFromData(SkData* data,
int face_index) const SK_OVERRIDE;
// NOTE: This returns NULL if the typeface cannot be created.
virtual SkTypeface* onCreateFromStream(SkStreamAsset* stream,
int face_index) const SK_OVERRIDE;
// NOTE: This returns NULL if the typeface cannot be created.
virtual SkTypeface* onCreateFromFile(const char path[],
int face_index) const SK_OVERRIDE;
// NOTE: This always returns a non-NULL value. If no match can be found, then
// the best match among the default family is returned.
virtual SkTypeface* onLegacyCreateTypeface(
const char family_name[], unsigned style_bits) const SK_OVERRIDE;
private:
typedef base::hash_map<std::string, SkFontStyleSet_Cobalt*> NameToStyleSetMap;
typedef base::SmallMap<base::hash_map<std::string, StyleSetArray*> >
NameToStyleSetArrayMap;
void ParseConfigAndBuildFamilies(
const char* font_config_directory, const char* font_files_directory,
PriorityStyleSetArrayMap* priority_fallback_families);
void BuildNameToFamilyMap(
const char* font_files_directory,
SkTDArray<FontFamilyInfo*>* config_font_families,
PriorityStyleSetArrayMap* priority_fallback_families);
void GeneratePriorityOrderedFallbackFamilies(
const PriorityStyleSetArrayMap& priority_fallback_families);
void FindDefaultFamily(const SkTArray<SkString, true>& default_families);
// Returns the first encountered fallback family that matches the language tag
// and supports the specified character.
// NOTE: |style_sets_mutex_| should be locked prior to calling this function.
SkTypeface* FindFamilyStyleCharacter(const SkFontStyle& style,
const SkString& language_tag,
SkUnichar character);
// Returns every fallback family that matches the language tag. If the tag is
// empty, then all fallback families are returned.
// NOTE: |style_sets_mutex_| should be locked prior to calling this function.
StyleSetArray* GetMatchingFallbackFamilies(const SkString& language_tag);
SkFileMemoryChunkStreamManager local_typeface_stream_manager_;
SkTArray<SkAutoTUnref<SkFontStyleSet_Cobalt>, true> families_;
SkTArray<SkString> family_names_;
// Map names to the back end so that all names for a given family refer to
// the same (non-replicated) set of typefaces.
NameToStyleSetMap name_to_family_map_;
NameToStyleSetMap full_font_name_to_family_map_;
NameToStyleSetMap font_postscript_name_to_family_map_;
// Fallback families that are used during character fallback.
// All fallback families, regardless of language.
StyleSetArray fallback_families_;
// Language-specific fallback families. These are lazily populated from
// |fallback_families_| when a new language tag is requested.
ScopedVector<StyleSetArray> language_fallback_families_array_;
NameToStyleSetArrayMap language_fallback_families_map_;
// The default family that is used when no specific match is found during a
// request.
SkFontStyleSet_Cobalt* default_family_;
// Mutex shared by all families for accessing their modifiable data.
mutable SkMutex family_mutex_;
};
#endif // COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_PORTS_SKFONTMGR_COBALT_H_