diff --git a/vcl/Library_vclplug_kf5.mk b/vcl/Library_vclplug_kf5.mk index cc518612d0bd..d3b75bb4d79f 100644 --- a/vcl/Library_vclplug_kf5.mk +++ b/vcl/Library_vclplug_kf5.mk @@ -78,6 +78,7 @@ $(eval $(call gb_Library_add_libs,vclplug_kf5,\ $(eval $(call gb_Library_add_exception_objects,vclplug_kf5,\ vcl/unx/kf5/Kf5Data \ vcl/unx/kf5/Kf5Frame \ + vcl/unx/kf5/Kf5FontFace \ vcl/unx/kf5/Kf5Graphics \ vcl/unx/kf5/Kf5Graphics_Controls \ vcl/unx/kf5/Kf5Graphics_GDI \ diff --git a/vcl/inc/PhysicalFontFamily.hxx b/vcl/inc/PhysicalFontFamily.hxx index 34548785c56d..b782c4fe69f4 100644 --- a/vcl/inc/PhysicalFontFamily.hxx +++ b/vcl/inc/PhysicalFontFamily.hxx @@ -20,6 +20,8 @@ #ifndef INCLUDED_VCL_INC_PHYSICALFONTFAMILY_HXX #define INCLUDED_VCL_INC_PHYSICALFONTFAMILY_HXX +#include + #include #include @@ -45,7 +47,7 @@ namespace o3tl { template<> struct typed_flags : is_typed_flags {}; }; -class PhysicalFontFamily +class VCL_PLUGIN_PUBLIC PhysicalFontFamily { public: PhysicalFontFamily( const OUString& rSearchName ); diff --git a/vcl/inc/fontattributes.hxx b/vcl/inc/fontattributes.hxx index 83b68f89464b..5487ac621668 100644 --- a/vcl/inc/fontattributes.hxx +++ b/vcl/inc/fontattributes.hxx @@ -20,13 +20,14 @@ #ifndef INCLUDED_VCL_INC_FONTATTRIBUTES_HXX #define INCLUDED_VCL_INC_FONTATTRIBUTES_HXX +#include #include #include /* The following class is extraordinarily similar to ImplFont. */ -class FontAttributes +class VCL_DLLPUBLIC FontAttributes { public: explicit FontAttributes(); diff --git a/vcl/inc/impfontcharmap.hxx b/vcl/inc/impfontcharmap.hxx index 197333a49b6e..67ba048153fa 100644 --- a/vcl/inc/impfontcharmap.hxx +++ b/vcl/inc/impfontcharmap.hxx @@ -51,7 +51,7 @@ private: int mnCharCount; // covered codepoints }; -bool ParseCMAP( const unsigned char* pRawData, int nRawLength, CmapResult& ); +bool VCL_DLLPUBLIC ParseCMAP( const unsigned char* pRawData, int nRawLength, CmapResult& ); #endif // INCLUDED_VCL_INC_IMPFONTCHARMAP_HXX diff --git a/vcl/inc/sft.hxx b/vcl/inc/sft.hxx index 3d676aa371e8..3dc6cb77b21f 100644 --- a/vcl/inc/sft.hxx +++ b/vcl/inc/sft.hxx @@ -247,7 +247,7 @@ namespace vcl int VCL_DLLPUBLIC OpenTTFontFile(const char *fname, sal_uInt32 facenum, TrueTypeFont** ttf); #endif - bool getTTCoverage( + bool VCL_DLLPUBLIC getTTCoverage( boost::optional> & rUnicodeCoverage, boost::optional> & rCodePageCoverage, const unsigned char* pTable, size_t nLength); diff --git a/vcl/unx/kf5/Kf5FontFace.cxx b/vcl/unx/kf5/Kf5FontFace.cxx new file mode 100644 index 000000000000..2bfa45cc2348 --- /dev/null +++ b/vcl/unx/kf5/Kf5FontFace.cxx @@ -0,0 +1,126 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "Kf5FontFace.hxx" +#include "Kf5Tools.hxx" + +#include +#include +#include +#include +#include + +#include +#include + +using namespace vcl; + +Kf5FontFace::Kf5FontFace( const Kf5FontFace& rSrc ) + : PhysicalFontFace( rSrc ) + , m_aFontId( rSrc.m_aFontId ) +{ + if( rSrc.m_xCharMap.is() ) + m_xCharMap = rSrc.m_xCharMap; +} + +Kf5FontFace* Kf5FontFace::fromQFont( const QFont &rFont ) +{ + FontAttributes aFA; + aFA.SetFamilyName( toOUString( rFont.family() ) ); + aFA.SetStyleName( toOUString( rFont.styleName() ) ); + aFA.SetItalic( rFont.italic() ? ITALIC_NORMAL : ITALIC_NONE ); + + return new Kf5FontFace( aFA, rFont.toString() ) ; +} + +Kf5FontFace::Kf5FontFace( const FontAttributes& rFA, const QString &rFontID ) + : PhysicalFontFace( rFA ) + , m_aFontId( rFontID ) + , m_bFontCapabilitiesRead( false ) +{ +} + +Kf5FontFace::~Kf5FontFace() +{ +} + +sal_IntPtr Kf5FontFace::GetFontId() const +{ + return reinterpret_cast( &m_aFontId ); +} + +const FontCharMapRef Kf5FontFace::GetFontCharMap() +{ + if( m_xCharMap.is() ) + return m_xCharMap; + + QFont aFont; + aFont.fromString( m_aFontId ); + QRawFont aRawFont( QRawFont::fromFont( aFont ) ); + QByteArray aCMapTable = aRawFont.fontTable( "cmap" ); + if ( aCMapTable.isEmpty() ) + { + m_xCharMap = new FontCharMap(); + return m_xCharMap; + } + + CmapResult aCmapResult; + if( ParseCMAP( reinterpret_cast( aCMapTable.data() ), + aCMapTable.size(), aCmapResult ) ) + m_xCharMap = new FontCharMap( aCmapResult ); + + return m_xCharMap; +} + +bool Kf5FontFace::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) +{ + // read this only once per font + if( m_bFontCapabilitiesRead ) + { + rFontCapabilities = m_aFontCapabilities; + return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange; + } + m_bFontCapabilitiesRead = true; + + QFont aFont; + aFont.fromString( m_aFontId ); + QRawFont aRawFont( QRawFont::fromFont( aFont ) ); + QByteArray aOS2Table = aRawFont.fontTable( "OS/2" ); + if ( !aOS2Table.isEmpty() ) + { + vcl::getTTCoverage( m_aFontCapabilities.oUnicodeRange, + m_aFontCapabilities.oCodePageRange, + reinterpret_cast( aOS2Table.data() ), + aOS2Table.size() ); + } + + rFontCapabilities = m_aFontCapabilities; + return rFontCapabilities.oUnicodeRange || rFontCapabilities.oCodePageRange; +} + +PhysicalFontFace* Kf5FontFace::Clone() const +{ + return new Kf5FontFace( *this ); +} + +LogicalFontInstance* Kf5FontFace::CreateFontInstance( const FontSelectPattern& rFSD ) const +{ + return new LogicalFontInstance( rFSD ); +} + diff --git a/vcl/unx/kf5/Kf5FontFace.hxx b/vcl/unx/kf5/Kf5FontFace.hxx new file mode 100644 index 000000000000..d2ae8099f345 --- /dev/null +++ b/vcl/unx/kf5/Kf5FontFace.hxx @@ -0,0 +1,62 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include + +#include +#include +#include + +#include + +class FontAttributes; +class FontSelectPattern; +class QFont; + +class Kf5FontFace : public PhysicalFontFace +{ +public: + virtual ~Kf5FontFace() override; + + static Kf5FontFace* fromQFont( const QFont &rFont ); + + PhysicalFontFace* Clone() const override; + LogicalFontInstance* CreateFontInstance( const FontSelectPattern& ) const override; + sal_IntPtr GetFontId() const override; + + int GetFontTable( const char pTagName[5], unsigned char* ) const; + + const FontCharMapRef GetFontCharMap(); + bool GetFontCapabilities( vcl::FontCapabilities &rFontCapabilities ); + bool HasChar( sal_uInt32 cChar ) const; + +protected: + Kf5FontFace( const Kf5FontFace& ); + Kf5FontFace( const FontAttributes& rFA, const QString &rFontID ); + +private: + const QString m_aFontId; + FontCharMapRef m_xCharMap; + vcl::FontCapabilities m_aFontCapabilities; + bool m_bFontCapabilitiesRead; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/kf5/Kf5Graphics.cxx b/vcl/unx/kf5/Kf5Graphics.cxx index f1627c2a1be1..b68cb3728287 100644 --- a/vcl/unx/kf5/Kf5Graphics.cxx +++ b/vcl/unx/kf5/Kf5Graphics.cxx @@ -25,12 +25,14 @@ Kf5Graphics::Kf5Graphics( Kf5Frame *pFrame ) : m_pFrame( pFrame ) , m_pQImage( nullptr ) + , m_pFontCollection( nullptr ) { } Kf5Graphics::Kf5Graphics( QImage *pQImage ) : m_pFrame( nullptr ) , m_pQImage( pQImage ) + , m_pFontCollection( nullptr ) { } diff --git a/vcl/unx/kf5/Kf5Graphics.hxx b/vcl/unx/kf5/Kf5Graphics.hxx index ff188a890fc1..141f8bdc61e1 100644 --- a/vcl/unx/kf5/Kf5Graphics.hxx +++ b/vcl/unx/kf5/Kf5Graphics.hxx @@ -21,13 +21,19 @@ #include +#include + class Kf5Frame; +class PhysicalFontCollection; +class PhysicalFontFace; class QImage; class Kf5Graphics : public SalGraphics { - Kf5Frame *m_pFrame; - QImage *m_pQImage; + Kf5Frame *m_pFrame; + QImage *m_pQImage; + PhysicalFontCollection *m_pFontCollection; + PhysicalFontFace *m_pFont; public: Kf5Graphics( Kf5Frame *pFrame ); diff --git a/vcl/unx/kf5/Kf5Graphics_GDI.cxx b/vcl/unx/kf5/Kf5Graphics_GDI.cxx index 7e4f6b0da183..12863565364c 100644 --- a/vcl/unx/kf5/Kf5Graphics_GDI.cxx +++ b/vcl/unx/kf5/Kf5Graphics_GDI.cxx @@ -19,7 +19,7 @@ #include "Kf5Graphics.hxx" -bool Kf5Graphics::setClipRegion( const vcl::Region& ) +bool Kf5Graphics::setClipRegion( const vcl::Region& rRegion ) { return false; } @@ -77,13 +77,12 @@ bool Kf5Graphics::drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt32* pPo return false; } -bool Kf5Graphics::drawPolyLine( - const basegfx::B2DPolygon&, +bool Kf5Graphics::drawPolyLine( const basegfx::B2DPolygon&, double fTransparency, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin, css::drawing::LineCap eLineCap, - double fMiterMinimumAngle) + double fMiterMinimumAngle ) { return false; } @@ -125,7 +124,7 @@ SalBitmap* Kf5Graphics::getBitmap( long nX, long nY, long nWidth, long nHeight ) SalColor Kf5Graphics::getPixel( long nX, long nY ) { - return SalColor(); + return 0; } void Kf5Graphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert nFlags) diff --git a/vcl/unx/kf5/Kf5Graphics_Text.cxx b/vcl/unx/kf5/Kf5Graphics_Text.cxx index 23eacc5ffda8..28af6be1bf65 100644 --- a/vcl/unx/kf5/Kf5Graphics_Text.cxx +++ b/vcl/unx/kf5/Kf5Graphics_Text.cxx @@ -18,9 +18,15 @@ */ #include "Kf5Graphics.hxx" +#include "Kf5FontFace.hxx" #include +#include + +#include +#include + void Kf5Graphics::SetTextColor( SalColor nSalColor ) { } @@ -29,7 +35,7 @@ void Kf5Graphics::SetFont( const FontSelectPattern*, int nFallbackLevel ) { } -void Kf5Graphics::GetFontMetric( ImplFontMetricDataRef&, int nFallbackLevel ) +void Kf5Graphics::GetFontMetric( ImplFontMetricDataRef &rFMD, int nFallbackLevel ) { } @@ -43,8 +49,20 @@ bool Kf5Graphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) return false; } -void Kf5Graphics::GetDevFontList( PhysicalFontCollection* ) +void Kf5Graphics::GetDevFontList( PhysicalFontCollection* pPFC ) { + m_pFontCollection = pPFC; + if ( pPFC->Count() ) + return; + + QFontDatabase aFDB; + for ( auto& family : aFDB.families() ) + for ( auto& style : aFDB.styles( family ) ) + { + // Just get any size - we don't care + QList sizes = aFDB.smoothSizes(family, style); + pPFC->Add( Kf5FontFace::fromQFont( aFDB.font( family, style, *sizes.begin() ) ) ); + } } void Kf5Graphics::ClearDevFontCache() diff --git a/vcl/unx/kf5/Kf5Tools.hxx b/vcl/unx/kf5/Kf5Tools.hxx new file mode 100644 index 000000000000..d5ba80bc0898 --- /dev/null +++ b/vcl/unx/kf5/Kf5Tools.hxx @@ -0,0 +1,38 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include + +#include + +inline OUString toOUString(const QString& s) +{ + // QString stores UTF16, just like OUString + return OUString(reinterpret_cast(s.data()), s.length()); +} + +inline QString toQString(const OUString& s) +{ + return QString::fromUtf16( + reinterpret_cast(s.getStr()), s.getLength()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/kf5/Kf5VirtualDevice.cxx b/vcl/unx/kf5/Kf5VirtualDevice.cxx index 866a49ba28d1..9c0e4864a55c 100644 --- a/vcl/unx/kf5/Kf5VirtualDevice.cxx +++ b/vcl/unx/kf5/Kf5VirtualDevice.cxx @@ -19,6 +19,10 @@ #include "Kf5VirtualDevice.hxx" +#include "Kf5Graphics.hxx" + +#include + Kf5VirtualDevice::Kf5VirtualDevice( DeviceFormat eFormat, double fScale ) { } @@ -29,32 +33,69 @@ Kf5VirtualDevice::~Kf5VirtualDevice() SalGraphics* Kf5VirtualDevice::AcquireGraphics() { - return nullptr; + assert( m_pImage ); + Kf5Graphics* pGraphics = new Kf5Graphics( m_pImage.get() ); + m_aGraphics.push_back( pGraphics ); + return pGraphics; } void Kf5VirtualDevice::ReleaseGraphics( SalGraphics* pGraphics ) { + m_aGraphics.remove( dynamic_cast( pGraphics ) ); + delete pGraphics; } bool Kf5VirtualDevice::SetSize( long nNewDX, long nNewDY ) { - return false; + return SetSizeUsingBuffer( nNewDX, nNewDY, nullptr ); } bool Kf5VirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY, sal_uInt8 * pBuffer ) { - return false; + if( nNewDX == 0 ) + nNewDX = 1; + if( nNewDY == 0 ) + nNewDY = 1; + + if( m_pImage && m_aFrameSize.getX() != nNewDX + && m_aFrameSize.getY() != nNewDY ) + return true; + + m_aFrameSize = basegfx::B2IVector( nNewDX, nNewDY ); + + nNewDX *= m_fScale; + nNewDY *= m_fScale; + + if (m_eFormat == DeviceFormat::BITMASK) + { + m_pImage.reset( new QImage( nNewDX, nNewDY, QImage::Format_Mono ) ); + } + else + { + if ( pBuffer ) + m_pImage.reset( new QImage( pBuffer, nNewDX, nNewDY, QImage::Format_ARGB32 ) ); + else + m_pImage.reset( new QImage( nNewDX, nNewDY, QImage::Format_ARGB32 ) ); + } + + m_pImage->setDevicePixelRatio( m_fScale ); + + // update device in existing graphics + for( auto pKf5Graph : m_aGraphics ) + pKf5Graph->ChangeQImage( m_pImage.get() ); + + return true; } long Kf5VirtualDevice::GetWidth() const { - return 0; + return m_pImage ? m_aFrameSize.getX() : 0; } long Kf5VirtualDevice::GetHeight() const { - return 0; + return m_pImage ? m_aFrameSize.getY() : 0; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/kf5/Kf5VirtualDevice.hxx b/vcl/unx/kf5/Kf5VirtualDevice.hxx index 9bffaa12861b..7b50a6e7d2dc 100644 --- a/vcl/unx/kf5/Kf5VirtualDevice.hxx +++ b/vcl/unx/kf5/Kf5VirtualDevice.hxx @@ -20,18 +20,22 @@ #pragma once #include - #include +#include #include class Kf5Graphics; +class QImage; enum class DeviceFormat; class Kf5VirtualDevice : public SalVirtualDevice { - basegfx::B2IVector m_aFrameSize; std::list< Kf5Graphics* > m_aGraphics; + std::unique_ptr< QImage > m_pImage; + DeviceFormat m_eFormat; + basegfx::B2IVector m_aFrameSize; + double m_fScale; public: Kf5VirtualDevice( DeviceFormat eFormat, double fScale );