summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--printing/metafile_impl.h2
-rw-r--r--printing/pdf_metafile_cairo_linux.cc259
-rw-r--r--printing/pdf_metafile_cairo_linux.h88
-rw-r--r--printing/pdf_metafile_cairo_linux_unittest.cc85
-rw-r--r--printing/printing.gyp3
-rw-r--r--skia/ext/vector_platform_device_cairo_linux.cc695
-rw-r--r--skia/ext/vector_platform_device_cairo_linux.h131
-rw-r--r--skia/skia.gyp2
8 files changed, 0 insertions, 1265 deletions
diff --git a/printing/metafile_impl.h b/printing/metafile_impl.h
index dd09e09..38c68a3 100644
--- a/printing/metafile_impl.h
+++ b/printing/metafile_impl.h
@@ -9,8 +9,6 @@
#include "printing/emf_win.h"
#elif defined(OS_MACOSX)
#include "printing/pdf_metafile_cg_mac.h"
-#elif defined(OS_POSIX)
-#include "printing/pdf_metafile_cairo_linux.h"
#endif
#if !defined(OS_MACOSX) || defined(USE_SKIA)
diff --git a/printing/pdf_metafile_cairo_linux.cc b/printing/pdf_metafile_cairo_linux.cc
deleted file mode 100644
index af2aa5c..0000000
--- a/printing/pdf_metafile_cairo_linux.cc
+++ /dev/null
@@ -1,259 +0,0 @@
-// 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 "printing/pdf_metafile_cairo_linux.h"
-
-#include <stdio.h>
-
-#include <cairo.h>
-#include <cairo-pdf.h>
-
-#include "base/eintr_wrapper.h"
-#include "base/file_descriptor_posix.h"
-#include "base/file_util.h"
-#include "base/logging.h"
-#include "printing/units.h"
-#include "skia/ext/vector_platform_device_cairo_linux.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/size.h"
-
-namespace {
-
-// Tests if |surface| is valid.
-bool IsSurfaceValid(cairo_surface_t* surface) {
- return cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS;
-}
-
-// Tests if |context| is valid.
-bool IsContextValid(cairo_t* context) {
- return cairo_status(context) == CAIRO_STATUS_SUCCESS;
-}
-
-// Destroys and resets |surface|.
-void CleanUpSurface(cairo_surface_t** surface) {
- if (*surface) {
- cairo_surface_destroy(*surface);
- *surface = NULL;
- }
-}
-
-// Destroys and resets |context|.
-void CleanUpContext(cairo_t** context) {
- if (*context) {
- cairo_destroy(*context);
- *context = NULL;
- }
-}
-
-// Callback function for Cairo to write PDF stream.
-// |dst_buffer| is actually a pointer of type `std::string*`.
-cairo_status_t WriteCairoStream(void* dst_buffer,
- const unsigned char* src_data,
- unsigned int src_data_length) {
- DCHECK(dst_buffer);
- DCHECK(src_data);
- DCHECK_GT(src_data_length, 0u);
-
- std::string* buffer = reinterpret_cast<std::string*>(dst_buffer);
- buffer->append(reinterpret_cast<const char*>(src_data), src_data_length);
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-} // namespace
-
-namespace printing {
-
-PdfMetafileCairo::PdfMetafileCairo()
- : surface_(NULL),
- context_(NULL),
- current_data_(NULL) {
-}
-
-PdfMetafileCairo::~PdfMetafileCairo() {
- // Releases all resources if we forgot to do so.
- CleanUpAll();
-}
-
-bool PdfMetafileCairo::Init() {
- // We need to check |current_data_| to ensure Init/InitFromData has not been
- // called before.
- DCHECK(!current_data_);
-
- current_data_ = &cairo_data_;
- // Creates an 1 by 1 Cairo surface for the entire PDF file.
- // The size for each page will be overwritten later in StartPage().
- surface_ = cairo_pdf_surface_create_for_stream(WriteCairoStream,
- current_data_, 1, 1);
-
- // Cairo always returns a valid pointer.
- // Hence, we have to check if it points to a "nil" object.
- if (!IsSurfaceValid(surface_)) {
- DLOG(ERROR) << "Cannot create Cairo surface for PdfMetafileCairo!";
- CleanUpSurface(&surface_);
- return false;
- }
-
- // Creates a context.
- context_ = cairo_create(surface_);
- if (!IsContextValid(context_)) {
- DLOG(ERROR) << "Cannot create Cairo context for PdfMetafileCairo!";
- CleanUpContext(&context_);
- CleanUpSurface(&surface_);
- return false;
- }
-
- return true;
-}
-
-bool PdfMetafileCairo::InitFromData(const void* src_buffer,
- uint32 src_buffer_size) {
- if (src_buffer == NULL || src_buffer_size == 0)
- return false;
-
- raw_data_ = std::string(reinterpret_cast<const char*>(src_buffer),
- src_buffer_size);
- current_data_ = &raw_data_;
- return true;
-}
-
-SkDevice* PdfMetafileCairo::StartPageForVectorCanvas(
- const gfx::Size& page_size, const gfx::Rect& content_area,
- const float& scale_factor) {
- if (!StartPage(page_size, content_area, scale_factor))
- return NULL;
-
- return skia::VectorPlatformDeviceCairo::CreateDevice(
- context_, page_size.width(), page_size.height(), true);
-}
-
-bool PdfMetafileCairo::StartPage(const gfx::Size& page_size,
- const gfx::Rect& content_area,
- const float& scale_factor) {
- DCHECK(IsSurfaceValid(surface_));
- DCHECK(IsContextValid(context_));
- // Passing this check implies page_surface_ is NULL, and current_page_ is
- // empty.
- DCHECK_GT(page_size.width(), 0);
- DCHECK_GT(page_size.height(), 0);
- // |scale_factor| is not supported yet.
- DCHECK_EQ(scale_factor, 1);
-
- // Don't let WebKit draw over the margins.
- cairo_surface_set_device_offset(surface_,
- content_area.x(),
- content_area.y());
-
- cairo_pdf_surface_set_size(surface_, page_size.width(), page_size.height());
- return context_ != NULL;
-}
-
-bool PdfMetafileCairo::FinishPage() {
- DCHECK(IsSurfaceValid(surface_));
- DCHECK(IsContextValid(context_));
-
- // Flushes all rendering for current page.
- cairo_surface_flush(surface_);
- cairo_show_page(context_);
- return true;
-}
-
-bool PdfMetafileCairo::FinishDocument() {
- DCHECK(IsSurfaceValid(surface_));
- DCHECK(IsContextValid(context_));
-
- cairo_surface_finish(surface_);
-
- DCHECK(!cairo_data_.empty()); // Make sure we did get something.
-
- CleanUpContext(&context_);
- CleanUpSurface(&surface_);
- return true;
-}
-
-uint32 PdfMetafileCairo::GetDataSize() const {
- // We need to check at least these two members to ensure that either Init()
- // has been called to initialize |data_|, or metafile has been closed.
- DCHECK(!context_);
- DCHECK(!current_data_->empty());
-
- return current_data_->size();
-}
-
-bool PdfMetafileCairo::GetData(void* dst_buffer, uint32 dst_buffer_size) const {
- DCHECK(dst_buffer);
- DCHECK_GT(dst_buffer_size, 0u);
- memcpy(dst_buffer, current_data_->data(), dst_buffer_size);
-
- return true;
-}
-
-cairo_t* PdfMetafileCairo::context() const {
- return context_;
-}
-
-bool PdfMetafileCairo::SaveTo(const FilePath& file_path) const {
- // We need to check at least these two members to ensure that either Init()
- // has been called to initialize |data_|, or metafile has been closed.
- DCHECK(!context_);
- DCHECK(!current_data_->empty());
-
- bool success = true;
- if (file_util::WriteFile(file_path, current_data_->data(), GetDataSize())
- != static_cast<int>(GetDataSize())) {
- DLOG(ERROR) << "Failed to save file " << file_path.value().c_str();
- success = false;
- }
- return success;
-}
-
-gfx::Rect PdfMetafileCairo::GetPageBounds(unsigned int page_number) const {
- NOTIMPLEMENTED();
- return gfx::Rect();
-}
-
-unsigned int PdfMetafileCairo::GetPageCount() const {
- NOTIMPLEMENTED();
- return 1;
-}
-
-#if defined(OS_CHROMEOS)
-bool PdfMetafileCairo::SaveToFD(const base::FileDescriptor& fd) const {
- // We need to check at least these two members to ensure that either Init()
- // has been called to initialize |data_|, or metafile has been closed.
- DCHECK(!context_);
- DCHECK(!current_data_->empty());
-
- if (fd.fd < 0) {
- DLOG(ERROR) << "Invalid file descriptor!";
- return false;
- }
-
- bool success = true;
- if (file_util::WriteFileDescriptor(fd.fd, current_data_->data(),
- GetDataSize()) < 0) {
- DLOG(ERROR) << "Failed to save file with fd " << fd.fd;
- success = false;
- }
-
- if (fd.auto_close) {
- if (HANDLE_EINTR(close(fd.fd)) < 0) {
- DPLOG(WARNING) << "close";
- success = false;
- }
- }
-
- return success;
-}
-#endif // if defined(OS_CHROMEOS)
-
-void PdfMetafileCairo::CleanUpAll() {
- CleanUpContext(&context_);
- CleanUpSurface(&surface_);
- cairo_data_.clear();
- raw_data_.clear();
- skia::VectorPlatformDeviceCairo::ClearFontCache();
-}
-
-} // namespace printing
diff --git a/printing/pdf_metafile_cairo_linux.h b/printing/pdf_metafile_cairo_linux.h
deleted file mode 100644
index 28c0698..0000000
--- a/printing/pdf_metafile_cairo_linux.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// 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.
-
-#ifndef PRINTING_PDF_METAFILE_CAIRO_LINUX_H_
-#define PRINTING_PDF_METAFILE_CAIRO_LINUX_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/gtest_prod_util.h"
-#include "printing/metafile.h"
-
-namespace gfx {
-class Point;
-class Rect;
-class Size;
-}
-
-typedef struct _cairo_surface cairo_surface_t;
-
-namespace printing {
-
-// This class uses Cairo graphics library to generate PDF stream and stores
-// rendering results in a string buffer.
-class PRINTING_EXPORT PdfMetafileCairo : public Metafile {
- public:
- PdfMetafileCairo();
- virtual ~PdfMetafileCairo();
-
- // Metafile methods.
- virtual bool Init();
-
- // Calling InitFromData() sets the data for this metafile and masks data
- // induced by previous calls to Init() or InitFromData(), even if drawing
- // continues on the surface returned by a previous call to Init().
- virtual bool InitFromData(const void* src_buffer, uint32 src_buffer_size);
-
- virtual SkDevice* StartPageForVectorCanvas(
- const gfx::Size& page_size, const gfx::Rect& content_area,
- const float& scale_factor);
-
- virtual bool StartPage(const gfx::Size& page_size,
- const gfx::Rect& content_area,
- const float& scale_factor);
- virtual bool FinishPage();
- virtual bool FinishDocument();
-
- virtual uint32 GetDataSize() const;
- virtual bool GetData(void* dst_buffer, uint32 dst_buffer_size) const;
-
- virtual bool SaveTo(const FilePath& file_path) const;
-
- virtual gfx::Rect GetPageBounds(unsigned int page_number) const;
- virtual unsigned int GetPageCount() const;
-
- virtual cairo_t* context() const;
-
-#if defined(OS_CHROMEOS)
- virtual bool SaveToFD(const base::FileDescriptor& fd) const;
-#endif // if defined(OS_CHROMEOS)
-
- private:
- // Cleans up all resources.
- void CleanUpAll();
-
- // Cairo surface and context for entire PDF file.
- cairo_surface_t* surface_;
- cairo_t* context_;
-
- // Buffer stores PDF contents for entire PDF file.
- std::string cairo_data_;
- // Buffer stores PDF contents. It can only be populated from InitFromData().
- // Any calls to StartPage(), FinishPage(), FinishDocument() do not affect
- // this buffer.
- // Note: Such calls will result in DCHECK errors if Init() has not been called
- // first.
- std::string raw_data_;
- // Points to the appropriate buffer depending on the way the object was
- // initialized (Init() vs InitFromData()).
- std::string* current_data_;
-
- DISALLOW_COPY_AND_ASSIGN(PdfMetafileCairo);
-};
-
-} // namespace printing
-
-#endif // PRINTING_PDF_METAFILE_CAIRO_LINUX_H_
diff --git a/printing/pdf_metafile_cairo_linux_unittest.cc b/printing/pdf_metafile_cairo_linux_unittest.cc
deleted file mode 100644
index 0ea08f81..0000000
--- a/printing/pdf_metafile_cairo_linux_unittest.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-// 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 "printing/pdf_metafile_cairo_linux.h"
-
-#include <fcntl.h>
-#include <string>
-#include <vector>
-
-#include "base/file_descriptor_posix.h"
-#include "base/file_path.h"
-#include "base/file_util.h"
-#include "base/string_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/rect.h"
-#include "ui/gfx/size.h"
-
-typedef struct _cairo cairo_t;
-
-namespace {
-
-class PdfMetafileCairoTest : public testing::Test {};
-
-} // namespace
-
-namespace printing {
-
-TEST_F(PdfMetafileCairoTest, Pdf) {
- // Tests in-renderer constructor.
- printing::PdfMetafileCairo pdf;
- EXPECT_TRUE(pdf.Init());
-
- // Renders page 1.
- EXPECT_TRUE(pdf.StartPage(gfx::Size(72, 73), gfx::Rect(4, 5, 64, 63), 1));
- // In theory, we should use Cairo to draw something on |context|.
- EXPECT_TRUE(pdf.FinishPage());
-
- // Renders page 2.
- EXPECT_TRUE(pdf.StartPage(gfx::Size(72, 73), gfx::Rect(4, 5, 64, 63), 1));
- // In theory, we should use Cairo to draw something on |context|.
- EXPECT_TRUE(pdf.FinishPage());
-
- // Closes the file.
- pdf.FinishDocument();
-
- // Checks data size.
- uint32 size = pdf.GetDataSize();
- EXPECT_GT(size, 0u);
-
- // Gets resulting data.
- std::vector<char> buffer(size, 0x00);
- pdf.GetData(&buffer.front(), size);
-
- // Tests another constructor.
- printing::PdfMetafileCairo pdf2;
- EXPECT_TRUE(pdf2.InitFromData(&buffer.front(), size));
-
- // Tries to get the first 4 characters from pdf2.
- std::vector<char> buffer2(4, 0x00);
- pdf2.GetData(&buffer2.front(), 4);
-
- // Tests if the header begins with "%PDF".
- std::string header(&buffer2.front(), 4);
- EXPECT_EQ(header.find("%PDF", 0), 0u);
-
- // Tests if we can save data.
- EXPECT_TRUE(pdf.SaveTo(FilePath("/dev/null")));
-
- // Test overriding the metafile with raw data.
- printing::PdfMetafileCairo pdf3;
- EXPECT_TRUE(pdf3.Init());
- EXPECT_TRUE(pdf3.StartPage(gfx::Size(72, 73), gfx::Rect(4, 5, 64, 63), 1));
- std::string test_raw_data = "Dummy PDF";
- EXPECT_TRUE(pdf3.InitFromData(test_raw_data.c_str(), test_raw_data.size()));
- EXPECT_TRUE(pdf3.FinishPage());
- pdf3.FinishDocument();
- size = pdf3.GetDataSize();
- EXPECT_EQ(test_raw_data.size(), size);
- std::string output;
- pdf3.GetData(WriteInto(&output, size + 1), size);
- EXPECT_EQ(test_raw_data, output);
-}
-
-} // namespace printing
diff --git a/printing/printing.gyp b/printing/printing.gyp
index 256108e..4d7aa20 100644
--- a/printing/printing.gyp
+++ b/printing/printing.gyp
@@ -50,8 +50,6 @@
'page_setup.cc',
'page_setup.h',
'page_size_margins.h',
- 'pdf_metafile_cairo_linux.cc',
- 'pdf_metafile_cairo_linux.h',
'pdf_metafile_cg_mac.cc',
'pdf_metafile_cg_mac.h',
'pdf_metafile_skia.h',
@@ -177,7 +175,6 @@
'page_number_unittest.cc',
'page_range_unittest.cc',
'page_setup_unittest.cc',
- 'pdf_metafile_cairo_linux_unittest.cc',
'pdf_metafile_cg_mac_unittest.cc',
'printed_page_unittest.cc',
'printing_context_win_unittest.cc',
diff --git a/skia/ext/vector_platform_device_cairo_linux.cc b/skia/ext/vector_platform_device_cairo_linux.cc
deleted file mode 100644
index 1d31cf6..0000000
--- a/skia/ext/vector_platform_device_cairo_linux.cc
+++ /dev/null
@@ -1,695 +0,0 @@
-// 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 "skia/ext/vector_platform_device_cairo_linux.h"
-
-#include <cairo.h>
-#include <cairo-ft.h>
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-#include <map>
-
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "skia/ext/bitmap_platform_device.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 {
-
-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;
-static base::LazyInstance<MapFontId2FontInfo> g_map_font_id_to_font_info(
- base::LINKER_INITIALIZED);
-
-// 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 " \
- << "VectorPlatformDeviceCairo.";
- }
- }
-
- ~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_;
-};
-static base::LazyInstance<FtLibrary> g_ft_library(base::LINKER_INITIALIZED);
-
-// Verify cairo surface after creation/modification.
-bool IsContextValid(cairo_t* context) {
- return cairo_status(context) == CAIRO_STATUS_SUCCESS;
-}
-
-} // namespace
-
-namespace skia {
-
-// static
-SkDevice* VectorPlatformDeviceCairo::CreateDevice(cairo_t* context, int width,
- int height, bool isOpaque) {
- // TODO(myhuang): Here we might also have similar issues as those on Windows
- // (vector_canvas_win.cc, http://crbug.com/18382 & http://crbug.com/18383).
- // Please note that is_opaque is true when we use this class for printing.
- // Fallback to bitmap when context is NULL.
- if (!isOpaque || NULL == context) {
- return BitmapPlatformDevice::Create(width, height, isOpaque);
- }
-
- SkASSERT(cairo_status(context) == CAIRO_STATUS_SUCCESS);
- SkASSERT(width > 0);
- SkASSERT(height > 0);
-
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
-
- return new VectorPlatformDeviceCairo(context, bitmap);
-}
-
-VectorPlatformDeviceCairo::VectorPlatformDeviceCairo(PlatformSurface context,
- const SkBitmap& bitmap)
- : SkDevice(bitmap),
- context_(context) {
- SkASSERT(bitmap.getConfig() == SkBitmap::kARGB_8888_Config);
-
- SetPlatformDevice(this, this);
-
- // Increase the reference count to keep the context alive.
- cairo_reference(context_);
-
- transform_.reset();
-}
-
-VectorPlatformDeviceCairo::~VectorPlatformDeviceCairo() {
- // Un-ref |context_| since we referenced it in the constructor.
- cairo_destroy(context_);
-}
-
-PlatformSurface VectorPlatformDeviceCairo::BeginPlatformPaint() {
- return context_;
-}
-
-void VectorPlatformDeviceCairo::DrawToNativeContext(
- PlatformSurface surface, int x, int y, const PlatformRect* src_rect) {
- // Should never be called on Linux.
- SkASSERT(false);
-}
-
-SkDevice* VectorPlatformDeviceCairo::onCreateCompatibleDevice(
- SkBitmap::Config config,
- int width, int height,
- bool isOpaque, Usage) {
- SkASSERT(config == SkBitmap::kARGB_8888_Config);
- return CreateDevice(NULL, width, height, isOpaque);
-}
-
-uint32_t VectorPlatformDeviceCairo::getDeviceCapabilities() {
- return SkDevice::getDeviceCapabilities() | kVector_Capability;
-}
-
-void VectorPlatformDeviceCairo::drawBitmap(const SkDraw& draw,
- const SkBitmap& bitmap,
- const SkIRect* srcRectOrNull,
- const SkMatrix& matrix,
- const SkPaint& paint) {
- SkASSERT(bitmap.getConfig() == SkBitmap::kARGB_8888_Config);
-
- // Load the temporary matrix. This is what will translate, rotate and resize
- // the bitmap.
- SkMatrix actual_transform(transform_);
- actual_transform.preConcat(matrix);
- LoadTransformToContext(actual_transform);
-
- InternalDrawBitmap(bitmap, 0, 0, paint);
-
- // Restore the original matrix.
- LoadTransformToContext(transform_);
-}
-
-void VectorPlatformDeviceCairo::drawDevice(const SkDraw& draw,
- SkDevice* device,
- int x,
- int y,
- const SkPaint& paint) {
- SkASSERT(device);
-
- // TODO(myhuang): We may also have to consider http://b/1183870 .
- drawSprite(draw, device->accessBitmap(false), x, y, paint);
-}
-
-void VectorPlatformDeviceCairo::drawPaint(const SkDraw& draw,
- const SkPaint& paint) {
- // Bypass the current transformation matrix.
- LoadIdentityTransformToContext();
-
- // TODO(myhuang): Is there a better way to do this?
- SkRect rect;
- rect.fLeft = 0;
- rect.fTop = 0;
- rect.fRight = SkIntToScalar(width() + 1);
- rect.fBottom = SkIntToScalar(height() + 1);
- drawRect(draw, rect, paint);
-
- // Restore the original matrix.
- LoadTransformToContext(transform_);
-}
-
-void VectorPlatformDeviceCairo::drawPath(const SkDraw& draw,
- const SkPath& path,
- const SkPaint& paint,
- const SkMatrix* prePathMatrix,
- bool pathIsMutable) {
- if (paint.getPathEffect()) {
- // Apply the path effect forehand.
- SkPath path_modified;
- paint.getFillPath(path, &path_modified);
-
- // Removes the path effect from the temporary SkPaint object.
- SkPaint paint_no_effet(paint);
- SkSafeUnref(paint_no_effet.setPathEffect(NULL));
-
- // Draw the calculated path.
- drawPath(draw, path_modified, paint_no_effet);
- return;
- }
-
- // Setup paint color.
- ApplyPaintColor(paint);
-
- SkPaint::Style style = paint.getStyle();
- // Setup fill style.
- if (style & SkPaint::kFill_Style) {
- ApplyFillStyle(path);
- }
-
- // Setup stroke style.
- if (style & SkPaint::kStroke_Style) {
- ApplyStrokeStyle(paint);
- }
-
- // Iterate path verbs.
- // TODO(myhuang): Is there a better way to do this?
- SkPoint current_points[4];
- SkPath::Iter iter(path, false);
- for (SkPath::Verb verb = iter.next(current_points);
- verb != SkPath::kDone_Verb;
- verb = iter.next(current_points)) {
- switch (verb) {
- case SkPath::kMove_Verb: { // iter.next returns 1 point
- cairo_move_to(context_, current_points[0].fX, current_points[0].fY);
- } break;
-
- case SkPath::kLine_Verb: { // iter.next returns 2 points
- cairo_line_to(context_, current_points[1].fX, current_points[1].fY);
- } break;
-
- case SkPath::kQuad_Verb: { // iter.next returns 3 points
- // Degree elevation (quadratic to cubic).
- // c1 = (2 * p1 + p0) / 3
- // c2 = (2 * p1 + p2) / 3
- current_points[1].scale(2.); // p1 *= 2.0;
- SkScalar c1_X = (current_points[1].fX + current_points[0].fX) / 3.;
- SkScalar c1_Y = (current_points[1].fY + current_points[0].fY) / 3.;
- SkScalar c2_X = (current_points[1].fX + current_points[2].fX) / 3.;
- SkScalar c2_Y = (current_points[1].fY + current_points[2].fY) / 3.;
- cairo_curve_to(context_,
- c1_X, c1_Y,
- c2_X, c2_Y,
- current_points[2].fX, current_points[2].fY);
- } break;
-
- case SkPath::kCubic_Verb: { // iter.next returns 4 points
- cairo_curve_to(context_,
- current_points[1].fX, current_points[1].fY,
- current_points[2].fX, current_points[2].fY,
- current_points[3].fX, current_points[3].fY);
- } break;
-
- case SkPath::kClose_Verb: { // iter.next returns 1 point (the last pt).
- cairo_close_path(context_);
- } break;
-
- default: {
- // Should not reach here!
- SkASSERT(false);
- } break;
- }
- }
-
- DoPaintStyle(paint);
-}
-
-void VectorPlatformDeviceCairo::drawPoints(const SkDraw& draw,
- SkCanvas::PointMode mode,
- size_t count,
- const SkPoint pts[],
- const SkPaint& paint) {
- SkASSERT(pts);
-
- if (!count)
- return;
-
- // Setup paint color.
- ApplyPaintColor(paint);
-
- // Setup stroke style.
- ApplyStrokeStyle(paint);
-
- switch (mode) {
- case SkCanvas::kPoints_PointMode: {
- // There is a bug in Cairo that it won't draw anything when using some
- // specific caps, e.g. SkPaint::kSquare_Cap. This is because Cairo does
- // not have enough/ambiguous direction information. One possible work-
- // around is to draw a really short line.
- for (size_t i = 0; i < count; ++i) {
- double x = pts[i].fX;
- double y = pts[i].fY;
- cairo_move_to(context_, x, y);
- cairo_line_to(context_, x+.01, y);
- }
- } break;
-
- case SkCanvas::kLines_PointMode: {
- if (count % 2) {
- SkASSERT(false);
- return;
- }
-
- for (size_t i = 0; i < count >> 1; ++i) {
- double x1 = pts[i << 1].fX;
- double y1 = pts[i << 1].fY;
- double x2 = pts[(i << 1) + 1].fX;
- double y2 = pts[(i << 1) + 1].fY;
- cairo_move_to(context_, x1, y1);
- cairo_line_to(context_, x2, y2);
- }
- } break;
-
- case SkCanvas::kPolygon_PointMode: {
- double x = pts[0].fX;
- double y = pts[0].fY;
- cairo_move_to(context_, x, y);
- for (size_t i = 1; i < count; ++i) {
- x = pts[i].fX;
- y = pts[i].fY;
- cairo_line_to(context_, x, y);
- }
- } break;
-
- default:
- SkASSERT(false);
- return;
- }
- cairo_stroke(context_);
-}
-
-// TODO(myhuang): Embed fonts/texts into PDF surface.
-// Please NOTE that len records text's length in byte, not uint16_t.
-void VectorPlatformDeviceCairo::drawPosText(const SkDraw& draw,
- const void* text,
- size_t len,
- const SkScalar pos[],
- SkScalar constY,
- int scalarsPerPos,
- const SkPaint& paint) {
- SkASSERT(text);
- SkASSERT(pos);
- SkASSERT(paint.getTextEncoding() == SkPaint::kGlyphID_TextEncoding);
- // Each pos should contain either only x, or (x, y).
- SkASSERT((scalarsPerPos == 1) || (scalarsPerPos == 2));
-
- if (!len)
- return;
-
- // Text color.
- ApplyPaintColor(paint);
-
- const uint16_t* glyph_ids = static_cast<const uint16_t*>(text);
-
- // The style is either kFill_Style or kStroke_Style.
- if (paint.getStyle() & SkPaint::kStroke_Style) {
- ApplyStrokeStyle(paint);
-
- // Draw each glyph by its path.
- for (size_t i = 0; i < len / sizeof(uint16_t); ++i) {
- uint16_t glyph_id = glyph_ids[i];
- SkPath textPath;
- paint.getTextPath(&glyph_id,
- sizeof(uint16_t),
- pos[i * scalarsPerPos],
- (scalarsPerPos == 1) ?
- constY :
- pos[i * scalarsPerPos + 1],
- &textPath);
- drawPath(draw, textPath, paint);
- }
- } else { // kFill_Style.
- // Selects correct font.
- if (!SelectFontById(paint.getTypeface()->uniqueID())) {
- SkASSERT(false);
- return;
- }
- cairo_set_font_size(context_, paint.getTextSize());
-
- // Draw glyphs.
- for (size_t i = 0; i < len / sizeof(uint16_t); ++i) {
- uint16_t glyph_id = glyph_ids[i];
-
- cairo_glyph_t glyph;
- glyph.index = glyph_id;
- glyph.x = pos[i * scalarsPerPos];
- glyph.y = (scalarsPerPos == 1) ? constY : pos[i * scalarsPerPos + 1];
-
- cairo_show_glyphs(context_, &glyph, 1);
- }
- }
-}
-
-void VectorPlatformDeviceCairo::drawRect(const SkDraw& draw,
- const SkRect& rect,
- const SkPaint& paint) {
- if (paint.getPathEffect()) {
- // Draw a path instead.
- SkPath path_orginal;
- path_orginal.addRect(rect);
-
- // Apply the path effect to the rect.
- SkPath path_modified;
- paint.getFillPath(path_orginal, &path_modified);
-
- // Removes the path effect from the temporary SkPaint object.
- SkPaint paint_no_effet(paint);
- SkSafeUnref(paint_no_effet.setPathEffect(NULL));
-
- // Draw the calculated path.
- drawPath(draw, path_modified, paint_no_effet);
- return;
- }
-
- // Setup color.
- ApplyPaintColor(paint);
-
- // Setup stroke style.
- ApplyStrokeStyle(paint);
-
- // Draw rectangle.
- cairo_rectangle(context_,
- rect.fLeft, rect.fTop,
- rect.fRight - rect.fLeft, rect.fBottom - rect.fTop);
-
- DoPaintStyle(paint);
-}
-
-void VectorPlatformDeviceCairo::drawSprite(const SkDraw& draw,
- const SkBitmap& bitmap,
- int x, int y,
- const SkPaint& paint) {
- SkASSERT(bitmap.getConfig() == SkBitmap::kARGB_8888_Config);
-
- LoadIdentityTransformToContext();
-
- InternalDrawBitmap(bitmap, x, y, paint);
-
- // Restore the original matrix.
- LoadTransformToContext(transform_);
-}
-
-void VectorPlatformDeviceCairo::drawText(const SkDraw& draw,
- const void* text,
- size_t byteLength,
- SkScalar x,
- SkScalar y,
- const SkPaint& paint) {
- // This function isn't used in the code. Verify this assumption.
- SkASSERT(false);
-}
-
-
-void VectorPlatformDeviceCairo::drawTextOnPath(const SkDraw& draw,
- const void* text,
- size_t len,
- const SkPath& path,
- const SkMatrix* matrix,
- const SkPaint& paint) {
- // This function isn't used in the code. Verify this assumption.
- SkASSERT(false);
-}
-
-void VectorPlatformDeviceCairo::drawVertices(const SkDraw& draw,
- SkCanvas::VertexMode vmode,
- int vertexCount,
- const SkPoint vertices[],
- const SkPoint texs[],
- const SkColor colors[],
- SkXfermode* xmode,
- const uint16_t indices[],
- int indexCount,
- const SkPaint& paint) {
- // This function isn't used in the code. Verify this assumption.
- SkASSERT(false);
-}
-
-void VectorPlatformDeviceCairo::setMatrixClip(const SkMatrix& transform,
- const SkRegion& region,
- const SkClipStack&) {
- clip_region_ = region;
- if (!clip_region_.isEmpty())
- LoadClipRegion(clip_region_);
-
- transform_ = transform;
- LoadTransformToContext(transform_);
-}
-
-void VectorPlatformDeviceCairo::ApplyPaintColor(const SkPaint& paint) {
- SkColor color = paint.getColor();
- double a = static_cast<double>(SkColorGetA(color)) / 255.;
- double r = static_cast<double>(SkColorGetR(color)) / 255.;
- double g = static_cast<double>(SkColorGetG(color)) / 255.;
- double b = static_cast<double>(SkColorGetB(color)) / 255.;
-
- cairo_set_source_rgba(context_, r, g, b, a);
-}
-
-void VectorPlatformDeviceCairo::ApplyFillStyle(const SkPath& path) {
- // Setup fill style.
- // TODO(myhuang): Cairo does NOT support all skia fill rules!!
- cairo_set_fill_rule(context_,
- static_cast<cairo_fill_rule_t>(path.getFillType()));
-}
-
-void VectorPlatformDeviceCairo::ApplyStrokeStyle(const SkPaint& paint) {
- // Line width.
- cairo_set_line_width(context_, paint.getStrokeWidth());
-
- // Line join.
- cairo_set_line_join(context_,
- static_cast<cairo_line_join_t>(paint.getStrokeJoin()));
-
- // Line cap.
- cairo_set_line_cap(context_,
- static_cast<cairo_line_cap_t>(paint.getStrokeCap()));
-}
-
-void VectorPlatformDeviceCairo::DoPaintStyle(const SkPaint& paint) {
- SkPaint::Style style = paint.getStyle();
-
- switch (style) {
- case SkPaint::kFill_Style: {
- cairo_fill(context_);
- } break;
-
- case SkPaint::kStroke_Style: {
- cairo_stroke(context_);
- } break;
-
- case SkPaint::kStrokeAndFill_Style: {
- cairo_fill_preserve(context_);
- cairo_stroke(context_);
- } break;
-
- default:
- SkASSERT(false);
- }
-}
-
-void VectorPlatformDeviceCairo::InternalDrawBitmap(const SkBitmap& bitmap,
- int x, int y,
- const SkPaint& paint) {
- SkASSERT(bitmap.getConfig() == SkBitmap::kARGB_8888_Config);
-
- unsigned char alpha = paint.getAlpha();
-
- if (alpha == 0)
- return;
-
- int src_size_x = bitmap.width();
- int src_size_y = bitmap.height();
-
- if (!src_size_x || !src_size_y)
- return;
-
- SkAutoLockPixels image_lock(bitmap);
-
- cairo_surface_t* bitmap_surface =
- cairo_image_surface_create_for_data(
- reinterpret_cast<unsigned char*>(bitmap.getPixels()),
- CAIRO_FORMAT_ARGB32, src_size_x, src_size_y, bitmap.rowBytes());
-
- cairo_set_source_surface(context_, bitmap_surface, x, y);
- cairo_paint_with_alpha(context_, static_cast<double>(alpha) / 255.);
-
- cairo_surface_destroy(bitmap_surface);
-}
-
-void VectorPlatformDeviceCairo::LoadClipRegion(const SkRegion& clip) {
- cairo_reset_clip(context_);
-
- LoadIdentityTransformToContext();
-
- // TODO(myhuang): Support non-rect clips.
- SkIRect bounding = clip.getBounds();
- cairo_rectangle(context_, bounding.fLeft, bounding.fTop,
- bounding.fRight - bounding.fLeft,
- bounding.fBottom - bounding.fTop);
- cairo_clip(context_);
-
- // Restore the original matrix.
- LoadTransformToContext(transform_);
-}
-
-void VectorPlatformDeviceCairo::LoadIdentityTransformToContext() {
- SkMatrix identity;
- identity.reset();
- LoadTransformToContext(identity);
-}
-
-void VectorPlatformDeviceCairo::LoadTransformToContext(const SkMatrix& matrix) {
- cairo_matrix_t m;
- m.xx = matrix[SkMatrix::kMScaleX];
- m.xy = matrix[SkMatrix::kMSkewX];
- m.x0 = matrix[SkMatrix::kMTransX];
- m.yx = matrix[SkMatrix::kMSkewY];
- m.yy = matrix[SkMatrix::kMScaleY];
- m.y0 = matrix[SkMatrix::kMTransY];
- cairo_set_matrix(context_, &m);
-}
-
-bool VectorPlatformDeviceCairo::SelectFontById(uint32_t font_id) {
- DCHECK(IsContextValid(context_));
- DCHECK(SkFontHost::ValidFontID(font_id));
-
- FtLibrary* ft_library = g_ft_library.Pointer();
- if (!ft_library->library())
- return false;
-
- // Checks if we have a cache hit.
- MapFontId2FontInfo* g_font_cache = g_map_font_id_to_font_info.Pointer();
- 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(
- ft_library->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;
-}
-
-// static
-void VectorPlatformDeviceCairo::ClearFontCache() {
- MapFontId2FontInfo* g_font_cache = g_map_font_id_to_font_info.Pointer();
- 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_cairo_linux.h b/skia/ext/vector_platform_device_cairo_linux.h
deleted file mode 100644
index 36be0c76..0000000
--- a/skia/ext/vector_platform_device_cairo_linux.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// 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.
-
-#ifndef SKIA_EXT_VECTOR_PLATFORM_DEVICE_CAIRO_LINUX_H_
-#define SKIA_EXT_VECTOR_PLATFORM_DEVICE_CAIRO_LINUX_H_
-#pragma once
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "skia/ext/platform_device.h"
-#include "third_party/skia/include/core/SkMatrix.h"
-#include "third_party/skia/include/core/SkRegion.h"
-
-namespace skia {
-
-// This device is basically a wrapper that provides a surface for SkCanvas
-// to draw into. It is basically an adaptor which converts skia APIs into
-// cooresponding Cairo APIs and outputs to a Cairo surface. Please NOTE that
-// since it is completely vectorial, the bitmap content in it is thus
-// meaningless.
-class SK_API VectorPlatformDeviceCairo : public PlatformDevice,
- public SkDevice {
- public:
- virtual ~VectorPlatformDeviceCairo();
-
- static SkDevice* CreateDevice(cairo_t* context, int width, int height,
- bool isOpaque);
-
- // Clean up cached fonts. It is an error to call this while some
- // VectorPlatformDeviceCairo callee is still using fonts created for it by
- // this class.
- static void ClearFontCache();
-
- // Overridden from SkDevice
- virtual uint32_t getDeviceCapabilities();
- virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) OVERRIDE;
- virtual void drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
- size_t count, const SkPoint[],
- const SkPaint& paint) OVERRIDE;
- virtual void drawRect(const SkDraw& draw, const SkRect& r,
- const SkPaint& paint) OVERRIDE;
- virtual void drawPath(const SkDraw& draw, const SkPath& path,
- const SkPaint& paint,
- const SkMatrix* prePathMatrix = NULL,
- bool pathIsMutable = false) OVERRIDE;
- virtual void drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
- const SkIRect* srcRectOrNull,
- const SkMatrix& matrix,
- const SkPaint& paint) OVERRIDE;
- virtual void drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
- int x, int y, const SkPaint& paint) OVERRIDE;
- virtual void drawText(const SkDraw& draw, const void* text, size_t len,
- SkScalar x, SkScalar y, const SkPaint& paint) OVERRIDE;
- virtual void drawPosText(const SkDraw& draw, const void* text, size_t len,
- const SkScalar pos[], SkScalar constY,
- int scalarsPerPos, const SkPaint& paint) OVERRIDE;
- virtual void drawTextOnPath(const SkDraw& draw, const void* text, size_t len,
- const SkPath& path, const SkMatrix* matrix,
- const SkPaint& paint) OVERRIDE;
- virtual void drawVertices(const SkDraw& draw, SkCanvas::VertexMode,
- int vertexCount,
- const SkPoint verts[], const SkPoint texs[],
- const SkColor colors[], SkXfermode* xmode,
- const uint16_t indices[], int indexCount,
- const SkPaint& paint) OVERRIDE;
- virtual void drawDevice(const SkDraw& draw, SkDevice*, int x, int y,
- const SkPaint&) OVERRIDE;
-
- virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region,
- const SkClipStack&) OVERRIDE;
-
- // Overridden from PlatformDevice
- virtual PlatformSurface BeginPlatformPaint() OVERRIDE;
- virtual void DrawToNativeContext(PlatformSurface surface, int x, int y,
- const PlatformRect* src_rect) OVERRIDE;
-
- protected:
- VectorPlatformDeviceCairo(PlatformSurface context, const SkBitmap& bitmap);
-
- virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config, int width,
- int height, bool isOpaque,
- Usage usage) OVERRIDE;
-
- private:
- // Apply paint's color in the context.
- void ApplyPaintColor(const SkPaint& paint);
-
- // Apply path's fill style in the context.
- void ApplyFillStyle(const SkPath& path);
-
- // Apply paint's stroke style in the context.
- void ApplyStrokeStyle(const SkPaint& paint);
-
- // Perform painting.
- void DoPaintStyle(const SkPaint& paint);
-
- // Draws a bitmap in the the device, using the currently loaded matrix.
- void InternalDrawBitmap(const SkBitmap& bitmap, int x, int y,
- const SkPaint& paint);
-
- // Set up the clipping region for the context. Please note that now we only
- // use the bounding box of the region for clipping.
- // TODO(myhuang): Support non-rectangular clipping.
- void LoadClipRegion(const SkRegion& clip);
-
- // Use identity matrix to set up context's transformation.
- void LoadIdentityTransformToContext();
-
- // 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(uint32_t font_id);
-
- // Transformation assigned to the context.
- SkMatrix transform_;
-
- // The current clipping region.
- SkRegion clip_region_;
-
- // Device context.
- PlatformSurface context_;
-
- DISALLOW_COPY_AND_ASSIGN(VectorPlatformDeviceCairo);
-};
-
-} // namespace skia
-
-#endif // SKIA_EXT_VECTOR_PLATFORM_DEVICE_CAIRO_LINUX_H_
diff --git a/skia/skia.gyp b/skia/skia.gyp
index 4baef8b..106efa9 100644
--- a/skia/skia.gyp
+++ b/skia/skia.gyp
@@ -696,8 +696,6 @@
'ext/skia_utils_win.h',
'ext/vector_canvas.cc',
'ext/vector_canvas.h',
- 'ext/vector_platform_device_cairo_linux.cc',
- 'ext/vector_platform_device_cairo_linux.h',
'ext/vector_platform_device_emf_win.cc',
'ext/vector_platform_device_emf_win.h',
'ext/vector_platform_device_skia.cc',