summaryrefslogtreecommitdiff
path: root/vcl/skia/osx/bitmap.cxx
blob: edb339ce5292a509e5fa32e89d50256a886c1ae0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/* -*- 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>
#include <SkShader.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.GetAlphaMask());
        // tdf#156854 invert alpha mask for macOS native menu item images
        // At the time of this change, only the AquaSalMenu class calls this
        // function so it should be safe to invert the alpha mask here.
        alpha.Invert();
        Bitmap alphaBitmap(alpha.GetBitmap());
        assert(dynamic_cast<SkiaSalBitmap*>(alphaBitmap.ImplGetSalBitmap().get()) != nullptr);
        SkiaSalBitmap* skiaAlpha
            = static_cast<SkiaSalBitmap*>(alphaBitmap.ImplGetSalBitmap().get());
#if 0
        // Drawing to a bitmap using a shader from a GPU-backed image fails silently.
        // https://bugs.chromium.org/p/skia/issues/detail?id=12685
        paint.setShader(SkShaders::Blend(SkBlendMode::kDstOut,
                                         skiaBitmap->GetSkShader(SkSamplingOptions()),
                                         skiaAlpha->GetAlphaSkShader(SkSamplingOptions())));
#else
        sk_sp<SkImage> imB = skiaBitmap->GetSkImage()->makeNonTextureImage();
        sk_sp<SkImage> imA = skiaAlpha->GetAlphaSkImage()->makeNonTextureImage();
        paint.setShader(SkShaders::Blend(SkBlendMode::kDstOut, imB->makeShader(SkSamplingOptions()),
                                         imA->makeShader(SkSamplingOptions())));
#endif
        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: */
a88ec7a43162df37098c4525c33451266a1575'>loplugin:simplifybool a little more aggressiveNoel Grandin 2020-08-03Revert "Adapt to changed clang::ASTContext::getParents behavior on Clang 11 t...Stephan Bergmann 2020-07-28Adapt to Clang 12 trunk Expr::getIntegerConstantExpressionStephan Bergmann 2020-05-25Adapt to changed clang::ASTContext::getParents behavior on Clang 11 trunkStephan Bergmann 2019-11-26Adapt to clang::MaterializeTemporaryExpr::GetTemparyExpr renameStephan Bergmann 2019-10-14New loplugin:getstrStephan Bergmann 2019-10-10Fix detection of std::unique_ptr/shared_ptr in loplugin:redundantpointeropsStephan Bergmann 2019-10-09Improve loplugin:redundantpointerops diagnostic messagesStephan Bergmann 2019-07-31Improved loplugin:stringconstant (now that GCC 7 supports it)Stephan Bergmann 2019-05-27fix clang version checkLuboš Luňák 2019-05-16Adapt compilerplugins to Clang 9 isExplicitSpecified -> getExplicitSpecifierStephan Bergmann 2018-11-29Revert "comment out the EvaluateAsInt compat code for now"Stephan Bergmann 2018-11-29comment out the EvaluateAsInt compat code for nowNoel Grandin 2018-11-27add EvaluateAsInt compat function for latest clangNoel Grandin 2018-11-23Bump compiler plugins Clang baseline to 5.0.2Stephan Bergmann 2018-10-10Fix failure of loplugin:useuniqueptr with older compilersStephan Bergmann 2018-08-10Avoid -Werror=deprecated-declarations with recent Clang trunkStephan Bergmann 2018-05-04Adapt to Clang trunk SourceManager::getImmediateExpansionRange changesStephan Bergmann 2017-12-19Bump --enable-compiler-plugins to Clang 3.8.0Stephan Bergmann 2017-12-10Fix isSalCallFunction furtherStephan Bergmann 2017-10-24loplugin:includeformStephan Bergmann 2017-07-17Fix typosAndrea Gelmini