diff options
author | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-09 23:05:34 +0000 |
---|---|---|
committer | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-09 23:05:34 +0000 |
commit | 81fc9f01241ed5d635d35328fa226a682c7a81d2 (patch) | |
tree | 74b83b41373f3e6223461fb3bec44f43c799d599 /content/common | |
parent | 8fdf9f5214e385b650c1a708a5c7e015b8fbde5e (diff) | |
download | chromium_src-81fc9f01241ed5d635d35328fa226a682c7a81d2.zip chromium_src-81fc9f01241ed5d635d35328fa226a682c7a81d2.tar.gz chromium_src-81fc9f01241ed5d635d35328fa226a682c7a81d2.tar.bz2 |
Move AttributedStringCoder from chrome to content.
Also, move a few Mac-only files to the new content/commmon/mac.
BUG=95573
TEST=no change
Review URL: http://codereview.chromium.org/7867016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@100526 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/common')
-rw-r--r-- | content/common/mac/attributed_string_coder.h | 119 | ||||
-rw-r--r-- | content/common/mac/attributed_string_coder.mm | 171 | ||||
-rw-r--r-- | content/common/mac/attributed_string_coder_unittest.mm | 135 | ||||
-rw-r--r-- | content/common/mac/font_descriptor.h (renamed from content/common/font_descriptor_mac.h) | 6 | ||||
-rw-r--r-- | content/common/mac/font_descriptor.mm (renamed from content/common/font_descriptor_mac.mm) | 2 | ||||
-rw-r--r-- | content/common/mac/font_descriptor_unittest.mm (renamed from content/common/font_descriptor_mac_unittest.mm) | 16 | ||||
-rw-r--r-- | content/common/mac/font_loader.h (renamed from content/common/font_loader_mac.h) | 6 | ||||
-rw-r--r-- | content/common/mac/font_loader.mm (renamed from content/common/font_loader_mac.mm) | 2 | ||||
-rw-r--r-- | content/common/sandbox_mac_fontloading_unittest.mm | 2 | ||||
-rw-r--r-- | content/common/view_messages.h | 2 |
10 files changed, 443 insertions, 18 deletions
diff --git a/content/common/mac/attributed_string_coder.h b/content/common/mac/attributed_string_coder.h new file mode 100644 index 0000000..054cb45 --- /dev/null +++ b/content/common/mac/attributed_string_coder.h @@ -0,0 +1,119 @@ +// Copyright (c) 2011 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. + +#ifndef CONTENT_COMMON_MAC_ATTRIBUTED_STRING_CODER_H_ +#define CONTENT_COMMON_MAC_ATTRIBUTED_STRING_CODER_H_ +#pragma once + +#include <set> + +#include "base/memory/scoped_ptr.h" +#include "base/string16.h" +#include "content/common/mac/font_descriptor.h" +#include "ipc/ipc_message_utils.h" +#include "ui/base/range/range.h" + +#if __OBJC__ +@class NSAttributedString; +@class NSDictionary; +#else +class NSAttributedString; +class NSDictionary; +#endif + +namespace mac { + +// This class will serialize the font information of an NSAttributedString so +// that it can be sent over IPC. This class only stores the information of the +// NSFontAttributeName. The motive is that of security: using NSArchiver and +// friends to send objects from the renderer to the browser could lead to +// deserialization of arbitrary objects. This class restricts serialization to +// a specific object class and specific attributes of that object. +class AttributedStringCoder { + public: + // A C++ IPC-friendly representation of the NSFontAttributeName attribute + // set. + class FontAttribute { + public: + FontAttribute(NSDictionary* ns_attributes, ui::Range effective_range); + FontAttribute(FontDescriptor font, ui::Range range); + FontAttribute(); + ~FontAttribute(); + + // Creates an autoreleased NSDictionary that can be attached to an + // NSAttributedString. + NSDictionary* ToAttributesDictionary() const; + + // Whether or not the attribute should be placed in the EncodedString. This + // can return false, e.g. if the Cocoa-based constructor can't find any + // information to encode. + bool ShouldEncode() const; + + // Accessors: + FontDescriptor font_descriptor() const { return font_descriptor_; } + ui::Range effective_range() const { return effective_range_; } + + private: + FontDescriptor font_descriptor_; + ui::Range effective_range_; + }; + + // A class that contains the pertinent information from an NSAttributedString, + // which can be serialized over IPC. + class EncodedString { + public: + explicit EncodedString(string16 string); + EncodedString(); + ~EncodedString(); + + // Accessors: + string16 string() const { return string_; } + const std::vector<FontAttribute>& attributes() const { + return attributes_; + } + std::vector<FontAttribute>* attributes() { return &attributes_; } + + private: + // The plain-text string. + string16 string_; + // The set of attributes that style |string_|. + std::vector<FontAttribute> attributes_; + }; + + // Takes an NSAttributedString, extracts the pertinent attributes, and returns + // an object that represents it. Caller owns the result. + static const EncodedString* Encode(NSAttributedString* str); + + // Returns an autoreleased NSAttributedString from an encoded representation. + static NSAttributedString* Decode(const EncodedString* str); + + private: + AttributedStringCoder(); +}; + +} // namespace mac + +// IPC ParamTraits specialization ////////////////////////////////////////////// + +namespace IPC { + +template <> +struct ParamTraits<mac::AttributedStringCoder::EncodedString> { + typedef mac::AttributedStringCoder::EncodedString param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, void** iter, param_type* r); + static void Log(const param_type& p, std::string* l); +}; + +template <> +struct ParamTraits<mac::AttributedStringCoder::FontAttribute> { + typedef mac::AttributedStringCoder::FontAttribute param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, void** iter, param_type* r); + static void Log(const param_type& p, std::string* l); +}; + +} // namespace IPC + +#endif // CONTENT_COMMON_MAC_ATTRIBUTED_STRING_CODER_H_ diff --git a/content/common/mac/attributed_string_coder.mm b/content/common/mac/attributed_string_coder.mm new file mode 100644 index 0000000..ca4847d --- /dev/null +++ b/content/common/mac/attributed_string_coder.mm @@ -0,0 +1,171 @@ +// Copyright (c) 2011 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/common/mac/attributed_string_coder.h" + +#include <AppKit/AppKit.h> + +#include "base/logging.h" +#include "base/memory/scoped_nsobject.h" +#include "base/sys_string_conversions.h" +#include "base/utf_string_conversions.h" +#include "content/common/common_param_traits.h" +#include "content/common/view_messages.h" +#include "ipc/ipc_message_utils.h" + +namespace mac { + +// static +const AttributedStringCoder::EncodedString* AttributedStringCoder::Encode( + NSAttributedString* str) { + // Create the return value. + EncodedString* encoded_string = + new EncodedString(base::SysNSStringToUTF16([str string])); + // Iterate over all the attributes in the string. + NSUInteger length = [str length]; + for (NSUInteger i = 0; i < length; ) { + NSRange effective_range; + NSDictionary* ns_attributes = [str attributesAtIndex:i + effectiveRange:&effective_range]; + // Convert the attributes to IPC-friendly types. + FontAttribute attrs(ns_attributes, ui::Range(effective_range)); + // Only encode the attributes if the filtered set contains font information. + if (attrs.ShouldEncode()) { + encoded_string->attributes()->push_back(attrs); + } + // Advance the iterator to the position outside of the effective range. + i = NSMaxRange(effective_range); + } + return encoded_string; +} + +// static +NSAttributedString* AttributedStringCoder::Decode( + const AttributedStringCoder::EncodedString* str) { + // Create the return value. + NSString* plain_text = base::SysUTF16ToNSString(str->string()); + scoped_nsobject<NSMutableAttributedString> decoded_string( + [[NSMutableAttributedString alloc] initWithString:plain_text]); + // Iterate over all the encoded attributes, attaching each to the string. + const std::vector<FontAttribute> attributes = str->attributes(); + for (std::vector<FontAttribute>::const_iterator it = attributes.begin(); + it != attributes.end(); ++it) { + // Protect against ranges that are outside the range of the string. + const ui::Range& range = it->effective_range(); + if (range.GetMin() > [plain_text length] || + range.GetMax() > [plain_text length]) { + continue; + } + [decoded_string addAttributes:it->ToAttributesDictionary() + range:range.ToNSRange()]; + } + return [decoded_string.release() autorelease]; +} + +// Data Types ////////////////////////////////////////////////////////////////// + +AttributedStringCoder::EncodedString::EncodedString(string16 string) + : string_(string) { +} + +AttributedStringCoder::EncodedString::EncodedString() + : string_() { +} + +AttributedStringCoder::EncodedString::~EncodedString() { +} + +AttributedStringCoder::FontAttribute::FontAttribute(NSDictionary* dict, + ui::Range effective_range) + : font_descriptor_(), + effective_range_(effective_range) { + NSFont* font = [dict objectForKey:NSFontAttributeName]; + if (font) { + font_descriptor_ = FontDescriptor(font); + } +} + +AttributedStringCoder::FontAttribute::FontAttribute(FontDescriptor font, + ui::Range range) + : font_descriptor_(font), + effective_range_(range) { +} + +AttributedStringCoder::FontAttribute::FontAttribute() + : font_descriptor_(), + effective_range_() { +} + +AttributedStringCoder::FontAttribute::~FontAttribute() { +} + +NSDictionary* AttributedStringCoder::FontAttribute::ToAttributesDictionary( + void) const { + DCHECK(ShouldEncode()); + NSFont* font = font_descriptor_.ToNSFont(); + return [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; +} + +bool AttributedStringCoder::FontAttribute::ShouldEncode() const { + return !font_descriptor_.font_name.empty(); +} + +} // namespace mac + +// IPC ParamTraits specialization ////////////////////////////////////////////// + +namespace IPC { + +using mac::AttributedStringCoder; + +void ParamTraits<AttributedStringCoder::EncodedString>::Write( + Message* m, const param_type& p) { + WriteParam(m, p.string()); + WriteParam(m, p.attributes()); +} + +bool ParamTraits<AttributedStringCoder::EncodedString>::Read( + const Message* m, void** iter, param_type* p) { + bool success = true; + + string16 result; + success &= ReadParam(m, iter, &result); + *p = AttributedStringCoder::EncodedString(result); + + success &= ReadParam(m, iter, p->attributes()); + return success; +} + +void ParamTraits<AttributedStringCoder::EncodedString>::Log( + const param_type& p, std::string* l) { + l->append(UTF16ToUTF8(p.string())); +} + +void ParamTraits<AttributedStringCoder::FontAttribute>::Write( + Message* m, const param_type& p) { + WriteParam(m, p.font_descriptor()); + WriteParam(m, p.effective_range()); +} + +bool ParamTraits<AttributedStringCoder::FontAttribute>::Read( + const Message* m, void** iter, param_type* p) { + bool success = true; + + FontDescriptor font; + success &= ReadParam(m, iter, &font); + + ui::Range range; + success &= ReadParam(m, iter, &range); + + if (success) { + *p = AttributedStringCoder::FontAttribute(font, range); + } + return success; +} + +void ParamTraits<AttributedStringCoder::FontAttribute>::Log( + const param_type& p, std::string* l) { +} + +} // namespace IPC diff --git a/content/common/mac/attributed_string_coder_unittest.mm b/content/common/mac/attributed_string_coder_unittest.mm new file mode 100644 index 0000000..993c842 --- /dev/null +++ b/content/common/mac/attributed_string_coder_unittest.mm @@ -0,0 +1,135 @@ +// Copyright (c) 2011 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 <AppKit/AppKit.h> + +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" +#include "base/utf_string_conversions.h" +#import "content/common/mac/attributed_string_coder.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/gtest_mac.h" + +using mac::AttributedStringCoder; + +class AttributedStringCoderTest : public testing::Test { + public: + NSMutableAttributedString* NewAttrString() { + NSString* str = @"The quick brown fox jumped over the lazy dog."; + return [[NSMutableAttributedString alloc] initWithString:str]; + } + + NSDictionary* FontAttribute(NSString* name, CGFloat size) { + NSFont* font = [NSFont fontWithName:name size:size]; + return [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; + } + + NSAttributedString* EncodeAndDecode(NSAttributedString* str) { + scoped_ptr<const AttributedStringCoder::EncodedString> encoded_str( + AttributedStringCoder::Encode(str)); + return AttributedStringCoder::Decode(encoded_str.get()); + } +}; + +TEST_F(AttributedStringCoderTest, SimpleString) { + scoped_nsobject<NSMutableAttributedString> attr_str(NewAttrString()); + [attr_str addAttributes:FontAttribute(@"Helvetica", 12.5) + range:NSMakeRange(0, [attr_str length])]; + + NSAttributedString* decoded = EncodeAndDecode(attr_str.get()); + EXPECT_NSEQ(attr_str.get(), decoded); +} + +TEST_F(AttributedStringCoderTest, NoAttributes) { + scoped_nsobject<NSAttributedString> attr_str(NewAttrString()); + NSAttributedString* decoded = EncodeAndDecode(attr_str.get()); + EXPECT_NSEQ(attr_str.get(), decoded); +} + +TEST_F(AttributedStringCoderTest, StripColor) { + scoped_nsobject<NSMutableAttributedString> attr_str(NewAttrString()); + const NSUInteger kStringLength = [attr_str length]; + [attr_str addAttribute:NSFontAttributeName + value:[NSFont systemFontOfSize:26] + range:NSMakeRange(0, kStringLength)]; + [attr_str addAttribute:NSForegroundColorAttributeName + value:[NSColor redColor] + range:NSMakeRange(0, kStringLength)]; + + NSAttributedString* decoded = EncodeAndDecode(attr_str.get()); + + NSRange range; + NSDictionary* attrs = [decoded attributesAtIndex:0 effectiveRange:&range]; + EXPECT_TRUE(NSEqualRanges(NSMakeRange(0, kStringLength), range)); + EXPECT_NSEQ([NSFont systemFontOfSize:26], + [attrs objectForKey:NSFontAttributeName]); + EXPECT_FALSE([attrs objectForKey:NSForegroundColorAttributeName]); +} + +TEST_F(AttributedStringCoderTest, MultipleFonts) { + scoped_nsobject<NSMutableAttributedString> attr_str(NewAttrString()); + [attr_str setAttributes:FontAttribute(@"Courier", 12) + range:NSMakeRange(0, 10)]; + [attr_str addAttributes:FontAttribute(@"Helvetica", 16) + range:NSMakeRange(12, 6)]; + [attr_str addAttributes:FontAttribute(@"Helvetica", 14) + range:NSMakeRange(15, 5)]; + + NSAttributedString* decoded = EncodeAndDecode(attr_str); + + EXPECT_NSEQ(attr_str.get(), decoded); +} + +TEST_F(AttributedStringCoderTest, NoPertinentAttributes) { + scoped_nsobject<NSMutableAttributedString> attr_str(NewAttrString()); + [attr_str addAttribute:NSForegroundColorAttributeName + value:[NSColor blueColor] + range:NSMakeRange(0, 10)]; + [attr_str addAttribute:NSBackgroundColorAttributeName + value:[NSColor blueColor] + range:NSMakeRange(15, 5)]; + [attr_str addAttribute:NSKernAttributeName + value:[NSNumber numberWithFloat:2.6] + range:NSMakeRange(11, 3)]; + + NSAttributedString* decoded = EncodeAndDecode(attr_str.get()); + + scoped_nsobject<NSAttributedString> expected(NewAttrString()); + EXPECT_NSEQ(expected.get(), decoded); +} + +TEST_F(AttributedStringCoderTest, NilString) { + NSAttributedString* decoded = EncodeAndDecode(nil); + EXPECT_TRUE(decoded); + EXPECT_EQ(0U, [decoded length]); +} + +TEST_F(AttributedStringCoderTest, OutOfRange) { + AttributedStringCoder::EncodedString encoded(ASCIIToUTF16("Hello World")); + encoded.attributes()->push_back( + AttributedStringCoder::FontAttribute( + FontDescriptor([NSFont systemFontOfSize:12]), + ui::Range(0, 5))); + encoded.attributes()->push_back( + AttributedStringCoder::FontAttribute( + FontDescriptor([NSFont systemFontOfSize:14]), + ui::Range(5, 100))); + encoded.attributes()->push_back( + AttributedStringCoder::FontAttribute( + FontDescriptor([NSFont systemFontOfSize:16]), + ui::Range(100, 5))); + + NSAttributedString* decoded = AttributedStringCoder::Decode(&encoded); + EXPECT_TRUE(decoded); + + NSRange range; + NSDictionary* attrs = [decoded attributesAtIndex:0 effectiveRange:&range]; + EXPECT_NSEQ([NSFont systemFontOfSize:12], + [attrs objectForKey:NSFontAttributeName]); + EXPECT_TRUE(NSEqualRanges(range, NSMakeRange(0, 5))); + + attrs = [decoded attributesAtIndex:5 effectiveRange:&range]; + EXPECT_FALSE([attrs objectForKey:NSFontAttributeName]); + EXPECT_EQ(0U, [attrs count]); +} diff --git a/content/common/font_descriptor_mac.h b/content/common/mac/font_descriptor.h index c3ac5a8..750976f 100644 --- a/content/common/font_descriptor_mac.h +++ b/content/common/mac/font_descriptor.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_COMMON_FONT_DESCRIPTOR_MAC_H_ -#define CONTENT_COMMON_FONT_DESCRIPTOR_MAC_H_ +#ifndef CONTENT_COMMON_MAC_FONT_DESCRIPTOR_H_ +#define CONTENT_COMMON_MAC_FONT_DESCRIPTOR_H_ #pragma once #include "base/string16.h" @@ -31,4 +31,4 @@ struct FontDescriptor { float font_point_size; }; -#endif // CONTENT_COMMON_FONT_DESCRIPTOR_MAC_H_ +#endif // CONTENT_COMMON_MAC_FONT_DESCRIPTOR_H_ diff --git a/content/common/font_descriptor_mac.mm b/content/common/mac/font_descriptor.mm index c8e3112..65ab40e 100644 --- a/content/common/font_descriptor_mac.mm +++ b/content/common/mac/font_descriptor.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/common/font_descriptor_mac.h" +#include "content/common/mac/font_descriptor.h" #include <Cocoa/Cocoa.h> diff --git a/content/common/font_descriptor_mac_unittest.mm b/content/common/mac/font_descriptor_unittest.mm index f8fdfc8..7054c22 100644 --- a/content/common/font_descriptor_mac_unittest.mm +++ b/content/common/mac/font_descriptor_unittest.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/common/font_descriptor_mac.h" +#include "content/common/mac/font_descriptor.h" #include <Cocoa/Cocoa.h> @@ -24,7 +24,7 @@ const std::string kCourierFontName("Courier"); bool CompareFonts(NSFont* font1, NSFont* font2) { ATSFontRef id1 = CTFontGetPlatformFont(reinterpret_cast<CTFontRef>(font1), 0); ATSFontRef id2 = CTFontGetPlatformFont(reinterpret_cast<CTFontRef>(font2), 0); - + if (id1 != id2) { LOG(ERROR) << "ATSFontRefs for " << [[font1 fontName] UTF8String] @@ -33,7 +33,7 @@ bool CompareFonts(NSFont* font1, NSFont* font2) { << " are different"; return false; } - + CGFloat size1 = [font1 pointSize]; CGFloat size2 = [font2 pointSize]; if (size1 != size2) { @@ -49,12 +49,12 @@ bool CompareFonts(NSFont* font1, NSFont* font2) { traitsOfFont:font1]; NSFontTraitMask traits2 = [[NSFontManager sharedFontManager] traitsOfFont:font2]; - + bool is_bold1 = traits1 & NSBoldFontMask; bool is_bold2 = traits2 & NSBoldFontMask; bool is_italic1 = traits1 & NSItalicFontMask; bool is_italic2 = traits2 & NSItalicFontMask; - + if (is_bold1 != is_bold2 || is_italic1 != is_italic2) { LOG(ERROR) << "Style information for " << [[font1 fontName] UTF8String] @@ -63,7 +63,7 @@ bool CompareFonts(NSFont* font1, NSFont* font2) { << " are different"; return false; } - + return true; } @@ -82,12 +82,12 @@ TEST_F(FontSerializationTest, StyledFonts) { ASSERT_TRUE(plain_font != nil); FontDescriptor desc_plain(plain_font); EXPECT_TRUE(CompareFonts(plain_font, desc_plain.ToNSFont())); - + NSFont* bold_font = [NSFont boldSystemFontOfSize:30.0]; ASSERT_TRUE(bold_font != nil); FontDescriptor desc_bold(bold_font); EXPECT_TRUE(CompareFonts(bold_font, desc_bold.ToNSFont())); - + NSFont* italic_bold_font = [[NSFontManager sharedFontManager] fontWithFamily:base::SysUTF8ToNSString(kCourierFontName) diff --git a/content/common/font_loader_mac.h b/content/common/mac/font_loader.h index 410e076..7cd6682 100644 --- a/content/common/font_loader_mac.h +++ b/content/common/mac/font_loader.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_COMMON_FONT_LOADER_MAC_H_ -#define CONTENT_COMMON_FONT_LOADER_MAC_H_ +#ifndef CONTENT_COMMON_MAC_FONT_LOADER_H_ +#define CONTENT_COMMON_MAC_FONT_LOADER_H_ #pragma once #include <ApplicationServices/ApplicationServices.h> @@ -60,4 +60,4 @@ class FontLoader { ATSFontContainerRef* font_container); }; -#endif // CONTENT_COMMON_FONT_LOADER_MAC_H_ +#endif // CONTENT_COMMON_MAC_FONT_LOADER_H_ diff --git a/content/common/font_loader_mac.mm b/content/common/mac/font_loader.mm index 867e1d3..93eb03f 100644 --- a/content/common/font_loader_mac.mm +++ b/content/common/mac/font_loader.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/common/font_loader_mac.h" +#include "content/common/mac/font_loader.h" #import <Cocoa/Cocoa.h> diff --git a/content/common/sandbox_mac_fontloading_unittest.mm b/content/common/sandbox_mac_fontloading_unittest.mm index bca576d..911110f 100644 --- a/content/common/sandbox_mac_fontloading_unittest.mm +++ b/content/common/sandbox_mac_fontloading_unittest.mm @@ -9,7 +9,7 @@ #include "base/mac/scoped_cftyperef.h" #include "base/memory/scoped_ptr.h" #include "base/shared_memory.h" -#include "content/common/font_loader_mac.h" +#include "content/common/mac/font_loader.h" #include "content/common/sandbox_mac_unittest_helper.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 9a281f54..d127d71 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -40,7 +40,7 @@ #include "webkit/plugins/webplugininfo.h" #if defined(OS_MACOSX) -#include "content/common/font_descriptor_mac.h" +#include "content/common/mac/font_descriptor.h" #endif // Define enums used in this file inside an include-guard. |