diff --git a/gfx/thebes/PrintTargetCG.cpp b/gfx/thebes/PrintTargetCG.cpp new file mode 100644 index 000000000000..3652df1fa8e7 --- /dev/null +++ b/gfx/thebes/PrintTargetCG.cpp @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "PrintTargetCG.h" + +#include "cairo.h" +#include "cairo-quartz.h" +#include "mozilla/gfx/HelpersCairo.h" + +namespace mozilla { +namespace gfx { + +PrintTargetCG::PrintTargetCG(cairo_surface_t* aCairoSurface, + const IntSize& aSize) + : PrintTarget(aCairoSurface, aSize) +{ + // TODO: Add memory reporting like gfxQuartzSurface. + //RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface)); +} + +/* static */ already_AddRefed +PrintTargetCG::CreateOrNull(const IntSize& aSize, gfxImageFormat aFormat) +{ + if (!Factory::CheckSurfaceSize(aSize)) { + return nullptr; + } + + unsigned int width = static_cast(aSize.width); + unsigned int height = static_cast(aSize.height); + + cairo_format_t cformat = GfxFormatToCairoFormat(aFormat); + cairo_surface_t* surface = + cairo_quartz_surface_create(cformat, width, height); + + if (cairo_surface_status(surface)) { + return nullptr; + } + + // The new object takes ownership of our surface reference. + RefPtr target = new PrintTargetCG(surface, aSize); + + return target.forget(); +} + +/* static */ already_AddRefed +PrintTargetCG::CreateOrNull(CGContextRef aContext, const IntSize& aSize) +{ + if (!Factory::CheckSurfaceSize(aSize)) { + return nullptr; + } + + unsigned int width = static_cast(aSize.width); + unsigned int height = static_cast(aSize.height); + + cairo_surface_t* surface = + cairo_quartz_surface_create_for_cg_context(aContext, width, height); + + if (cairo_surface_status(surface)) { + return nullptr; + } + + // The new object takes ownership of our surface reference. + RefPtr target = new PrintTargetCG(surface, aSize); + + return target.forget(); +} + +} // namespace gfx +} // namespace mozilla diff --git a/gfx/thebes/PrintTargetCG.h b/gfx/thebes/PrintTargetCG.h new file mode 100644 index 000000000000..515ee5a73cae --- /dev/null +++ b/gfx/thebes/PrintTargetCG.h @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_GFX_PRINTTARGETCG_H +#define MOZILLA_GFX_PRINTTARGETCG_H + +#include +#include "PrintTarget.h" + +namespace mozilla { +namespace gfx { + +/** + * CoreGraphics printing target. + * + * Note that a CGContextRef obtained from PMSessionGetCGGraphicsContext is + * valid only for the current page. As a consequence instances of this class + * should only be used to print a single page. + */ +class PrintTargetCG final : public PrintTarget +{ +public: + static already_AddRefed + CreateOrNull(const IntSize& aSize, gfxImageFormat aFormat); + + static already_AddRefed + CreateOrNull(CGContextRef aContext, const IntSize& aSize); + +private: + PrintTargetCG(cairo_surface_t* aCairoSurface, + const IntSize& aSize); +}; + +} // namespace gfx +} // namespace mozilla + +#endif /* MOZILLA_GFX_PRINTTARGETCG_H */ diff --git a/gfx/thebes/moz.build b/gfx/thebes/moz.build index 2acb2bc3235c..0ff6800eced5 100644 --- a/gfx/thebes/moz.build +++ b/gfx/thebes/moz.build @@ -97,12 +97,16 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': 'gfxQuartzNativeDrawing.h', 'gfxQuartzSurface.h', ] + EXPORTS.mozilla.gfx += [ + 'PrintTargetCG.h', + ] SOURCES += [ 'gfxCoreTextShaper.cpp', 'gfxMacFont.cpp', 'gfxPlatformMac.cpp', 'gfxQuartzNativeDrawing.cpp', 'gfxQuartzSurface.cpp', + 'PrintTargetCG.cpp', ] elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']: EXPORTS += [ diff --git a/widget/cocoa/nsDeviceContextSpecX.mm b/widget/cocoa/nsDeviceContextSpecX.mm index e6c85ed19fcb..a6b4de9ab44e 100644 --- a/widget/cocoa/nsDeviceContextSpecX.mm +++ b/widget/cocoa/nsDeviceContextSpecX.mm @@ -5,7 +5,7 @@ #include "nsDeviceContextSpecX.h" -#include "mozilla/gfx/PrintTargetThebes.h" +#include "mozilla/gfx/PrintTargetCG.h" #include "mozilla/RefPtr.h" #include "nsCRT.h" #include @@ -15,8 +15,6 @@ #include "nsIPrintOptions.h" #include "nsPrintSettingsX.h" -#include "gfxQuartzSurface.h" - // This must be the last include: #include "nsObjCExceptions.h" @@ -153,23 +151,16 @@ already_AddRefed nsDeviceContextSpecX::MakePrintTarget() CGContextRef context; ::PMSessionGetCGGraphicsContext(mPrintSession, &context); - RefPtr newSurface; - if (context) { // Initially, origin is at bottom-left corner of the paper. // Here, we translate it to top-left corner of the paper. CGContextTranslateCTM(context, 0, height); CGContextScaleCTM(context, 1.0, -1.0); - newSurface = new gfxQuartzSurface(context, size); - } else { - newSurface = new gfxQuartzSurface(size, SurfaceFormat::A8R8G8B8_UINT32); + return PrintTargetCG::CreateOrNull(context, size); } - if (!newSurface) { - return nullptr; - } - - return PrintTargetThebes::CreateOrNull(newSurface); + // Apparently we do need this branch - bug 368933. + return PrintTargetCG::CreateOrNull(size, SurfaceFormat::A8R8G8B8_UINT32); NS_OBJC_END_TRY_ABORT_BLOCK_NSNULL; }