summaryrefslogtreecommitdiffstats
path: root/ui/gfx
diff options
context:
space:
mode:
authorasvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-23 21:17:30 +0000
committerasvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-23 21:17:30 +0000
commit7e7a004713c446d6b888f75901f73176a0282982 (patch)
tree8728238851f449943cc617f2045a1c678e8973f2 /ui/gfx
parent65a78cbf36f6fd634edecfcd8439e171135eec18 (diff)
downloadchromium_src-7e7a004713c446d6b888f75901f73176a0282982.zip
chromium_src-7e7a004713c446d6b888f75901f73176a0282982.tar.gz
chromium_src-7e7a004713c446d6b888f75901f73176a0282982.tar.bz2
Fix memory leaks in RenderTextMac.
This addresses a TODO from http://crrev.com/147862 to not leak CFAttributedString attributes and additionally ensures that the CTFontRef is properly disposed. Also renames SkColorToCGColorRef() to CGColorCreateFromSkColor() to be clear that it follows the Create rule. BUG=125664 TEST=No leaks on waterfall. Review URL: https://chromiumcodereview.appspot.com/10808084 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@147948 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx')
-rw-r--r--ui/gfx/render_text_mac.cc29
-rw-r--r--ui/gfx/render_text_mac.h4
2 files changed, 23 insertions, 10 deletions
diff --git a/ui/gfx/render_text_mac.cc b/ui/gfx/render_text_mac.cc
index b157ecc..4b02924 100644
--- a/ui/gfx/render_text_mac.cc
+++ b/ui/gfx/render_text_mac.cc
@@ -155,6 +155,7 @@ bool RenderTextMac::IsCursorablePosition(size_t position) {
void RenderTextMac::ResetLayout() {
line_.reset();
+ attributes_.reset();
runs_.clear();
runs_valid_ = false;
}
@@ -172,7 +173,8 @@ void RenderTextMac::EnsureLayout() {
const void* keys[] = { kCTFontAttributeName };
const void* values[] = { ct_font };
base::mac::ScopedCFTypeRef<CFDictionaryRef> attributes(
- CFDictionaryCreate(NULL, keys, values, arraysize(keys), NULL, NULL));
+ CFDictionaryCreate(NULL, keys, values, arraysize(keys), NULL,
+ &kCFTypeDictionaryValueCallBacks));
base::mac::ScopedCFTypeRef<CFStringRef> cf_text(
base::SysUTF16ToCFStringRef(text()));
@@ -228,6 +230,11 @@ RenderTextMac::TextRun::~TextRun() {
void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string,
CTFontRef font) {
+ // Clear attributes and reserve space to hold the maximum number of entries,
+ // which is at most three per style range per the code below.
+ attributes_.reset(CFArrayCreateMutable(NULL, 3 * style_ranges().size(),
+ &kCFTypeArrayCallBacks));
+
// https://developer.apple.com/library/mac/#documentation/Carbon/Reference/CoreText_StringAttributes_Ref/Reference/reference.html
for (size_t i = 0; i < style_ranges().size(); ++i) {
const StyleRange& style = style_ranges()[i];
@@ -235,23 +242,24 @@ void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string,
style.range.length());
// Note: CFAttributedStringSetAttribute() does not appear to retain the
- // values passed in, as can be verified via CFGetRetainCount().
- //
- // TODO(asvitkine): The attributed string appears to hold weak refs to these
- // objects (it does not release them either), so we need to keep track of
- // them ourselves and release them at an appropriate time.
+ // values passed in, as can be verified via CFGetRetainCount(). To ensure
+ // the attribute objects do not leak, they are saved to |attributes_|.
- CGColorRef foreground = gfx::SkColorToCGColorRef(style.foreground);
+ base::mac::ScopedCFTypeRef<CGColorRef> foreground(
+ gfx::CGColorCreateFromSkColor(style.foreground));
CFAttributedStringSetAttribute(attr_string, range,
kCTForegroundColorAttributeName,
foreground);
+ CFArrayAppendValue(attributes_, foreground);
if (style.underline) {
CTUnderlineStyle value = kCTUnderlineStyleSingle;
- CFNumberRef underline = CFNumberCreate(NULL, kCFNumberSInt32Type, &value);
+ base::mac::ScopedCFTypeRef<CFNumberRef> underline(
+ CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
CFAttributedStringSetAttribute(attr_string, range,
kCTUnderlineStyleAttributeName,
underline);
+ CFArrayAppendValue(attributes_, underline);
}
if (style.font_style & (Font::BOLD | Font::ITALIC)) {
@@ -260,12 +268,13 @@ void RenderTextMac::ApplyStyles(CFMutableAttributedStringRef attr_string,
traits |= kCTFontBoldTrait;
if (style.font_style & Font::ITALIC)
traits |= kCTFontItalicTrait;
- CTFontRef styled_font =
- CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits);
+ base::mac::ScopedCFTypeRef<CTFontRef> styled_font(
+ CTFontCreateCopyWithSymbolicTraits(font, 0.0, NULL, traits, traits));
// TODO(asvitkine): Handle |styled_font| == NULL case better.
if (styled_font) {
CFAttributedStringSetAttribute(attr_string, range, kCTFontAttributeName,
styled_font);
+ CFArrayAppendValue(attributes_, styled_font);
}
}
}
diff --git a/ui/gfx/render_text_mac.h b/ui/gfx/render_text_mac.h
index ccd9c75..1d558ad 100644
--- a/ui/gfx/render_text_mac.h
+++ b/ui/gfx/render_text_mac.h
@@ -75,6 +75,10 @@ class RenderTextMac : public RenderText {
// The Core Text line of text. Created by |EnsureLayout()|.
base::mac::ScopedCFTypeRef<CTLineRef> line_;
+ // Array to hold CFAttributedString attributes that allows Core Text to hold
+ // weak references to them without leaking.
+ base::mac::ScopedCFTypeRef<CFMutableArrayRef> attributes_;
+
// Visual dimensions of the text. Computed by |EnsureLayout()|.
Size string_size_;