Chromium Code Reviews| Index: chrome/common/attributed_string_coder.mm |
| diff --git a/chrome/common/attributed_string_coder.mm b/chrome/common/attributed_string_coder.mm |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1c183683ecd143ee954ba24ad1c463828cbf098b |
| --- /dev/null |
| +++ b/chrome/common/attributed_string_coder.mm |
| @@ -0,0 +1,168 @@ |
| +// 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 "chrome/common/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 "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) { |
| + [decoded_string addAttributes:it->ToAttributesDictionary() |
| + range:it->effective_range().ToNSRange()]; |
| + } |
| + return [decoded_string.release() autorelease]; |
| +} |
| + |
| +// Data Types ////////////////////////////////////////////////////////////////// |
| + |
| +AttributedStringCoder::EncodedString::EncodedString(string16 string) |
| + : string_(string) { |
| +} |
| + |
| +AttributedStringCoder::EncodedString::EncodedString() |
| + : string_() { |
| +} |
| + |
| +AttributedStringCoder::FontAttribute::FontAttribute(NSDictionary* dict, |
| + ui::Range effective_range) |
| + : font_name_(), |
| + font_size_(0), |
| + effective_range_(effective_range) { |
| + NSFont* font = [dict objectForKey:NSFontAttributeName]; |
| + if (font) { |
| + font_name_ = base::SysNSStringToUTF8([font fontName]); |
|
jeremy
2011/04/12 09:44:06
Could you use a FontDescriptor (content/common/fon
Robert Sesek
2011/04/25 20:58:18
Done.
|
| + font_size_ = [font pointSize]; |
| + } |
| +} |
| + |
| +AttributedStringCoder::FontAttribute::FontAttribute(std::string name, |
| + float size, |
| + ui::Range range) |
| + : font_name_(name), |
| + font_size_(size), |
| + effective_range_(range) { |
| +} |
| + |
| +AttributedStringCoder::FontAttribute::FontAttribute() |
| + : font_name_(), |
| + font_size_(0), |
| + effective_range_() { |
| +} |
| + |
| +NSDictionary* AttributedStringCoder::FontAttribute::ToAttributesDictionary( |
| + void) const { |
| + DCHECK(ShouldEncode()); |
| + NSFont* font = [NSFont fontWithName:base::SysUTF8ToNSString(font_name_) |
| + size:font_size_]; |
| + return [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; |
| +} |
| + |
| +bool AttributedStringCoder::FontAttribute::ShouldEncode() const { |
| + return !font_name_.empty(); |
| +} |
| + |
| +} // namespace mac |
| + |
| +// IPC ParamTraits specialization ////////////////////////////////////////////// |
|
jeremy
2011/04/12 09:44:06
When deserializing values here, could you add some
Robert Sesek
2011/04/25 20:58:18
ui::Range protects against this in its own ParamTr
jeremy
2011/05/01 09:25:56
FontDescriptor's code uses the standard macros and
Robert Sesek
2011/05/02 15:43:31
Added a check that Range::GetMin() and GetMax() ar
|
| + |
| +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_name()); |
| + WriteParam(m, p.font_size()); |
| + WriteParam(m, p.effective_range()); |
| +} |
| + |
| +bool ParamTraits<AttributedStringCoder::FontAttribute>::Read( |
| + const Message* m, void** iter, param_type* p) { |
| + bool success = true; |
| + |
| + std::string name; |
| + success &= ReadParam(m, iter, &name); |
| + |
| + float size; |
| + success &= ReadParam(m, iter, &size); |
| + |
| + ui::Range range; |
| + success &= ReadParam(m, iter, &range); |
| + |
| + if (success) { |
| + *p = AttributedStringCoder::FontAttribute(name, size, range); |
| + } |
| + return success; |
| +} |
| + |
| +void ParamTraits<AttributedStringCoder::FontAttribute>::Log( |
| + const param_type& p, std::string* l) { |
| +} |
| + |
| +} // namespace IPC |