KF5 add FontFace implementation

To pass the "Application error: no fonts and no vcl resource found
on your system" failure from OutputDevice::ImplInitFontList.

Just saw there is a SAL_NO_FONT_LOOKUP, which probably also would
have helped.

Change-Id: I2c818313c4f8b0f1d36242281e5c51973315b642
This commit is contained in:
Jan-Marek Glogowski 2017-10-31 01:10:36 +01:00 committed by Thorsten Behrens
parent 688e32b75d
commit 97d520049f
14 changed files with 320 additions and 20 deletions

View file

@ -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 \

View file

@ -20,6 +20,8 @@
#ifndef INCLUDED_VCL_INC_PHYSICALFONTFAMILY_HXX
#define INCLUDED_VCL_INC_PHYSICALFONTFAMILY_HXX
#include <vcl/dllapi.h>
#include <set>
#include <unotools/fontcfg.hxx>
@ -45,7 +47,7 @@ namespace o3tl {
template<> struct typed_flags<FontTypeFaces> : is_typed_flags<FontTypeFaces, 0xff> {};
};
class PhysicalFontFamily
class VCL_PLUGIN_PUBLIC PhysicalFontFamily
{
public:
PhysicalFontFamily( const OUString& rSearchName );

View file

@ -20,13 +20,14 @@
#ifndef INCLUDED_VCL_INC_FONTATTRIBUTES_HXX
#define INCLUDED_VCL_INC_FONTATTRIBUTES_HXX
#include <vcl/dllapi.h>
#include <rtl/ustring.hxx>
#include <vcl/vclenum.hxx>
/* The following class is extraordinarily similar to ImplFont. */
class FontAttributes
class VCL_DLLPUBLIC FontAttributes
{
public:
explicit FontAttributes();

View file

@ -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

View file

@ -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<std::bitset<UnicodeCoverage::MAX_UC_ENUM>> & rUnicodeCoverage,
boost::optional<std::bitset<CodePageCoverage::MAX_CP_ENUM>> & rCodePageCoverage,
const unsigned char* pTable, size_t nLength);

126
vcl/unx/kf5/Kf5FontFace.cxx Normal file
View file

@ -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 <sft.hxx>
#include <impfontcharmap.hxx>
#include <fontinstance.hxx>
#include <fontselect.hxx>
#include <PhysicalFontCollection.hxx>
#include <QtGui/QFont>
#include <QtGui/QRawFont>
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<sal_IntPtr>( &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<const unsigned char*>( 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<const unsigned char*>( 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 );
}

View file

@ -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 <PhysicalFontFace.hxx>
#include <tools/ref.hxx>
#include <vcl/fontcapabilities.hxx>
#include <vcl/fontcharmap.hxx>
#include <QtCore/QString>
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: */

View file

@ -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 )
{
}

View file

@ -21,13 +21,19 @@
#include <salgdi.hxx>
#include <memory>
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 );

View file

@ -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)

View file

@ -18,9 +18,15 @@
*/
#include "Kf5Graphics.hxx"
#include "Kf5FontFace.hxx"
#include <vcl/fontcharmap.hxx>
#include <PhysicalFontCollection.hxx>
#include <QtGui/QFontDatabase>
#include <QtCore/QStringList>
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<int> sizes = aFDB.smoothSizes(family, style);
pPFC->Add( Kf5FontFace::fromQFont( aFDB.font( family, style, *sizes.begin() ) ) );
}
}
void Kf5Graphics::ClearDevFontCache()

38
vcl/unx/kf5/Kf5Tools.hxx Normal file
View file

@ -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 <QtCore/QString>
#include <rtl/string.hxx>
inline OUString toOUString(const QString& s)
{
// QString stores UTF16, just like OUString
return OUString(reinterpret_cast<const sal_Unicode*>(s.data()), s.length());
}
inline QString toQString(const OUString& s)
{
return QString::fromUtf16(
reinterpret_cast<ushort const *>(s.getStr()), s.getLength());
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -19,6 +19,10 @@
#include "Kf5VirtualDevice.hxx"
#include "Kf5Graphics.hxx"
#include <QtGui/QImage>
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<Kf5Graphics*>( 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: */

View file

@ -20,18 +20,22 @@
#pragma once
#include <salvd.hxx>
#include <basegfx/vector/b2ivector.hxx>
#include <memory>
#include <list>
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 );