blob: b1006d5b7d4767d5d91b98e8409c14e4217bec1e [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.
#include "cobalt/renderer/rasterizer/skia/typeface.h"
#include "cobalt/renderer/rasterizer/skia/font.h"
#include "third_party/skia/include/core/SkPaint.h"
namespace {
const uint32 kEstimatedBytesPerGlyph = 256;
} // namespace
namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace skia {
SkiaTypeface::SkiaTypeface(SkTypeface* typeface) : typeface_(SkRef(typeface)) {
character_glyph_thread_checker_.DetachFromThread();
}
SkTypeface* SkiaTypeface::GetSkTypeface() const {
return SkRef(typeface_.get());
}
render_tree::TypefaceId SkiaTypeface::GetId() const {
return typeface_->uniqueID();
}
uint32 SkiaTypeface::GetEstimatedSizeInBytes() const {
return typeface_->countGlyphs() * kEstimatedBytesPerGlyph;
}
scoped_refptr<render_tree::Font> SkiaTypeface::CreateFontWithSize(
float font_size) {
return scoped_refptr<render_tree::Font>(new Font(this, font_size));
}
render_tree::GlyphIndex SkiaTypeface::GetGlyphForCharacter(
int32 utf32_character) {
DCHECK(character_glyph_thread_checker_.CalledOnValidThread());
// If the character falls within the first 256 characters (Latin-1), then
// simply check the primary page for the glyph.
if (utf32_character < kPrimaryPageSize) {
// The first page glyph array is lazily allocated, so we don't use the
// memory if it's never requested.
if (!primary_page_character_glyphs_) {
primary_page_character_glyphs_.reset(
new render_tree::GlyphIndex[kPrimaryPageSize]);
memset(&primary_page_character_glyphs_[0], 0xff,
kPrimaryPageSize * sizeof(render_tree::GlyphIndex));
// If it has already been allocated, then check the array for the
// character. The unknown glyph signifies that the character's glyph has
// not already been retrieved.
} else if (primary_page_character_glyphs_[utf32_character] !=
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_->charsToGlyphs(&utf32_character, SkTypeface::kUTF32_Encoding,
&glyph, 1);
// 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;
}
}
} // namespace skia
} // namespace rasterizer
} // namespace renderer
} // namespace cobalt