[Libreoffice-commits] core.git: 2 commits - vcl/inc vcl/Library_vclplug_osx.mk vcl/osx vcl/quartz vcl/skia
LuboÅ¡ LuÅák (via logerrit)
logerrit at kemper.freedesktop.org
Mon Aug 23 13:01:05 UTC 2021
vcl/Library_vclplug_osx.mk | 1
vcl/inc/quartz/salgdi.h | 14 +++++-
vcl/inc/skia/osx/bitmap.hxx | 26 ++++++++++++
vcl/inc/skia/osx/gdiimpl.hxx | 5 ++
vcl/osx/salinst.cxx | 6 ++
vcl/quartz/salgdi.cxx | 38 ++++++++++--------
vcl/skia/osx/bitmap.cxx | 88 +++++++++++++++++++++++++++++++++++++++++++
vcl/skia/osx/gdiimpl.cxx | 51 ++++++++++++++++++++++++
8 files changed, 209 insertions(+), 20 deletions(-)
New commits:
commit ab9c627bc8f16dd679a19b0946863cebab7b03bc
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Aug 17 17:05:55 2021 +0200
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Mon Aug 23 15:00:45 2021 +0200
add CreateCGImage() variant for Mac/Skia
Needed at least for 'recent documents' icons in the Mac menubar.
Change-Id: I5a22cf64ff5c5aba2c70ca2556fd0b66c425bafd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120811
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak at collabora.com>
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: */
commit 55422ec895d3014ba0507757870ebdec9ac1a2a9
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Aug 17 13:10:36 2021 +0200
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Mon Aug 23 15:00:30 2021 +0200
implement text rendering on Mac using Skia
There may be still small problems (CJK needs checking), but this is
already usable.
Change-Id: Ic9381c22ca55d9e6320152ffebeae740fd90f796
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120810
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak at collabora.com>
diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h
index 6cedf6f09b29..80b79a6ec720 100644
--- a/vcl/inc/quartz/salgdi.h
+++ b/vcl/inc/quartz/salgdi.h
@@ -123,6 +123,8 @@ public:
void AnnounceFonts( PhysicalFontCollection& ) const;
CoreTextFontFace* GetFontDataFromId( sal_IntPtr nFontId ) const;
+ CTFontCollectionRef fontCollection() { return mpCTFontCollection; }
+
private:
CTFontCollectionRef mpCTFontCollection;
CFArrayRef mpCTFontArray;
@@ -170,6 +172,10 @@ struct AquaSharedAttributes
int mnXorMode; // 0: off 1: on 2: invert only
int mnBitmapDepth; // zero unless bitmap
+ Color maTextColor;
+ /// allows text to be rendered without antialiasing
+ bool mbNonAntialiasedText;
+
std::unique_ptr<XorEmulation> mpXorEmulation;
AquaSharedAttributes()
@@ -188,6 +194,8 @@ struct AquaSharedAttributes
, mnHeight(0)
, mnXorMode(0)
, mnBitmapDepth(0)
+ , maTextColor( COL_BLACK )
+ , mbNonAntialiasedText( false )
{}
void unsetClipPath()
@@ -287,6 +295,7 @@ public:
const tools::Rectangle &rControlRegion,
ControlState nState,
const ImplControlValue &aValue) = 0;
+ virtual void drawTextLayout(const GenericSalLayout& layout) = 0;
protected:
static bool performDrawNativeControl(ControlType nType,
ControlPart nPart,
@@ -433,6 +442,8 @@ public:
ControlState nState,
const ImplControlValue &aValue) override;
+ virtual void drawTextLayout(const GenericSalLayout& layout) override;
+
bool supportsOperation(OutDevSupportType eType) const override;
};
@@ -447,9 +458,6 @@ class AquaSalGraphics : public SalGraphicsAutoDelegateToImpl
// Device Font settings
rtl::Reference<CoreTextStyle> mpTextStyle[MAX_FALLBACK];
- RGBAColor maTextColor;
- /// allows text to be rendered without antialiasing
- bool mbNonAntialiasedText;
public:
AquaSalGraphics();
diff --git a/vcl/inc/skia/osx/gdiimpl.hxx b/vcl/inc/skia/osx/gdiimpl.hxx
index e42126cfae46..cc291bd38764 100644
--- a/vcl/inc/skia/osx/gdiimpl.hxx
+++ b/vcl/inc/skia/osx/gdiimpl.hxx
@@ -17,6 +17,8 @@
#include <skia/gdiimpl.hxx>
#include <skia/utils.hxx>
+#include <SkFontMgr.h>
+
class VCL_PLUGIN_PUBLIC AquaSkiaSalGraphicsImpl final : public SkiaSalGraphicsImpl,
public AquaGraphicsBackendBase
{
@@ -38,11 +40,14 @@ public:
const tools::Rectangle& rControlRegion, ControlState nState,
const ImplControlValue& aValue) override;
+ virtual void drawTextLayout(const GenericSalLayout& layout) override;
+
private:
virtual void createWindowContext(bool forceRaster = false) override;
virtual void performFlush() override;
void flushToScreen(const SkIRect& rect);
friend std::unique_ptr<sk_app::WindowContext> createVulkanWindowContext(bool);
+ static inline sk_sp<SkFontMgr> fontManager;
};
#endif // INCLUDED_VCL_INC_SKIA_OSX_GDIIMPL_HXX
diff --git a/vcl/quartz/salgdi.cxx b/vcl/quartz/salgdi.cxx
index 1fa3d425a6d4..53b10ab9533c 100644
--- a/vcl/quartz/salgdi.cxx
+++ b/vcl/quartz/salgdi.cxx
@@ -194,8 +194,6 @@ bool CoreTextFontFace::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilit
AquaSalGraphics::AquaSalGraphics()
: mnRealDPIX( 0 )
, mnRealDPIY( 0 )
- , maTextColor( COL_BLACK )
- , mbNonAntialiasedText( false )
{
SAL_INFO( "vcl.quartz", "AquaSalGraphics::AquaSalGraphics() this=" << this );
@@ -250,8 +248,8 @@ SalGraphicsImpl* AquaSalGraphics::GetImpl() const
void AquaSalGraphics::SetTextColor( Color nColor )
{
- maTextColor = RGBAColor( nColor );
- // SAL_ DEBUG(std::hex << nColor << std::dec << "={" << maTextColor.GetRed() << ", " << maTextColor.GetGreen() << ", " << maTextColor.GetBlue() << ", " << maTextColor.GetAlpha() << "}");
+ maShared.maTextColor = nColor;
+ // SAL_ DEBUG(std::hex << nColor << std::dec << "={" << maShared.maTextColor.GetRed() << ", " << maShared.maTextColor.GetGreen() << ", " << maShared.maTextColor.GetBlue() << ", " << maShared.maTextColor.GetAlpha() << "}");
}
void AquaSalGraphics::GetFontMetric(ImplFontMetricDataRef& rxFontMetric, int nFallbackLevel)
@@ -361,9 +359,14 @@ bool AquaSalGraphics::AddTempDevFont( PhysicalFontCollection*,
}
void AquaSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
+{
+ mpBackend->drawTextLayout(rLayout);
+}
+
+void AquaGraphicsBackend::drawTextLayout(const GenericSalLayout& rLayout)
{
#ifdef IOS
- if (!maShared.checkContext())
+ if (!mrShared.checkContext())
{
SAL_WARN("vcl.quartz", "AquaSalGraphics::DrawTextLayout() without context");
return;
@@ -437,20 +440,21 @@ void AquaSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
std::cerr << "]\n";
#endif
- maShared.maContextHolder.saveState();
+ mrShared.maContextHolder.saveState();
+ RGBAColor textColor( mrShared.maTextColor );
// The view is vertically flipped (no idea why), flip it back.
- CGContextScaleCTM(maShared.maContextHolder.get(), 1.0, -1.0);
- CGContextSetShouldAntialias(maShared.maContextHolder.get(), !mbNonAntialiasedText);
- CGContextSetFillColor(maShared.maContextHolder.get(), maTextColor.AsArray());
+ CGContextScaleCTM(mrShared.maContextHolder.get(), 1.0, -1.0);
+ CGContextSetShouldAntialias(mrShared.maContextHolder.get(), !mrShared.mbNonAntialiasedText);
+ CGContextSetFillColor(mrShared.maContextHolder.get(), textColor.AsArray());
if (rStyle.mbFauxBold)
{
float fSize = rFontSelect.mnHeight / 23.0f;
- CGContextSetStrokeColor(maShared.maContextHolder.get(), maTextColor.AsArray());
- CGContextSetLineWidth(maShared.maContextHolder.get(), fSize);
- CGContextSetTextDrawingMode(maShared.maContextHolder.get(), kCGTextFillStroke);
+ CGContextSetStrokeColor(mrShared.maContextHolder.get(), textColor.AsArray());
+ CGContextSetLineWidth(mrShared.maContextHolder.get(), fSize);
+ CGContextSetTextDrawingMode(mrShared.maContextHolder.get(), kCGTextFillStroke);
}
auto aIt = aGlyphOrientation.cbegin();
@@ -463,18 +467,18 @@ void AquaSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
size_t nStartIndex = std::distance(aGlyphOrientation.cbegin(), aIt);
size_t nLen = std::distance(aIt, aNext);
- maShared.maContextHolder.saveState();
+ mrShared.maContextHolder.saveState();
if (rStyle.mfFontRotation && !bUprightGlyph)
{
- CGContextRotateCTM(maShared.maContextHolder.get(), rStyle.mfFontRotation);
+ CGContextRotateCTM(mrShared.maContextHolder.get(), rStyle.mfFontRotation);
}
- CTFontDrawGlyphs(pFont, &aGlyphIds[nStartIndex], &aGlyphPos[nStartIndex], nLen, maShared.maContextHolder.get());
- maShared.maContextHolder.restoreState();
+ CTFontDrawGlyphs(pFont, &aGlyphIds[nStartIndex], &aGlyphPos[nStartIndex], nLen, mrShared.maContextHolder.get());
+ mrShared.maContextHolder.restoreState();
aIt = aNext;
}
- maShared.maContextHolder.restoreState();
+ mrShared.maContextHolder.restoreState();
}
void AquaSalGraphics::SetFont(LogicalFontInstance* pReqFont, int nFallbackLevel)
diff --git a/vcl/skia/osx/gdiimpl.cxx b/vcl/skia/osx/gdiimpl.cxx
index c5e8911d339e..8a879e2f7788 100644
--- a/vcl/skia/osx/gdiimpl.cxx
+++ b/vcl/skia/osx/gdiimpl.cxx
@@ -23,7 +23,12 @@
#include <skia/osx/rastercontext.hxx>
+#include <quartz/ctfonts.hxx>
+
#include <SkCanvas.h>
+#include <SkFont.h>
+#include <SkFontMgr_mac_ct.h>
+#include <SkTypeface_mac.h>
using namespace SkiaHelper;
@@ -173,6 +178,52 @@ bool AquaSkiaSalGraphicsImpl::drawNativeControl(ControlType nType, ControlPart n
return bOK;
}
+void AquaSkiaSalGraphicsImpl::drawTextLayout(const GenericSalLayout& rLayout)
+{
+ const CoreTextStyle& rStyle = *static_cast<const CoreTextStyle*>(&rLayout.GetFont());
+ const FontSelectPattern& rFontSelect = rStyle.GetFontSelectPattern();
+ int nHeight = rFontSelect.mnHeight;
+ int nWidth = rFontSelect.mnWidth ? rFontSelect.mnWidth : nHeight;
+ if (nWidth == 0 || nHeight == 0)
+ {
+ SAL_WARN("vcl.skia", "DrawTextLayout(): rFontSelect.mnHeight is zero!?");
+ return;
+ }
+
+ if (!fontManager)
+ {
+ SystemFontList* fontList = GetCoretextFontList();
+ if (fontList == nullptr)
+ {
+ SAL_WARN("vcl.skia", "DrawTextLayout(): No coretext font list");
+ fontManager = SkFontMgr_New_CoreText(nullptr);
+ }
+ else
+ {
+ fontManager = SkFontMgr_New_CoreText(fontList->fontCollection());
+ }
+ }
+
+ CTFontRef pFont
+ = static_cast<CTFontRef>(CFDictionaryGetValue(rStyle.GetStyleDict(), kCTFontAttributeName));
+ sk_sp<SkTypeface> typeface = SkMakeTypefaceFromCTFont(pFont);
+ SkFont font(typeface);
+ font.setSize(nHeight);
+ // font.setScaleX(rStyle.mfFontStretch); TODO
+ if (rStyle.mbFauxBold)
+ font.setEmbolden(true);
+ font.setEdging(!mrShared.mbNonAntialiasedText ? SkFont::Edging::kAntiAlias
+ : SkFont::Edging::kAlias);
+
+ // Vertical font, use width as "height".
+ SkFont verticalFont(font);
+ verticalFont.setSize(nHeight);
+ // verticalFont.setSize(nWidth); TODO
+ // verticalFont.setScaleX(1.0 * nHeight / nWidth);
+
+ drawGenericLayout(rLayout, mrShared.maTextColor, font, verticalFont);
+}
+
std::unique_ptr<sk_app::WindowContext> createVulkanWindowContext(bool /*temporary*/)
{
return nullptr;
More information about the Libreoffice-commits
mailing list