diff options
-rw-r--r-- | vcl/Library_vclplug_osx.mk | 1 | ||||
-rw-r--r-- | vcl/inc/skia/osx/bitmap.hxx | 26 | ||||
-rw-r--r-- | vcl/osx/salinst.cxx | 6 | ||||
-rw-r--r-- | vcl/skia/osx/bitmap.cxx | 88 |
4 files changed, 121 insertions, 0 deletions
diff --git a/vcl/Library_vclplug_osx.mk b/vcl/Library_vclplug_osx.mk index 3e0e0ff481be..ddc3a3608f1b 100644 --- a/vcl/Library_vclplug_osx.mk +++ b/vcl/Library_vclplug_osx.mk @@ -142,6 +142,7 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_osx,\ vcl/quartz/utils \ vcl/quartz/AquaGraphicsBackend \ $(if $(filter SKIA,$(BUILD_TYPE)), \ + vcl/skia/osx/bitmap \ vcl/skia/osx/gdiimpl \ vcl/skia/osx/rastercontext \ ) \ diff --git a/vcl/inc/skia/osx/bitmap.hxx b/vcl/inc/skia/osx/bitmap.hxx new file mode 100644 index 000000000000..0c0b1ee09be3 --- /dev/null +++ b/vcl/inc/skia/osx/bitmap.hxx @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * 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 INCLUDED_VCL_INC_SKIA_OSX_BITMAP_HXX +#define INCLUDED_VCL_INC_SKIA_OSX_BITMAP_HXX + +#include <vcl/dllapi.h> + +#include <osx/osxvcltypes.h> + +class Image; + +namespace SkiaHelper +{ +VCL_PLUGIN_PUBLIC CGImageRef createCGImage(const Image& rImage); +}; + +#endif // INCLUDED_VCL_INC_SKIA_OSX_BITMAP_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/osx/salinst.cxx b/vcl/osx/salinst.cxx index 08fae66b4ad3..dbdb8038b493 100644 --- a/vcl/osx/salinst.cxx +++ b/vcl/osx/salinst.cxx @@ -78,6 +78,7 @@ #include <vcl/skia/SkiaHelper.hxx> #include <skia/salbmp.hxx> #include <skia/osx/gdiimpl.hxx> +#include <skia/osx/bitmap.hxx> #endif extern "C" { @@ -918,6 +919,11 @@ OUString AquaSalInstance::getOSVersion() CGImageRef CreateCGImage( const Image& rImage ) { +#if HAVE_FEATURE_SKIA + if (SkiaHelper::isVCLSkiaEnabled()) + return SkiaHelper::createCGImage( rImage ); +#endif + BitmapEx aBmpEx( rImage.GetBitmapEx() ); Bitmap aBmp( aBmpEx.GetBitmap() ); diff --git a/vcl/skia/osx/bitmap.cxx b/vcl/skia/osx/bitmap.cxx new file mode 100644 index 000000000000..77e34697aa50 --- /dev/null +++ b/vcl/skia/osx/bitmap.cxx @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * 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/. + * + * Some of this code is based on Skia source code, covered by the following + * license notice (see readlicense_oo for the full license): + * + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + */ + +#include <skia/osx/bitmap.hxx> + +#include <vcl/bitmapex.hxx> +#include <vcl/image.hxx> + +#include <skia/salbmp.hxx> +#include <osx/saldata.hxx> + +#include <SkBitmap.h> +#include <SkCanvas.h> + +using namespace SkiaHelper; + +namespace SkiaHelper +{ +CGImageRef createCGImage(const Image& rImage) +{ + BitmapEx bitmapEx(rImage.GetBitmapEx()); + Bitmap bitmap(bitmapEx.GetBitmap()); + + if (bitmap.IsEmpty() || !bitmap.ImplGetSalBitmap()) + return nullptr; + + assert(dynamic_cast<SkiaSalBitmap*>(bitmap.ImplGetSalBitmap().get()) != nullptr); + SkiaSalBitmap* skiaBitmap = static_cast<SkiaSalBitmap*>(bitmap.ImplGetSalBitmap().get()); + + SkBitmap targetBitmap; + if (!targetBitmap.tryAllocPixels( + SkImageInfo::Make(bitmap.GetSizePixel().getWidth(), bitmap.GetSizePixel().getHeight(), + kRGBA_8888_SkColorType, kPremul_SkAlphaType))) + return nullptr; + SkPaint paint; + paint.setBlendMode(SkBlendMode::kSrc); // set as is + SkMatrix matrix; // The image is needed upside-down. + matrix.preTranslate(0, targetBitmap.height()); + matrix.setConcat(matrix, SkMatrix::Scale(1, -1)); + + if (!bitmapEx.IsAlpha()) + { + SkCanvas canvas(targetBitmap); + canvas.concat(matrix); + canvas.drawImage(skiaBitmap->GetSkImage(), 0, 0, SkSamplingOptions(), &paint); + } + else + { + AlphaMask alpha(bitmapEx.GetAlpha()); + Bitmap alphaBitmap(alpha.GetBitmap()); + assert(dynamic_cast<SkiaSalBitmap*>(alphaBitmap.ImplGetSalBitmap().get()) != nullptr); + SkiaSalBitmap* skiaAlpha + = static_cast<SkiaSalBitmap*>(alphaBitmap.ImplGetSalBitmap().get()); + paint.setShader(SkShaders::Blend(SkBlendMode::kDstOut, + skiaBitmap->GetSkShader(SkSamplingOptions()), + skiaAlpha->GetAlphaSkShader(SkSamplingOptions()))); + SkCanvas canvas(targetBitmap); + canvas.concat(matrix); + canvas.drawPaint(paint); + } + + CGContextRef context = CGBitmapContextCreate( + targetBitmap.getAddr32(0, 0), targetBitmap.width(), targetBitmap.height(), 8, + targetBitmap.rowBytes(), GetSalData()->mxRGBSpace, kCGImageAlphaPremultipliedLast); + if (!context) + return nullptr; + CGImageRef screenImage = CGBitmapContextCreateImage(context); + CFRelease(context); + return screenImage; +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |