diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-09 22:47:31 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-09 22:47:31 +0000 |
commit | 9a9712aa6811c21c6f79c73ab7fb2e5501081bcb (patch) | |
tree | b6a04384d2adbb4beada6c506effad710a3e353a /skia | |
parent | 109d31f08853a4aa5c64e3b52ad7d8bf1bce7196 (diff) | |
download | chromium_src-9a9712aa6811c21c6f79c73ab7fb2e5501081bcb.zip chromium_src-9a9712aa6811c21c6f79c73ab7fb2e5501081bcb.tar.gz chromium_src-9a9712aa6811c21c6f79c73ab7fb2e5501081bcb.tar.bz2 |
Linux: Fix early font free during printing.
The ownership model for this stuff (fonts, cairo canvas, etc.) is a bit brittle. Don't know how to improve it though.
BUG=23372
Review URL: http://codereview.chromium.org/270048
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28619 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r-- | skia/ext/vector_platform_device_linux.cc | 101 | ||||
-rw-r--r-- | skia/ext/vector_platform_device_linux.h | 7 |
2 files changed, 59 insertions, 49 deletions
diff --git a/skia/ext/vector_platform_device_linux.cc b/skia/ext/vector_platform_device_linux.cc index 31506b4..e3438e3 100644 --- a/skia/ext/vector_platform_device_linux.cc +++ b/skia/ext/vector_platform_device_linux.cc @@ -21,8 +21,6 @@ namespace { -FT_Library g_ft_library = NULL; // handle to FreeType library. - struct FontInfo { SkStream* font_stream; FT_Face ft_face; @@ -32,32 +30,31 @@ struct FontInfo { typedef std::map<uint32_t, FontInfo> MapFontId2FontInfo; -// NOTE: Only call this function when no further rendering will be performed, -// and/or the metafile is closed. -void CleanUpFonts() { - MapFontId2FontInfo* g_font_cache = Singleton<MapFontId2FontInfo>::get(); - DCHECK(g_font_cache); - - for (MapFontId2FontInfo::iterator it = g_font_cache->begin(); - it !=g_font_cache->end(); - ++it) { - DCHECK(it->second.cairo_face); - DCHECK(it->second.font_stream); - - cairo_font_face_destroy(it->second.cairo_face); - // |it->second.ft_face| is handled by Cairo. - it->second.font_stream->unref(); +// Wrapper for FT_Library that handles initialization and cleanup, and allows +// us to use a singleton. +class FtLibrary { + public: + FtLibrary() : library_(NULL) { + FT_Error ft_error = FT_Init_FreeType(&library_); + if (ft_error) { + DLOG(ERROR) << "Cannot initialize FreeType library for " \ + << "VectorPlatformDevice."; + } } - g_font_cache->clear(); -} -void CleanUpFreeType() { - if (g_ft_library) { - FT_Error ft_error = FT_Done_FreeType(g_ft_library); - g_ft_library = NULL; - DCHECK_EQ(ft_error, 0); + ~FtLibrary() { + if (library_) { + FT_Error ft_error = FT_Done_FreeType(library_); + library_ = NULL; + DCHECK_EQ(ft_error, 0); + } } -} + + FT_Library library() { return library_; } + + private: + FT_Library library_; +}; // Verify cairo surface after creation/modification. bool IsContextValid(cairo_t* context) { @@ -85,7 +82,8 @@ VectorPlatformDevice* VectorPlatformDevice::create(PlatformSurface context, VectorPlatformDevice::VectorPlatformDevice(PlatformSurface context, const SkBitmap& bitmap) - : PlatformDevice(bitmap), context_(context) { + : PlatformDevice(bitmap), + context_(context) { SkASSERT(bitmap.getConfig() == SkBitmap::kARGB_8888_Config); // Increase the reference count to keep the context alive. @@ -97,8 +95,6 @@ VectorPlatformDevice::VectorPlatformDevice(PlatformSurface context, VectorPlatformDevice::~VectorPlatformDevice() { // Un-ref |context_| since we referenced it in the constructor. cairo_destroy(context_); - CleanUpFonts(); - CleanUpFreeType(); } void VectorPlatformDevice::drawBitmap(const SkDraw& draw, @@ -339,8 +335,7 @@ void VectorPlatformDevice::drawPosText(const SkDraw& draw, } } else { // kFill_Style. // Selects correct font. - if (!SelectFontById( - context_, paint.getTypeface()->uniqueID())) { + if (!SelectFontById(paint.getTypeface()->uniqueID())) { SkASSERT(false); return; } @@ -568,21 +563,13 @@ void VectorPlatformDevice::LoadTransformToContext(const SkMatrix& matrix) { cairo_set_matrix(context_, &m); } -bool VectorPlatformDevice::SelectFontById(PlatformSurface context, - uint32_t font_id) { - DCHECK(IsContextValid(context)); +bool VectorPlatformDevice::SelectFontById(uint32_t font_id) { + DCHECK(IsContextValid(context_)); DCHECK(SkFontHost::ValidFontID(font_id)); - if (!g_ft_library) { - // Initializes FreeType library. - FT_Error ft_error = FT_Init_FreeType(&g_ft_library); - if (ft_error) { - DLOG(ERROR) << "Cannot initialize FreeType library for " \ - << "VectorPlatformDevice."; - g_ft_library = NULL; - return false; - } - } + FtLibrary* ft_library = Singleton<FtLibrary>::get(); + if (!ft_library->library()) + return false; // Checks if we have a cache hit. MapFontId2FontInfo* g_font_cache = Singleton<MapFontId2FontInfo>::get(); @@ -590,8 +577,8 @@ bool VectorPlatformDevice::SelectFontById(PlatformSurface context, MapFontId2FontInfo::iterator it = g_font_cache->find(font_id); if (it != g_font_cache->end()) { - cairo_set_font_face(context, it->second.cairo_face); - if (IsContextValid(context)) { + cairo_set_font_face(context_, it->second.cairo_face); + if (IsContextValid(context_)) { return true; } else { NOTREACHED() << "Cannot set font face in Cairo!"; @@ -607,7 +594,7 @@ bool VectorPlatformDevice::SelectFontById(PlatformSurface context, DCHECK(stream_size) << "The Font stream has nothing!"; FT_Error ft_error = FT_New_Memory_Face( - g_ft_library, + ft_library->library(), static_cast<FT_Byte*>( const_cast<void*>(new_font_info.font_stream->getMemoryBase())), stream_size, @@ -644,8 +631,8 @@ bool VectorPlatformDevice::SelectFontById(PlatformSurface context, // Inserts |new_font_info| info |g_font_cache|. (*g_font_cache)[font_id] = new_font_info; - cairo_set_font_face(context, new_font_info.cairo_face); - if (IsContextValid(context)) { + cairo_set_font_face(context_, new_font_info.cairo_face); + if (IsContextValid(context_)) { return true; } @@ -653,4 +640,22 @@ bool VectorPlatformDevice::SelectFontById(PlatformSurface context, return false; } +// static +void VectorPlatformDevice::ClearFontCache() { + MapFontId2FontInfo* g_font_cache = Singleton<MapFontId2FontInfo>::get(); + DCHECK(g_font_cache); + + for (MapFontId2FontInfo::iterator it = g_font_cache->begin(); + it !=g_font_cache->end(); + ++it) { + DCHECK(it->second.cairo_face); + DCHECK(it->second.font_stream); + + cairo_font_face_destroy(it->second.cairo_face); + // |it->second.ft_face| is handled by Cairo. + it->second.font_stream->unref(); + } + g_font_cache->clear(); +} + } // namespace skia diff --git a/skia/ext/vector_platform_device_linux.h b/skia/ext/vector_platform_device_linux.h index 8ec453b..118e708 100644 --- a/skia/ext/vector_platform_device_linux.h +++ b/skia/ext/vector_platform_device_linux.h @@ -57,6 +57,11 @@ class VectorPlatformDevice : public PlatformDevice { virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region); + // Clean up cached fonts. It is an error to call this while some + // VectorPlatformDevice callee is still using fonts created for it by this + // class. + static void ClearFontCache(); + protected: explicit VectorPlatformDevice(PlatformSurface context, const SkBitmap& bitmap); @@ -91,7 +96,7 @@ class VectorPlatformDevice : public PlatformDevice { // Selects the font associated with |font_id| in |context|. // Return true on success. - bool SelectFontById(PlatformSurface context, uint32_t font_id); + bool SelectFontById(uint32_t font_id); // Transformation assigned to the context. SkMatrix transform_; |