summaryrefslogtreecommitdiffstats
path: root/skia
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-09 22:47:31 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-09 22:47:31 +0000
commit9a9712aa6811c21c6f79c73ab7fb2e5501081bcb (patch)
treeb6a04384d2adbb4beada6c506effad710a3e353a /skia
parent109d31f08853a4aa5c64e3b52ad7d8bf1bce7196 (diff)
downloadchromium_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.cc101
-rw-r--r--skia/ext/vector_platform_device_linux.h7
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_;