summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormmoss@chromium.org <mmoss@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-28 19:50:39 +0000
committermmoss@chromium.org <mmoss@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-28 19:50:39 +0000
commitb33892e62a94b183df6892cbe0edce7c523e4ba3 (patch)
tree1cc74750efc53a50aaa7b70c70d8ef1067098736
parent9132d2b58b32ec01d3859dc96c058124bd6c347d (diff)
downloadchromium_src-b33892e62a94b183df6892cbe0edce7c523e4ba3.zip
chromium_src-b33892e62a94b183df6892cbe0edce7c523e4ba3.tar.gz
chromium_src-b33892e62a94b183df6892cbe0edce7c523e4ba3.tar.bz2
Move cairo font handling from printing to skia to avoid circular dependency.
http://crbug.com/22792 Review URL: http://codereview.chromium.org/245027 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27395 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--printing/pdf_ps_metafile_linux.cc138
-rw-r--r--printing/pdf_ps_metafile_linux.h4
-rw-r--r--skia/ext/vector_platform_device_linux.cc149
-rw-r--r--skia/ext/vector_platform_device_linux.h5
4 files changed, 150 insertions, 146 deletions
diff --git a/printing/pdf_ps_metafile_linux.cc b/printing/pdf_ps_metafile_linux.cc
index d5fe5fb..aa9a9d32 100644
--- a/printing/pdf_ps_metafile_linux.cc
+++ b/printing/pdf_ps_metafile_linux.cc
@@ -7,64 +7,16 @@
#include <stdio.h>
#include <cairo.h>
-#include <cairo-ft.h>
#include <cairo-pdf.h>
#include <cairo-ps.h>
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-#include <map>
-
#include "base/eintr_wrapper.h"
#include "base/file_descriptor_posix.h"
#include "base/file_util.h"
#include "base/logging.h"
-#include "base/singleton.h"
-#include "third_party/skia/include/core/SkFontHost.h"
-#include "third_party/skia/include/core/SkStream.h"
-#include "third_party/skia/include/core/SkTypeface.h"
namespace {
-FT_Library g_ft_library = NULL; // handle to FreeType library.
-
-struct FontInfo {
- SkStream* font_stream;
- FT_Face ft_face;
- cairo_font_face_t* cairo_face;
- cairo_user_data_key_t data_key;
-};
-
-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();
- }
- 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);
- }
-}
-
// Tests if |surface| is valid.
bool IsSurfaceValid(cairo_surface_t* surface) {
return cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS;
@@ -127,15 +79,6 @@ bool PdfPsMetafile::Init() {
// page_surface_, and page_context_ are NULL, and current_page_ is empty.
DCHECK(!context_);
DCHECK(all_pages_.empty());
- DCHECK(!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 PdfPsMetafile.";
- g_ft_library = NULL;
- return false;
- }
// Creates an 1 by 1 Cairo surface for entire PDF/PS file.
// The size for each page will be overwritten later in StartPage().
@@ -162,7 +105,6 @@ bool PdfPsMetafile::Init() {
if (!IsSurfaceValid(surface_)) {
DLOG(ERROR) << "Cannot create Cairo surface for PdfPsMetafile!";
CleanUpSurface(&surface_);
- CleanUpFreeType();
return false;
}
@@ -172,7 +114,6 @@ bool PdfPsMetafile::Init() {
DLOG(ERROR) << "Cannot create Cairo context for PdfPsMetafile!";
CleanUpContext(&context_);
CleanUpSurface(&surface_);
- CleanUpFreeType();
return false;
}
@@ -363,83 +304,6 @@ void PdfPsMetafile::Close() {
CleanUpContext(&context_);
CleanUpSurface(&surface_);
- CleanUpFonts();
- CleanUpFreeType();
-}
-
-// static
-bool PdfPsMetafile::SelectFontById(cairo_t* context, uint32_t font_id) {
- DCHECK(IsContextValid(context));
- DCHECK(SkFontHost::ValidFontID(font_id));
- DCHECK(g_ft_library);
-
- // Checks if we have a cache hit.
- MapFontId2FontInfo* g_font_cache = Singleton<MapFontId2FontInfo>::get();
- DCHECK(g_font_cache);
-
- 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)) {
- return true;
- } else {
- NOTREACHED() << "Cannot set font face in Cairo!";
- return false;
- }
- }
-
- // Cache missed. We need to load and create the font.
- FontInfo new_font_info = {0};
- new_font_info.font_stream = SkFontHost::OpenStream(font_id);
- DCHECK(new_font_info.font_stream);
- size_t stream_size = new_font_info.font_stream->getLength();
- DCHECK(stream_size) << "The Font stream has nothing!";
-
- FT_Error ft_error = FT_New_Memory_Face(
- g_ft_library,
- static_cast<FT_Byte*>(
- const_cast<void*>(new_font_info.font_stream->getMemoryBase())),
- stream_size,
- 0,
- &new_font_info.ft_face);
-
- if (ft_error) {
- new_font_info.font_stream->unref();
- DLOG(ERROR) << "Cannot create FT_Face!";
- SkASSERT(false);
- return false;
- }
-
- new_font_info.cairo_face = cairo_ft_font_face_create_for_ft_face(
- new_font_info.ft_face, 0);
- DCHECK(new_font_info.cairo_face) << "Cannot create font in Cairo!";
-
- // Manage |new_font_info.ft_face|'s life by Cairo.
- cairo_status_t status = cairo_font_face_set_user_data(
- new_font_info.cairo_face,
- &new_font_info.data_key,
- new_font_info.ft_face,
- reinterpret_cast<cairo_destroy_func_t>(FT_Done_Face));
-
- if (status != CAIRO_STATUS_SUCCESS) {
- DLOG(ERROR) << "Cannot set font's user data in Cairo!";
- cairo_font_face_destroy(new_font_info.cairo_face);
- FT_Done_Face(new_font_info.ft_face);
- new_font_info.font_stream->unref();
- SkASSERT(false);
- return false;
- }
-
- // 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)) {
- return true;
- }
-
- DLOG(ERROR) << "Connot set font face in Cairo!";
- return false;
}
unsigned int PdfPsMetafile::GetDataSize() const {
@@ -505,8 +369,6 @@ void PdfPsMetafile::CleanUpAll() {
CleanUpSurface(&page_surface_);
current_page_.clear();
all_pages_.clear();
- CleanUpFonts();
- CleanUpFreeType();
}
} // namespace printing
diff --git a/printing/pdf_ps_metafile_linux.h b/printing/pdf_ps_metafile_linux.h
index faf6ab7..6f92b66 100644
--- a/printing/pdf_ps_metafile_linux.h
+++ b/printing/pdf_ps_metafile_linux.h
@@ -68,10 +68,6 @@ class PdfPsMetafile {
// Closes resulting PDF/PS file. No further rendering is allowed.
void Close();
- // Selects the font associated with |font_id| in |context|.
- // Return true on success.
- static bool SelectFontById(cairo_t* context, uint32_t font_id);
-
// Returns size of PDF/PS contents stored in buffer |all_pages_|.
// This function should ONLY be called after PDF/PS file is closed.
unsigned int GetDataSize() const;
diff --git a/skia/ext/vector_platform_device_linux.cc b/skia/ext/vector_platform_device_linux.cc
index f0afbef..31506b4 100644
--- a/skia/ext/vector_platform_device_linux.cc
+++ b/skia/ext/vector_platform_device_linux.cc
@@ -5,10 +5,67 @@
#include "skia/ext/vector_platform_device.h"
#include <cairo.h>
+#include <cairo-ft.h>
-#include "printing/pdf_ps_metafile_linux.h"
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#include <map>
+
+#include "third_party/skia/include/core/SkFontHost.h"
+#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/core/SkTypeface.h"
+#include "base/logging.h"
+#include "base/singleton.h"
+
+namespace {
+
+FT_Library g_ft_library = NULL; // handle to FreeType library.
+
+struct FontInfo {
+ SkStream* font_stream;
+ FT_Face ft_face;
+ cairo_font_face_t* cairo_face;
+ cairo_user_data_key_t data_key;
+};
+
+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();
+ }
+ 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);
+ }
+}
+
+// Verify cairo surface after creation/modification.
+bool IsContextValid(cairo_t* context) {
+ return cairo_status(context) == CAIRO_STATUS_SUCCESS;
+}
+
+} // namespace
+
namespace skia {
VectorPlatformDevice* VectorPlatformDevice::create(PlatformSurface context,
@@ -40,6 +97,8 @@ 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,
@@ -280,7 +339,7 @@ void VectorPlatformDevice::drawPosText(const SkDraw& draw,
}
} else { // kFill_Style.
// Selects correct font.
- if (!printing::PdfPsMetafile::SelectFontById(
+ if (!SelectFontById(
context_, paint.getTypeface()->uniqueID())) {
SkASSERT(false);
return;
@@ -509,5 +568,89 @@ void VectorPlatformDevice::LoadTransformToContext(const SkMatrix& matrix) {
cairo_set_matrix(context_, &m);
}
-} // namespace skia
+bool VectorPlatformDevice::SelectFontById(PlatformSurface context,
+ 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;
+ }
+ }
+
+ // Checks if we have a cache hit.
+ MapFontId2FontInfo* g_font_cache = Singleton<MapFontId2FontInfo>::get();
+ DCHECK(g_font_cache);
+
+ 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)) {
+ return true;
+ } else {
+ NOTREACHED() << "Cannot set font face in Cairo!";
+ return false;
+ }
+ }
+
+ // Cache missed. We need to load and create the font.
+ FontInfo new_font_info = {0};
+ new_font_info.font_stream = SkFontHost::OpenStream(font_id);
+ DCHECK(new_font_info.font_stream);
+ size_t stream_size = new_font_info.font_stream->getLength();
+ DCHECK(stream_size) << "The Font stream has nothing!";
+
+ FT_Error ft_error = FT_New_Memory_Face(
+ g_ft_library,
+ static_cast<FT_Byte*>(
+ const_cast<void*>(new_font_info.font_stream->getMemoryBase())),
+ stream_size,
+ 0,
+ &new_font_info.ft_face);
+
+ if (ft_error) {
+ new_font_info.font_stream->unref();
+ DLOG(ERROR) << "Cannot create FT_Face!";
+ SkASSERT(false);
+ return false;
+ }
+ new_font_info.cairo_face = cairo_ft_font_face_create_for_ft_face(
+ new_font_info.ft_face, 0);
+ DCHECK(new_font_info.cairo_face) << "Cannot create font in Cairo!";
+
+ // Manage |new_font_info.ft_face|'s life by Cairo.
+ cairo_status_t status = cairo_font_face_set_user_data(
+ new_font_info.cairo_face,
+ &new_font_info.data_key,
+ new_font_info.ft_face,
+ reinterpret_cast<cairo_destroy_func_t>(FT_Done_Face));
+
+ if (status != CAIRO_STATUS_SUCCESS) {
+ DLOG(ERROR) << "Cannot set font's user data in Cairo!";
+ cairo_font_face_destroy(new_font_info.cairo_face);
+ FT_Done_Face(new_font_info.ft_face);
+ new_font_info.font_stream->unref();
+ SkASSERT(false);
+ return false;
+ }
+
+ // 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)) {
+ return true;
+ }
+
+ DLOG(ERROR) << "Connot set font face in Cairo!";
+ return false;
+}
+
+} // namespace skia
diff --git a/skia/ext/vector_platform_device_linux.h b/skia/ext/vector_platform_device_linux.h
index 67f1c48..8ec453b 100644
--- a/skia/ext/vector_platform_device_linux.h
+++ b/skia/ext/vector_platform_device_linux.h
@@ -89,6 +89,10 @@ class VectorPlatformDevice : public PlatformDevice {
// Use matrix to set up context's transformation.
void LoadTransformToContext(const SkMatrix& matrix);
+ // Selects the font associated with |font_id| in |context|.
+ // Return true on success.
+ bool SelectFontById(PlatformSurface context, uint32_t font_id);
+
// Transformation assigned to the context.
SkMatrix transform_;
@@ -106,4 +110,3 @@ class VectorPlatformDevice : public PlatformDevice {
} // namespace skia
#endif // SKIA_EXT_VECTOR_PLATFORM_DEVICE_LINUX_H_
-