| Index: content/renderer/pepper/pepper_truetype_font_mac.mm
|
| diff --git a/content/renderer/pepper/pepper_truetype_font_mac.mm b/content/renderer/pepper/pepper_truetype_font_mac.mm
|
| deleted file mode 100644
|
| index 19e74749506d440c7aa85a7b7f4428d7c4527f5d..0000000000000000000000000000000000000000
|
| --- a/content/renderer/pepper/pepper_truetype_font_mac.mm
|
| +++ /dev/null
|
| @@ -1,408 +0,0 @@
|
| -// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "content/renderer/pepper/pepper_truetype_font.h"
|
| -
|
| -#import <ApplicationServices/ApplicationServices.h>
|
| -
|
| -#include <stdio.h>
|
| -
|
| -#include "base/compiler_specific.h"
|
| -#include "base/mac/foundation_util.h"
|
| -#include "base/mac/scoped_cftyperef.h"
|
| -#include "base/mac/scoped_nsautorelease_pool.h"
|
| -#include "base/numerics/safe_conversions.h"
|
| -#include "base/strings/sys_string_conversions.h"
|
| -#include "base/sys_byteorder.h"
|
| -#include "ppapi/c/dev/ppb_truetype_font_dev.h"
|
| -#include "ppapi/c/pp_errors.h"
|
| -
|
| -namespace content {
|
| -
|
| -namespace {
|
| -
|
| -static bool FindFloat(CFDictionaryRef dict, CFStringRef name, float* value) {
|
| - CFNumberRef num;
|
| - return
|
| - CFDictionaryGetValueIfPresent(dict, name,
|
| - reinterpret_cast<const void**>(&num)) &&
|
| - CFNumberIsFloatType(num) &&
|
| - CFNumberGetValue(num, kCFNumberFloatType, value);
|
| -}
|
| -
|
| -float GetMacWeight(PP_TrueTypeFontWeight_Dev weight) {
|
| - // Map values from NORMAL (400) to HEAVY (900) to the range [0 .. 1], and
|
| - // values below NORMAL to the range [-0.6 .. 0]. NORMAL should map to 0.
|
| - float normal = PP_TRUETYPEFONTWEIGHT_NORMAL;
|
| - float heavy = PP_TRUETYPEFONTWEIGHT_HEAVY;
|
| - return (weight - normal) / (heavy - normal);
|
| -}
|
| -
|
| -PP_TrueTypeFontWeight_Dev GetPepperWeight(float weight) {
|
| - // Perform the inverse mapping of GetMacWeight.
|
| - return static_cast<PP_TrueTypeFontWeight_Dev>(
|
| - weight * (PP_TRUETYPEFONTWEIGHT_HEAVY - PP_TRUETYPEFONTWEIGHT_NORMAL) +
|
| - PP_TRUETYPEFONTWEIGHT_NORMAL);
|
| -}
|
| -
|
| -float GetMacWidth(PP_TrueTypeFontWidth_Dev width) {
|
| - // Map values from NORMAL (4) to ULTRA_EXPANDED (8) to the range [0 .. 1],
|
| - // and values below NORMAL to the range [-1 .. 0]. Normal should map to 0.
|
| - float normal = PP_TRUETYPEFONTWIDTH_NORMAL;
|
| - float ultra_expanded = PP_TRUETYPEFONTWIDTH_ULTRAEXPANDED;
|
| - return (width - normal) / (ultra_expanded - normal);
|
| -}
|
| -
|
| -PP_TrueTypeFontWidth_Dev GetPepperWidth(float width) {
|
| - // Perform the inverse mapping of GetMacWeight.
|
| - return static_cast<PP_TrueTypeFontWidth_Dev>(
|
| - width *
|
| - (PP_TRUETYPEFONTWIDTH_ULTRAEXPANDED - PP_TRUETYPEFONTWIDTH_NORMAL) +
|
| - PP_TRUETYPEFONTWIDTH_NORMAL);
|
| -}
|
| -
|
| -#define MAKE_TABLE_TAG(a, b, c, d) ((a) << 24) + ((b) << 16) + ((c) << 8) + (d)
|
| -
|
| -// TrueType font header and table entry structs. See
|
| -// https://developer.apple.com/fonts/TTRefMan/RM06/Chap6.html
|
| -struct FontHeader {
|
| - int32_t font_type;
|
| - uint16_t num_tables;
|
| - uint16_t search_range;
|
| - uint16_t entry_selector;
|
| - uint16_t range_shift;
|
| -};
|
| -static_assert(sizeof(FontHeader) == 12, "FontHeader wrong size");
|
| -
|
| -struct FontDirectoryEntry {
|
| - uint32_t tag;
|
| - uint32_t checksum;
|
| - uint32_t offset;
|
| - uint32_t logical_length;
|
| -};
|
| -static_assert(sizeof(FontDirectoryEntry) == 16,
|
| - "FontDirectoryEntry wrong size");
|
| -
|
| -uint32_t CalculateChecksum(char* table, int32_t table_length) {
|
| - uint32_t sum = 0;
|
| - uint32_t* current = reinterpret_cast<uint32_t*>(table);
|
| - uint32_t length = (table_length + 3) / 4;
|
| - // Raw font data is big-endian.
|
| - while (length-- > 0)
|
| - sum += base::NetToHost32(*current++);
|
| - return sum;
|
| -}
|
| -
|
| -class PepperTrueTypeFontMac : public PepperTrueTypeFont {
|
| - public:
|
| - explicit PepperTrueTypeFontMac(
|
| - const ppapi::proxy::SerializedTrueTypeFontDesc& desc);
|
| - virtual ~PepperTrueTypeFontMac() OVERRIDE;
|
| -
|
| - // PepperTrueTypeFont overrides.
|
| - virtual bool IsValid() OVERRIDE;
|
| - virtual int32_t Describe(
|
| - ppapi::proxy::SerializedTrueTypeFontDesc* desc) OVERRIDE;
|
| - virtual int32_t GetTableTags(std::vector<uint32_t>* tags) OVERRIDE;
|
| - virtual int32_t GetTable(uint32_t table_tag,
|
| - int32_t offset,
|
| - int32_t max_data_length,
|
| - std::string* data) OVERRIDE;
|
| - private:
|
| - virtual int32_t GetEntireFont(int32_t offset,
|
| - int32_t max_data_length,
|
| - std::string* data);
|
| -
|
| - base::ScopedCFTypeRef<CTFontRef> font_ref_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(PepperTrueTypeFontMac);
|
| -};
|
| -
|
| -PepperTrueTypeFontMac::PepperTrueTypeFontMac(
|
| - const ppapi::proxy::SerializedTrueTypeFontDesc& desc) {
|
| - // Create attributes and traits dictionaries.
|
| - base::ScopedCFTypeRef<CFMutableDictionaryRef> attributes_ref(
|
| - CFDictionaryCreateMutable(kCFAllocatorDefault,
|
| - 0,
|
| - &kCFTypeDictionaryKeyCallBacks,
|
| - &kCFTypeDictionaryValueCallBacks));
|
| -
|
| - base::ScopedCFTypeRef<CFMutableDictionaryRef> traits_ref(
|
| - CFDictionaryCreateMutable(kCFAllocatorDefault,
|
| - 0,
|
| - &kCFTypeDictionaryKeyCallBacks,
|
| - &kCFTypeDictionaryValueCallBacks));
|
| - if (!attributes_ref || !traits_ref)
|
| - return;
|
| -
|
| - CFDictionaryAddValue(attributes_ref, kCTFontTraitsAttribute, traits_ref);
|
| -
|
| - // Use symbolic traits to specify traits when possible.
|
| - CTFontSymbolicTraits symbolic_traits = 0;
|
| - if (desc.style & PP_TRUETYPEFONTSTYLE_ITALIC)
|
| - symbolic_traits |= kCTFontItalicTrait;
|
| - if (desc.weight == PP_TRUETYPEFONTWEIGHT_BOLD)
|
| - symbolic_traits |= kCTFontBoldTrait;
|
| - if (desc.width == PP_TRUETYPEFONTWIDTH_CONDENSED)
|
| - symbolic_traits |= kCTFontCondensedTrait;
|
| - else if (desc.width == PP_TRUETYPEFONTWIDTH_EXPANDED)
|
| - symbolic_traits |= kCTFontExpandedTrait;
|
| -
|
| - base::ScopedCFTypeRef<CFNumberRef> symbolic_traits_ref(CFNumberCreate(
|
| - kCFAllocatorDefault, kCFNumberSInt32Type, &symbolic_traits));
|
| - if (!symbolic_traits_ref)
|
| - return;
|
| - CFDictionaryAddValue(traits_ref, kCTFontSymbolicTrait, symbolic_traits_ref);
|
| -
|
| - // Font family matching doesn't work using family classes in symbolic traits.
|
| - // Instead, map generic_family to font families that are always available.
|
| - std::string family(desc.family);
|
| - if (family.empty()) {
|
| - switch (desc.generic_family) {
|
| - case PP_TRUETYPEFONTFAMILY_SERIF:
|
| - family = "Times";
|
| - break;
|
| - case PP_TRUETYPEFONTFAMILY_SANSSERIF:
|
| - family = "Helvetica";
|
| - break;
|
| - case PP_TRUETYPEFONTFAMILY_CURSIVE:
|
| - family = "Apple Chancery";
|
| - break;
|
| - case PP_TRUETYPEFONTFAMILY_FANTASY:
|
| - family = "Papyrus";
|
| - break;
|
| - case PP_TRUETYPEFONTFAMILY_MONOSPACE:
|
| - family = "Courier";
|
| - break;
|
| - }
|
| - }
|
| -
|
| - base::ScopedCFTypeRef<CFStringRef> name_ref(
|
| - base::SysUTF8ToCFStringRef(family));
|
| - if (name_ref)
|
| - CFDictionaryAddValue(attributes_ref, kCTFontFamilyNameAttribute, name_ref);
|
| -
|
| - if (desc.weight != PP_TRUETYPEFONTWEIGHT_NORMAL &&
|
| - desc.weight != PP_TRUETYPEFONTWEIGHT_BOLD) {
|
| - float weight = GetMacWeight(desc.weight);
|
| - base::ScopedCFTypeRef<CFNumberRef> weight_trait_ref(
|
| - CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat32Type, &weight));
|
| - if (weight_trait_ref)
|
| - CFDictionaryAddValue(traits_ref, kCTFontWeightTrait, weight_trait_ref);
|
| - }
|
| -
|
| - if (desc.width != PP_TRUETYPEFONTWIDTH_NORMAL &&
|
| - desc.width != PP_TRUETYPEFONTWIDTH_CONDENSED &&
|
| - desc.width != PP_TRUETYPEFONTWIDTH_EXPANDED) {
|
| - float width = GetMacWidth(desc.width);
|
| - base::ScopedCFTypeRef<CFNumberRef> width_trait_ref(
|
| - CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat32Type, &width));
|
| - if (width_trait_ref)
|
| - CFDictionaryAddValue(traits_ref, kCTFontWidthTrait, width_trait_ref);
|
| - }
|
| -
|
| - base::ScopedCFTypeRef<CTFontDescriptorRef> desc_ref(
|
| - CTFontDescriptorCreateWithAttributes(attributes_ref));
|
| -
|
| - if (desc_ref)
|
| - font_ref_.reset(CTFontCreateWithFontDescriptor(desc_ref, 0, NULL));
|
| -}
|
| -
|
| -PepperTrueTypeFontMac::~PepperTrueTypeFontMac() {
|
| -}
|
| -
|
| -bool PepperTrueTypeFontMac::IsValid() {
|
| - return font_ref_.get() != NULL;
|
| -}
|
| -
|
| -int32_t PepperTrueTypeFontMac::Describe(
|
| - ppapi::proxy::SerializedTrueTypeFontDesc* desc) {
|
| - if (!IsValid())
|
| - return PP_ERROR_FAILED;
|
| -
|
| - base::ScopedCFTypeRef<CTFontDescriptorRef> desc_ref(
|
| - CTFontCopyFontDescriptor(font_ref_));
|
| -
|
| - base::ScopedCFTypeRef<CFStringRef> family_name_ref(
|
| - base::mac::CFCast<CFStringRef>(
|
| - CTFontDescriptorCopyAttribute(desc_ref, kCTFontFamilyNameAttribute)));
|
| - desc->family = base::SysCFStringRefToUTF8(family_name_ref);
|
| -
|
| - base::ScopedCFTypeRef<CFDictionaryRef> traits_ref(
|
| - base::mac::CFCast<CFDictionaryRef>(
|
| - CTFontDescriptorCopyAttribute(desc_ref, kCTFontTraitsAttribute)));
|
| -
|
| - desc->style = PP_TRUETYPEFONTSTYLE_NORMAL;
|
| - CTFontSymbolicTraits symbolic_traits(CTFontGetSymbolicTraits(font_ref_));
|
| - if (symbolic_traits & kCTFontItalicTrait)
|
| - desc->style = static_cast<PP_TrueTypeFontStyle_Dev>(
|
| - desc->style | PP_TRUETYPEFONTSTYLE_ITALIC);
|
| - if (symbolic_traits & kCTFontBoldTrait) {
|
| - desc->weight = PP_TRUETYPEFONTWEIGHT_BOLD;
|
| - } else {
|
| - float weight;
|
| - if (FindFloat(traits_ref, kCTFontWeightTrait, &weight))
|
| - desc->weight = GetPepperWeight(weight);
|
| - }
|
| - if (symbolic_traits & kCTFontCondensedTrait) {
|
| - desc->width = PP_TRUETYPEFONTWIDTH_CONDENSED;
|
| - } else if (symbolic_traits & kCTFontExpandedTrait) {
|
| - desc->width = PP_TRUETYPEFONTWIDTH_EXPANDED;
|
| - } else {
|
| - float width;
|
| - if (FindFloat(traits_ref, kCTFontWidthTrait, &width))
|
| - desc->width = GetPepperWidth(width);
|
| - }
|
| -
|
| - // Character set isn't supported on Mac.
|
| - desc->charset = PP_TRUETYPEFONTCHARSET_DEFAULT;
|
| - return PP_OK;
|
| -}
|
| -
|
| -int32_t PepperTrueTypeFontMac::GetTableTags(std::vector<uint32_t>* tags) {
|
| - base::ScopedCFTypeRef<CFArrayRef> tag_array(
|
| - CTFontCopyAvailableTables(font_ref_, kCTFontTableOptionNoOptions));
|
| - if (!tag_array)
|
| - return PP_ERROR_FAILED;
|
| -
|
| - // Items returned by CTFontCopyAvailableTables are not boxed. Whose bright
|
| - // idea was this?
|
| - CFIndex length = CFArrayGetCount(tag_array);
|
| - tags->resize(length);
|
| - for (CFIndex i = 0; i < length; ++i) {
|
| - (*tags)[i] =
|
| - reinterpret_cast<uintptr_t>(CFArrayGetValueAtIndex(tag_array, i));
|
| - }
|
| - return length;
|
| -}
|
| -
|
| -int32_t PepperTrueTypeFontMac::GetTable(uint32_t table_tag,
|
| - int32_t offset,
|
| - int32_t max_data_length,
|
| - std::string* data) {
|
| - if (!table_tag)
|
| - return GetEntireFont(offset, max_data_length, data);
|
| -
|
| - base::ScopedCFTypeRef<CFDataRef> table_ref(
|
| - CTFontCopyTable(font_ref_,
|
| - static_cast<CTFontTableTag>(table_tag),
|
| - kCTFontTableOptionNoOptions));
|
| - if (!table_ref)
|
| - return PP_ERROR_FAILED;
|
| -
|
| - CFIndex table_size = CFDataGetLength(table_ref);
|
| - CFIndex safe_offset =
|
| - std::min(base::checked_cast<CFIndex>(offset), table_size);
|
| - CFIndex safe_length =
|
| - std::min(table_size - safe_offset,
|
| - base::checked_cast<CFIndex>(max_data_length));
|
| - data->resize(safe_length);
|
| - CFDataGetBytes(table_ref, CFRangeMake(safe_offset, safe_length),
|
| - reinterpret_cast<UInt8*>(&(*data)[0]));
|
| -
|
| - return safe_length;
|
| -}
|
| -
|
| -int32_t PepperTrueTypeFontMac::GetEntireFont(int32_t offset,
|
| - int32_t max_data_length,
|
| - std::string* data) {
|
| - // Reconstruct the font header, table directory, and tables.
|
| - std::vector<uint32_t> table_tags;
|
| - int32_t table_count = GetTableTags(&table_tags);
|
| - if (table_count < 0)
|
| - return table_count; // PPAPI error code.
|
| -
|
| - // Allocate enough room for the header and the table directory entries.
|
| - std::string font(sizeof(FontHeader) +
|
| - sizeof(FontDirectoryEntry) * table_count, 0);
|
| - // Map the OS X font type value to a TrueType scalar type.
|
| - base::ScopedCFTypeRef<CFNumberRef> font_type_ref(
|
| - base::mac::CFCast<CFNumberRef>(
|
| - CTFontCopyAttribute(font_ref_, kCTFontFormatAttribute)));
|
| - int32_t font_type;
|
| - CFNumberGetValue(font_type_ref, kCFNumberSInt32Type, &font_type);
|
| - switch (font_type) {
|
| - case kCTFontFormatOpenTypePostScript:
|
| - font_type = MAKE_TABLE_TAG('O', 'T', 'T', 'O');
|
| - break;
|
| - case kCTFontFormatTrueType:
|
| - case kCTFontFormatBitmap:
|
| - font_type = MAKE_TABLE_TAG('t', 'r', 'u', 'e');
|
| - break;
|
| - case kCTFontFormatPostScript:
|
| - font_type = MAKE_TABLE_TAG('t', 'y', 'p', '1');
|
| - break;
|
| - case kCTFontFormatOpenTypeTrueType:
|
| - case kCTFontFormatUnrecognized:
|
| - default:
|
| - font_type = MAKE_TABLE_TAG(0, 1, 0, 0);
|
| - break;
|
| - }
|
| -
|
| - // Calculate the rest of the header values.
|
| - uint16_t num_tables = base::checked_cast<uint16_t>(table_count);
|
| - uint16_t entry_selector = 0;
|
| - uint16_t search_range = 1;
|
| - while (search_range < num_tables >> 1) {
|
| - entry_selector++;
|
| - search_range <<= 1;
|
| - }
|
| - search_range <<= 4;
|
| - uint16_t range_shift = (num_tables << 4) - search_range;
|
| -
|
| - // Write the header, with values in big-endian order.
|
| - FontHeader* font_header = reinterpret_cast<FontHeader*>(&font[0]);
|
| - font_header->font_type = base::HostToNet32(font_type);
|
| - font_header->num_tables = base::HostToNet16(num_tables);
|
| - font_header->search_range = base::HostToNet16(search_range);
|
| - font_header->entry_selector = base::HostToNet16(entry_selector);
|
| - font_header->range_shift = base::HostToNet16(range_shift);
|
| -
|
| - for (int32_t i = 0; i < table_count; i++) {
|
| - // Get the table data.
|
| - std::string table;
|
| - int32_t table_size = GetTable(table_tags[i],
|
| - 0, std::numeric_limits<int32_t>::max(),
|
| - &table);
|
| - if (table_size < 0)
|
| - return table_size; // PPAPI error code.
|
| -
|
| - // Append it to the font data so far, and zero pad so tables stay aligned.
|
| - size_t table_offset = font.size();
|
| - font.append(table);
|
| - size_t padding = font.size() & 0x3;
|
| - font.append(padding, 0);
|
| -
|
| - // Fill in the directory entry for this table.
|
| - FontDirectoryEntry* entry = reinterpret_cast<FontDirectoryEntry*>(
|
| - &font[0] + sizeof(FontHeader) + i * sizeof(FontDirectoryEntry));
|
| - entry->tag = base::HostToNet32(table_tags[i]);
|
| - entry->checksum = base::HostToNet32(
|
| - CalculateChecksum(&font[table_offset], table_size));
|
| - entry->offset = base::HostToNet32(table_offset);
|
| - entry->logical_length = base::HostToNet32(table_size);
|
| - // TODO(bbudge) set the 'head' table checksumAdjustment.
|
| - }
|
| -
|
| - // Extract a substring if the caller specified an offset or max data length.
|
| - int32_t font_size = base::checked_cast<int32_t>(font.size());
|
| - int32_t safe_offset = std::min(offset, font_size);
|
| - int32_t safe_length = std::min(font_size - safe_offset, max_data_length);
|
| - if (safe_offset || safe_length != font_size)
|
| - font = font.substr(safe_offset, safe_length);
|
| -
|
| - data->clear();
|
| - data->swap(font);
|
| - return safe_length;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -// static
|
| -PepperTrueTypeFont* PepperTrueTypeFont::Create(
|
| - const ppapi::proxy::SerializedTrueTypeFontDesc& desc) {
|
| - return new PepperTrueTypeFontMac(desc);
|
| -}
|
| -
|
| -} // namespace content
|
|
|