Skip to content

Commit

Permalink
Revert "Revert "Cache glyph ids when creating character map.""
Browse files Browse the repository at this point in the history
This reverts commit e7b20c50a045c2b5731fb100f0a062a198fda27a.

Reason for revert: Applying fix.

Change-Id: I14948d82538734f05b7ff9ee9a0f811a91cc3595
  • Loading branch information
Cobalt Team committed Jun 22, 2021
1 parent 0da303a commit febb250
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -276,12 +276,17 @@ sk_sp<SkTypeface> SkFontMgr_Cobalt::onMakeFromStreamIndex(
bool is_fixed_pitch;
SkFontStyle style;
SkString name;

// To pre-fetch glyphs for remote fonts, we could pass character_map here.
if (!sk_freetype_cobalt::ScanFont(stream.get(), face_index, &name, &style,
&is_fixed_pitch)) {
&is_fixed_pitch, nullptr)) {
return NULL;
}
return sk_sp<SkTypeface>(new SkTypeface_CobaltStream(
std::move(stream), face_index, style, is_fixed_pitch, name));
scoped_refptr<font_character_map::CharacterMap> character_map =
base::MakeRefCounted<font_character_map::CharacterMap>();
return sk_sp<SkTypeface>(
new SkTypeface_CobaltStream(std::move(stream), face_index, style,
is_fixed_pitch, name, character_map));
}

sk_sp<SkTypeface> SkFontMgr_Cobalt::onMakeFromFile(const char path[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ SkFontStyleSet_Cobalt::SkFontStyleSet_Cobalt(
return;
}

character_map_ = base::MakeRefCounted<font_character_map::CharacterMap>();

family_name_ = family_info.names[0];
SkTHashMap<SkString, int> styles_index_map;

Expand Down Expand Up @@ -333,11 +335,8 @@ bool SkFontStyleSet_Cobalt::ContainsCharacter(const SkFontStyle& style,
}

bool SkFontStyleSet_Cobalt::CharacterMapContainsCharacter(SkUnichar character) {
font_character_map::CharacterMap::iterator page_iterator =
character_map_.find(font_character_map::GetPage(character));
return page_iterator != character_map_.end() &&
page_iterator->second.test(
font_character_map::GetPageCharacterIndex(character));
font_character_map::Character c = character_map_->Find(character);
return c.is_set && c.id > 0;
}

bool SkFontStyleSet_Cobalt::GenerateStyleFaceInfo(
Expand All @@ -349,7 +348,7 @@ bool SkFontStyleSet_Cobalt::GenerateStyleFaceInfo(
// Providing a pointer to the character map will cause it to be generated
// during ScanFont. Only provide it if it hasn't already been generated.
font_character_map::CharacterMap* character_map =
!is_character_map_generated_ ? &character_map_ : NULL;
!is_character_map_generated_ ? character_map_.get() : NULL;

if (!sk_freetype_cobalt::ScanFont(
stream, style->face_index, &style->face_name, &style->font_style,
Expand Down Expand Up @@ -396,7 +395,7 @@ void SkFontStyleSet_Cobalt::CreateStreamProviderTypeface(
style_entry->typeface.reset(new SkTypeface_CobaltStreamProvider(
stream_provider, style_entry->face_index, style_entry->font_style,
style_entry->face_is_fixed_pitch, family_name_,
style_entry->disable_synthetic_bolding));
style_entry->disable_synthetic_bolding, character_map_));
} else {
LOG(ERROR) << "Failed to scan font: "
<< style_entry->font_file_path.c_str();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class SkFontStyleSet_Cobalt : public SkFontStyleSet {

// NOTE: The following characters require locking when being accessed.
bool is_character_map_generated_;
font_character_map::CharacterMap character_map_;
scoped_refptr<font_character_map::CharacterMap> character_map_;

SkTArray<sk_sp<SkFontStyleSetEntry_Cobalt>, true> styles_;

Expand Down
41 changes: 38 additions & 3 deletions cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontUtil_cobalt.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
#include <map>
#include <utility>

#include "SkMutex.h"
#include "SkString.h"
#include "SkTDArray.h"
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"

// The font_character_map namespace contains all of the constants, typedefs, and
// utility functions used with determining whether or not a font supports a
Expand Down Expand Up @@ -54,13 +56,46 @@ typedef std::pair<int16, int16> PageRange;
// in non-overlapping ascending order.
typedef SkTArray<PageRange> PageRanges;

typedef std::bitset<kNumCharactersPerPage> PageCharacters;
typedef std::map<int16, PageCharacters> CharacterMap;

bool IsCharacterValid(SkUnichar character);
int16 GetPage(SkUnichar character);
unsigned char GetPageCharacterIndex(SkUnichar character);

struct Character {
SkGlyphID id = 0;
bool is_set = false;
};

using PageCharacters = Character[kNumCharactersPerPage];
class CharacterMap : public base::RefCountedThreadSafe<CharacterMap> {
public:
const Character Find(SkUnichar character) {
SkAutoMutexExclusive scoped_mutex(mutex_);

int16 page = GetPage(character);
std::map<int16, PageCharacters>::iterator page_iterator = data_.find(page);

if (page_iterator == data_.end()) return {};

unsigned char character_index = GetPageCharacterIndex(character);
return page_iterator->second[character_index];
}

void Insert(SkUnichar character, SkGlyphID glyph) {
SkAutoMutexExclusive scoped_mutex(mutex_);

int16 page = GetPage(character);
unsigned char character_index = GetPageCharacterIndex(character);
Character c;
c.id = glyph;
c.is_set = true;
data_[page][character_index] = c;
}

private:
std::map<int16, PageCharacters> data_;
mutable SkMutex mutex_;
};

} // namespace font_character_map

// The SkLanguage class represents a human written language, and is used by
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,19 +106,9 @@ void GenerateCharacterMapFromFace(
TRACE_EVENT0("cobalt::renderer", "GenerateCharacterMapFromFace");

FT_UInt glyph_index;

int last_page = -1;
font_character_map::PageCharacters* page_characters = NULL;

SkUnichar code_point = FT_Get_First_Char(face, &glyph_index);
while (glyph_index) {
int page = font_character_map::GetPage(code_point);
if (page != last_page) {
page_characters = &(*character_map)[page];
last_page = page;
}
page_characters->set(font_character_map::GetPageCharacterIndex(code_point));

character_map->Insert(code_point, SkToU16(glyph_index));
code_point = FT_Get_Next_Char(face, code_point, &glyph_index);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,52 @@
#include "SkFontStyle.h"
#include "SkTypefaceCache.h"

SkTypeface_Cobalt::SkTypeface_Cobalt(int face_index, SkFontStyle style,
bool is_fixed_pitch,
const SkString& family_name)
SkTypeface_Cobalt::SkTypeface_Cobalt(
int face_index, SkFontStyle style, bool is_fixed_pitch,
const SkString& family_name,
scoped_refptr<font_character_map::CharacterMap> character_map)
: INHERITED(style, is_fixed_pitch),
face_index_(face_index),
family_name_(family_name),
synthesizes_bold_(!isBold()) {}
synthesizes_bold_(!isBold()),
character_map_(character_map) {}

sk_sp<SkTypeface> SkTypeface_Cobalt::onMakeClone(
const SkFontArguments& args) const {
return sk_ref_sp(this);
}

void SkTypeface_Cobalt::onCharsToGlyphs(const SkUnichar uni[], int count,
SkGlyphID glyphs[]) const {
for (int i = 0; i < count; ++i) {
glyphs[i] = characterMapGetGlyphIdForCharacter(uni[i]);
}
}

SkGlyphID SkTypeface_Cobalt::characterMapGetGlyphIdForCharacter(
SkUnichar character) const {
CHECK(character_map_);

// Check whether the character is cached in the character map.
font_character_map::Character c = character_map_->Find(character);
if (c.is_set) return c.id;

// If the character isn't there, look it up with FreeType, then cache it.
SkGlyphID glyphs[1] = {0};
SkTypeface_FreeType::onCharsToGlyphs(&character, 1, glyphs);
character_map_->Insert(character, glyphs[0]);
return glyphs[0];
}

void SkTypeface_Cobalt::onGetFamilyName(SkString* family_name) const {
*family_name = family_name_;
}

SkTypeface_CobaltStream::SkTypeface_CobaltStream(
std::unique_ptr<SkStreamAsset> stream, int face_index, SkFontStyle style,
bool is_fixed_pitch, const SkString& family_name)
: INHERITED(face_index, style, is_fixed_pitch, family_name),
bool is_fixed_pitch, const SkString& family_name,
scoped_refptr<font_character_map::CharacterMap> character_map)
: INHERITED(face_index, style, is_fixed_pitch, family_name, character_map),
stream_(std::move(stream)) {
LOG(INFO) << "Created SkTypeface_CobaltStream: " << family_name.c_str() << "("
<< style.weight() << ", " << style.width() << ", " << style.slant()
Expand Down Expand Up @@ -68,8 +93,9 @@ size_t SkTypeface_CobaltStream::GetStreamLength() const {
SkTypeface_CobaltStreamProvider::SkTypeface_CobaltStreamProvider(
SkFileMemoryChunkStreamProvider* stream_provider, int face_index,
SkFontStyle style, bool is_fixed_pitch, const SkString& family_name,
bool disable_synthetic_bolding)
: INHERITED(face_index, style, is_fixed_pitch, family_name),
bool disable_synthetic_bolding,
scoped_refptr<font_character_map::CharacterMap> character_map)
: INHERITED(face_index, style, is_fixed_pitch, family_name, character_map),
stream_provider_(stream_provider) {
if (disable_synthetic_bolding) {
synthesizes_bold_ = false;
Expand Down
22 changes: 16 additions & 6 deletions cobalt/renderer/rasterizer/skia/skia/src/ports/SkTypeface_cobalt.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,18 @@
#include "SkStream.h"
#include "SkString.h"
#include "base/memory/ref_counted.h"
#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkFontStyleSet_cobalt.h"
#include "cobalt/renderer/rasterizer/skia/skia/src/ports/SkStream_cobalt.h"
#include "third_party/skia/src/ports/SkFontHost_FreeType_common.h"

class SkFontMgr_Cobalt;

class SkTypeface_Cobalt : public SkTypeface_FreeType {
public:
SkTypeface_Cobalt(int face_index, SkFontStyle style, bool is_fixed_pitch,
const SkString& family_name);
SkTypeface_Cobalt(
int face_index, SkFontStyle style, bool is_fixed_pitch,
const SkString& family_name,
scoped_refptr<font_character_map::CharacterMap> character_map);

virtual size_t GetStreamLength() const = 0;

Expand All @@ -37,6 +40,9 @@ class SkTypeface_Cobalt : public SkTypeface_FreeType {
protected:
sk_sp<SkTypeface> onMakeClone(const SkFontArguments& args) const override;

void onCharsToGlyphs(const SkUnichar uni[], int count,
SkGlyphID glyphs[]) const override;

void onGetFamilyName(SkString* family_name) const override;

int face_index_;
Expand All @@ -45,13 +51,16 @@ class SkTypeface_Cobalt : public SkTypeface_FreeType {

private:
typedef SkTypeface_FreeType INHERITED;
SkGlyphID characterMapGetGlyphIdForCharacter(SkUnichar character) const;
scoped_refptr<font_character_map::CharacterMap> character_map_;
};

class SkTypeface_CobaltStream : public SkTypeface_Cobalt {
public:
SkTypeface_CobaltStream(std::unique_ptr<SkStreamAsset> stream, int face_index,
SkFontStyle style, bool is_fixed_pitch,
const SkString& family_name);
SkTypeface_CobaltStream(
std::unique_ptr<SkStreamAsset> stream, int face_index, SkFontStyle style,
bool is_fixed_pitch, const SkString& family_name,
scoped_refptr<font_character_map::CharacterMap> character_map);

void onGetFontDescriptor(SkFontDescriptor* descriptor,
bool* serialize) const override;
Expand All @@ -71,7 +80,8 @@ class SkTypeface_CobaltStreamProvider : public SkTypeface_Cobalt {
SkTypeface_CobaltStreamProvider(
SkFileMemoryChunkStreamProvider* stream_provider, int face_index,
SkFontStyle style, bool is_fixed_pitch, const SkString& family_name,
bool disable_synthetic_bolding);
bool disable_synthetic_bolding,
scoped_refptr<font_character_map::CharacterMap> character_map);

void onGetFontDescriptor(SkFontDescriptor* descriptor,
bool* serialize) const override;
Expand Down
13 changes: 1 addition & 12 deletions cobalt/renderer/rasterizer/skia/typeface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,26 +65,15 @@ render_tree::GlyphIndex SkiaTypeface::GetGlyphForCharacter(
render_tree::kUnknownGlyphIndex) {
return primary_page_character_glyphs_[utf32_character];
}
// Otherwise, check for the character's glyph within the map.
} else {
CharacterToGlyphMap::iterator glyph_iterator =
character_to_glyph_map_.find(utf32_character);
if (glyph_iterator != character_to_glyph_map_.end()) {
return glyph_iterator->second;
}
}

// If we reach this point, the character's glyph was not previously cached and
// needs to be retrieved now.
render_tree::GlyphIndex glyph = render_tree::kInvalidGlyphIndex;
typeface_->unicharsToGlyphs(&utf32_character, 1, &glyph);

// Both cache and return the character's glyph.
if (utf32_character < kPrimaryPageSize) {
return primary_page_character_glyphs_[utf32_character] = glyph;
} else {
return character_to_glyph_map_[utf32_character] = glyph;
}
return glyph;
}

} // namespace skia
Expand Down
2 changes: 0 additions & 2 deletions cobalt/renderer/rasterizer/skia/typeface.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ class SkiaTypeface : public render_tree::Typeface {
private:
// Usually covers Latin-1 in a single page.
static const int kPrimaryPageSize = 256;
typedef base::hash_map<int32, render_tree::GlyphIndex> CharacterToGlyphMap;

// The underlying SkTypeface that was used to create this typeface.
sk_sp<SkTypeface_Cobalt> typeface_;
Expand All @@ -73,7 +72,6 @@ class SkiaTypeface : public render_tree::Typeface {
// Thread checking is used to used to ensure that they are only accessed and
// modified on a single thread.
std::unique_ptr<render_tree::GlyphIndex[]> primary_page_character_glyphs_;
CharacterToGlyphMap character_to_glyph_map_;
THREAD_CHECKER(character_glyph_thread_checker_);
};

Expand Down

0 comments on commit febb250

Please sign in to comment.