vcl/Library_vcl.mk | 1 vcl/StaticLibrary_headless.mk | 1 vcl/headless/svpgdi.cxx | 27 -- vcl/headless/svptext.cxx | 396 ++--------------------------- vcl/headless/svptextrender.cxx | 496 +++++++++++++++++++++++++++++++++++++ vcl/inc/devicetextrender.hxx | 24 + vcl/inc/headless/svpgdi.hxx | 18 - vcl/inc/headless/svptextrender.hxx | 82 ++++++ 8 files changed, 651 insertions(+), 394 deletions(-)
New commits: commit dd179370e0905dc4ae206467d65cb69b70d5356e Author: Caolán McNamara <caol...@redhat.com> Date: Fri Feb 27 11:01:49 2015 +0000 seperate headless textrendering into its own class and forward calls to it from the SvpGraphics Change-Id: I6d1fbc8919596d5f47661b3471570fcb7e14bc3e diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index e114ae3..6aeb70b 100644 --- a/vcl/Library_vcl.mk +++ b/vcl/Library_vcl.mk @@ -558,6 +558,7 @@ vcl_headless_code= \ vcl_headless_freetype_code=\ vcl/headless/svpprn \ vcl/headless/svptext \ + vcl/headless/svptextrender \ ifeq ($(GUIBASE),unx) $(eval $(call gb_Library_add_exception_objects,vcl,\ diff --git a/vcl/StaticLibrary_headless.mk b/vcl/StaticLibrary_headless.mk index 1b63851..941f4ed 100644 --- a/vcl/StaticLibrary_headless.mk +++ b/vcl/StaticLibrary_headless.mk @@ -25,6 +25,7 @@ $(eval $(call gb_StaticLibrary_add_exception_objects,headless,\ vcl/headless/svpframe \ vcl/headless/svpprn \ vcl/headless/svptext \ + vcl/headless/svptextrender \ vcl/headless/svpvd \ )) diff --git a/vcl/headless/svpgdi.cxx b/vcl/headless/svpgdi.cxx index 3f63146..677d165 100644 --- a/vcl/headless/svpgdi.cxx +++ b/vcl/headless/svpgdi.cxx @@ -19,6 +19,7 @@ #include "headless/svpgdi.hxx" #include "headless/svpbmp.hxx" +#include "headless/svptextrender.hxx" #include "saldatabasic.hxx" #include <vcl/sysdata.hxx> @@ -101,12 +102,9 @@ SvpSalGraphics::SvpSalGraphics() : m_bUseFillColor( false ), m_aFillColor( COL_WHITE ), m_aDrawMode( basebmp::DrawMode_PAINT ), - m_aTextColor( COL_BLACK ), - m_eTextFmt( basebmp::FORMAT_EIGHT_BIT_GREY ), m_bClipSetup( false ) { - for( int i = 0; i < MAX_FALLBACK; ++i ) - m_pServerFont[i] = NULL; + m_xTextRenderImpl.reset(new SvpTextRender(*this)); } SvpSalGraphics::~SvpSalGraphics() @@ -117,26 +115,7 @@ void SvpSalGraphics::setDevice( basebmp::BitmapDeviceSharedPtr& rDevice ) { m_aOrigDevice = rDevice; ResetClipRegion(); - - // determine matching bitmap format for masks - basebmp::Format nDeviceFmt = m_aDevice ? m_aDevice->getScanlineFormat() : basebmp::FORMAT_EIGHT_BIT_GREY; - switch( nDeviceFmt ) - { - case basebmp::FORMAT_EIGHT_BIT_GREY: - case basebmp::FORMAT_SIXTEEN_BIT_LSB_TC_MASK: - case basebmp::FORMAT_SIXTEEN_BIT_MSB_TC_MASK: - case basebmp::FORMAT_TWENTYFOUR_BIT_TC_MASK: - case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX: - case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA: - case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_ARGB: - case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_ABGR: - case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA: - m_eTextFmt = basebmp::FORMAT_EIGHT_BIT_GREY; - break; - default: - m_eTextFmt = basebmp::FORMAT_ONE_BIT_LSB_GREY; - break; - } + m_xTextRenderImpl->setDevice(rDevice); } #endif diff --git a/vcl/headless/svptext.cxx b/vcl/headless/svptext.cxx index ef6e1ab..1651a3a 100644 --- a/vcl/headless/svptext.cxx +++ b/vcl/headless/svptext.cxx @@ -18,279 +18,43 @@ */ #include <sal/types.h> - -#include <cassert> - -#include <basebmp/scanlineformats.hxx> -#include <basegfx/polygon/b2dpolypolygon.hxx> -#include <basegfx/range/b2drange.hxx> #include <basegfx/range/b2ibox.hxx> -#include <rtl/instance.hxx> -#include <tools/debug.hxx> -#include <vcl/sysdata.hxx> - -#include "generic/geninst.h" -#include "generic/genpspgraphics.h" -#include "generic/glyphcache.hxx" -#include "headless/svpbmp.hxx" #include "headless/svpgdi.hxx" -#include "impfont.hxx" -#include "outfont.hxx" -#include "PhysicalFontFace.hxx" - -class PhysicalFontCollection; - -using namespace basegfx; -using namespace basebmp; - -class SvpGlyphPeer : public GlyphCachePeer -{ -public: - SvpGlyphPeer() {} - - BitmapDeviceSharedPtr GetGlyphBmp( ServerFont&, sal_GlyphId, - basebmp::Format nBmpFormat, B2IPoint& rTargetPos ); - -protected: - virtual void RemovingFont( ServerFont& ) SAL_OVERRIDE; - virtual void RemovingGlyph( GlyphData& ) SAL_OVERRIDE; - - class SvpGcpHelper - { - public: - RawBitmap maRawBitmap; - BitmapDeviceSharedPtr maBitmapDev; - }; -}; - -class SvpGlyphCache : public GlyphCache -{ -public: - SvpGlyphCache( SvpGlyphPeer& rPeer ) : GlyphCache( rPeer) {} - SvpGlyphPeer& GetPeer() { return reinterpret_cast<SvpGlyphPeer&>( mrPeer ); } - static SvpGlyphCache& GetInstance(); -}; - -namespace -{ - struct GlyphCacheHolder - { - private: - SvpGlyphPeer* m_pSvpGlyphPeer; - SvpGlyphCache* m_pSvpGlyphCache; - public: - GlyphCacheHolder() - { - m_pSvpGlyphPeer = new SvpGlyphPeer(); - m_pSvpGlyphCache = new SvpGlyphCache( *m_pSvpGlyphPeer ); - } - void release() - { - delete m_pSvpGlyphCache; - delete m_pSvpGlyphPeer; - m_pSvpGlyphCache = NULL; - m_pSvpGlyphPeer = NULL; - } - SvpGlyphCache& getGlyphCache() - { - return *m_pSvpGlyphCache; - } - ~GlyphCacheHolder() - { - release(); - } - }; - - struct theGlyphCacheHolder : - public rtl::Static<GlyphCacheHolder, theGlyphCacheHolder> - {}; -} - -SvpGlyphCache& SvpGlyphCache::GetInstance() -{ - return theGlyphCacheHolder::get().getGlyphCache(); -} - -BitmapDeviceSharedPtr SvpGlyphPeer::GetGlyphBmp( ServerFont& rServerFont, - sal_GlyphId aGlyphId, basebmp::Format nBmpFormat, B2IPoint& rTargetPos ) -{ - GlyphData& rGlyphData = rServerFont.GetGlyphData( aGlyphId ); - - if( rGlyphData.ExtDataRef().meInfo != nBmpFormat ) - { - SvpGcpHelper* pGcpHelper = static_cast<SvpGcpHelper*>( - rGlyphData.ExtDataRef().mpData); - bool bNew = pGcpHelper == 0; - if( bNew ) - pGcpHelper = new SvpGcpHelper; - - // get glyph bitmap in matching format - bool bFound = false; - switch( nBmpFormat ) - { - case FORMAT_ONE_BIT_LSB_GREY: - bFound = rServerFont.GetGlyphBitmap1( aGlyphId, pGcpHelper->maRawBitmap ); - break; - case FORMAT_EIGHT_BIT_GREY: - bFound = rServerFont.GetGlyphBitmap8( aGlyphId, pGcpHelper->maRawBitmap ); - break; - default: - OSL_FAIL( "SVP GCP::GetGlyphBmp(): illegal scanline format"); - // fall back to black&white mask - nBmpFormat = FORMAT_ONE_BIT_LSB_GREY; - bFound = false; - break; - } - - // return .notdef glyph if needed - if( !bFound && (aGlyphId != 0) ) - { - if( bNew ) - delete pGcpHelper; - return GetGlyphBmp( rServerFont, 0, nBmpFormat, rTargetPos ); - } - - // construct alpha mask from raw bitmap - if (pGcpHelper->maRawBitmap.mnScanlineSize && pGcpHelper->maRawBitmap.mnHeight) - { - const B2IVector aSize( - pGcpHelper->maRawBitmap.mnScanlineSize, - pGcpHelper->maRawBitmap.mnHeight ); - static PaletteMemorySharedVector aDummyPAL; - pGcpHelper->maBitmapDev = createBitmapDevice( aSize, true, nBmpFormat, aSize.getX(), pGcpHelper->maRawBitmap.mpBits, aDummyPAL ); - } - - rGlyphData.ExtDataRef().meInfo = nBmpFormat; - rGlyphData.ExtDataRef().mpData = pGcpHelper; - } - - SvpGcpHelper* pGcpHelper = static_cast<SvpGcpHelper*>( - rGlyphData.ExtDataRef().mpData); - assert(pGcpHelper != 0); - rTargetPos += B2IPoint( pGcpHelper->maRawBitmap.mnXOffset, pGcpHelper->maRawBitmap.mnYOffset ); - return pGcpHelper->maBitmapDev; -} - -void SvpGlyphPeer::RemovingFont( ServerFont& ) -{ - // nothing to do: no font resources held in SvpGlyphPeer -} - -void SvpGlyphPeer::RemovingGlyph( GlyphData& rGlyphData ) -{ - SvpGcpHelper* pGcpHelper = static_cast<SvpGcpHelper*>( - rGlyphData.ExtDataRef().mpData); - rGlyphData.ExtDataRef().meInfo = basebmp::FORMAT_NONE; - rGlyphData.ExtDataRef().mpData = 0; - delete pGcpHelper; -} sal_uInt16 SvpSalGraphics::SetFont( FontSelectPattern* pIFSD, int nFallbackLevel ) { - // release all no longer needed font resources - for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i ) - { - if( m_pServerFont[i] != NULL ) - { - // old server side font is no longer referenced - SvpGlyphCache::GetInstance().UncacheFont( *m_pServerFont[i] ); - m_pServerFont[i] = NULL; - } - } - - // return early if there is no new font - if( !pIFSD ) - return 0; - - // handle the request for a non-native X11-font => use the GlyphCache - ServerFont* pServerFont = SvpGlyphCache::GetInstance().CacheFont( *pIFSD ); - if( !pServerFont ) - return SAL_SETFONT_BADFONT; - - // check selected font - if( !pServerFont->TestFont() ) - { - SvpGlyphCache::GetInstance().UncacheFont( *pServerFont ); - return SAL_SETFONT_BADFONT; - } - - // update SalGraphics font settings - m_pServerFont[ nFallbackLevel ] = pServerFont; - return SAL_SETFONT_USEDRAWTEXTARRAY; + return m_xTextRenderImpl->SetFont(pIFSD, nFallbackLevel); } void SvpSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLevel ) { - if( nFallbackLevel >= MAX_FALLBACK ) - return; - - if( m_pServerFont[nFallbackLevel] != NULL ) - { - long rDummyFactor; - m_pServerFont[nFallbackLevel]->FetchFontMetric( *pMetric, rDummyFactor ); - } + m_xTextRenderImpl->GetFontMetric(pMetric, nFallbackLevel); } const FontCharMapPtr SvpSalGraphics::GetFontCharMap() const { - if( !m_pServerFont[0] ) - return NULL; - - const FontCharMapPtr pFCMap = m_pServerFont[0]->GetFontCharMap(); - return pFCMap; + return m_xTextRenderImpl->GetFontCharMap(); } bool SvpSalGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const { - if (!m_pServerFont[0]) - return false; - - return m_pServerFont[0]->GetFontCapabilities(rFontCapabilities); + return m_xTextRenderImpl->GetFontCapabilities(rFontCapabilities); } void SvpSalGraphics::GetDevFontList( PhysicalFontCollection* pFontCollection ) { - GlyphCache& rGC = SvpGlyphCache::GetInstance(); - - psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); - psp::FastPrintFontInfo aInfo; - ::std::list< psp::fontID > aList; - rMgr.getFontList( aList ); - ::std::list< psp::fontID >::iterator it; - for( it = aList.begin(); it != aList.end(); ++it ) - { - if( !rMgr.getFontFastInfo( *it, aInfo ) ) - continue; - - // normalize face number to the GlyphCache - int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID ); - - // inform GlyphCache about this font provided by the PsPrint subsystem - ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo ); - aDFA.mnQuality += 4096; - const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID ); - rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA ); - } - - // announce glyphcache fonts - rGC.AnnounceFonts( pFontCollection ); - - // register platform specific font substitutions if available - SalGenericInstance::RegisterFontSubstitutors( pFontCollection ); - - ImplGetSVData()->maGDIData.mbNativeFontConfig = true; + m_xTextRenderImpl->GetDevFontList(pFontCollection); } void SvpSalGraphics::ClearDevFontCache() { - GlyphCache& rGC = SvpGlyphCache::GetInstance(); - rGC.ClearFontCache(); + m_xTextRenderImpl->ClearDevFontCache(); } -bool SvpSalGraphics::AddTempDevFont( PhysicalFontCollection*, - const OUString&, const OUString& ) +bool SvpSalGraphics::AddTempDevFont( PhysicalFontCollection* pFontCollection, + const OUString& rFileURL, const OUString& rFontName) { - return false; + return m_xTextRenderImpl->AddTempDevFont(pFontCollection, rFileURL, rFontName); } bool SvpSalGraphics::CreateFontSubset( @@ -300,36 +64,14 @@ bool SvpSalGraphics::CreateFontSubset( const sal_uInt8* pEncoding, sal_Int32* pWidths, int nGlyphCount, - FontSubsetInfo& rInfo - ) + FontSubsetInfo& rInfo) { - // in this context the pFont->GetFontId() is a valid PSP - // font since they are the only ones left after the PDF - // export has filtered its list of subsettable fonts (for - // which this method was created). The correct way would - // be to have the GlyphCache search for the PhysicalFontFace pFont - psp::fontID aFont = pFont->GetFontId(); - - psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); - bool bSuccess = rMgr.createFontSubset( rInfo, - aFont, - rToFile, - pGlyphIds, - pEncoding, - pWidths, - nGlyphCount ); - return bSuccess; + return m_xTextRenderImpl->CreateFontSubset(rToFile, pFont, pGlyphIds, pEncoding, pWidths, nGlyphCount, rInfo); } const Ucs2SIntMap* SvpSalGraphics::GetFontEncodingVector( const PhysicalFontFace* pFont, const Ucs2OStrMap** pNonEncoded, std::set<sal_Unicode> const** ppPriority) { - // in this context the pFont->GetFontId() is a valid PSP - // font since they are the only ones left after the PDF - // export has filtered its list of subsettable fonts (for - // which this method was created). The correct way would - // be to have the GlyphCache search for the PhysicalFontFace pFont - psp::fontID aFont = pFont->GetFontId(); - return GenPspGraphics::DoGetFontEncodingVector(aFont, pNonEncoded, ppPriority); + return m_xTextRenderImpl->GetFontEncodingVector(pFont, pNonEncoded, ppPriority); } const void* SvpSalGraphics::GetEmbedFontData( @@ -338,21 +80,14 @@ const void* SvpSalGraphics::GetEmbedFontData( sal_Int32* pWidths, size_t nLen, FontSubsetInfo& rInfo, - long* pDataLen - ) + long* pDataLen) { - // in this context the pFont->GetFontId() is a valid PSP - // font since they are the only ones left after the PDF - // export has filtered its list of subsettable fonts (for - // which this method was created). The correct way would - // be to have the GlyphCache search for the PhysicalFontFace pFont - psp::fontID aFont = pFont->GetFontId(); - return GenPspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, nLen, rInfo, pDataLen ); + return m_xTextRenderImpl->GetEmbedFontData(pFont, pUnicodes, pWidths, nLen, rInfo, pDataLen); } void SvpSalGraphics::FreeEmbedFontData( const void* pData, long nLen ) { - GenPspGraphics::DoFreeEmbedFontData( pData, nLen ); + m_xTextRenderImpl->FreeEmbedFontData(pData, nLen); } void SvpSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, @@ -360,110 +95,51 @@ void SvpSalGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, Int32Vector& rWidths, Ucs2UIntMap& rUnicodeEnc ) { - // in this context the pFont->GetFontId() is a valid PSP - // font since they are the only ones left after the PDF - // export has filtered its list of subsettable fonts (for - // which this method was created). The correct way would - // be to have the GlyphCache search for the PhysicalFontFace pFont - psp::fontID aFont = pFont->GetFontId(); - GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc ); + m_xTextRenderImpl->GetGlyphWidths(pFont, bVertical, rWidths, rUnicodeEnc); } bool SvpSalGraphics::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect ) { - const int nLevel = aGlyphId >> GF_FONTSHIFT; - if( nLevel >= MAX_FALLBACK ) - return false; - - ServerFont* pSF = m_pServerFont[ nLevel ]; - if( !pSF ) - return false; - - aGlyphId &= GF_IDXMASK; - const GlyphMetric& rGM = pSF->GetGlyphMetric( aGlyphId ); - rRect = Rectangle( rGM.GetOffset(), rGM.GetSize() ); - return true; + return m_xTextRenderImpl->GetGlyphBoundRect(aGlyphId, rRect); } -bool SvpSalGraphics::GetGlyphOutline( sal_GlyphId aGlyphId, B2DPolyPolygon& rPolyPoly ) +bool SvpSalGraphics::GetGlyphOutline( sal_GlyphId aGlyphId, basegfx::B2DPolyPolygon& rPolyPoly ) { - const int nLevel = aGlyphId >> GF_FONTSHIFT; - if( nLevel >= MAX_FALLBACK ) - return false; - - const ServerFont* pSF = m_pServerFont[ nLevel ]; - if( !pSF ) - return false; - - aGlyphId &= GF_IDXMASK; - if( pSF->GetGlyphOutline( aGlyphId, rPolyPoly ) ) - return true; - - return false; + return m_xTextRenderImpl->GetGlyphOutline(aGlyphId, rPolyPoly); } -SalLayout* SvpSalGraphics::GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) +SalLayout* SvpSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel ) { - GenericSalLayout* pLayout = NULL; - - if( m_pServerFont[ nFallbackLevel ] ) - pLayout = new ServerFontLayout( *m_pServerFont[ nFallbackLevel ] ); - - return pLayout; + return m_xTextRenderImpl->GetTextLayout(rArgs, nFallbackLevel); } void SvpSalGraphics::DrawServerFontLayout( const ServerFontLayout& rSalLayout ) { - // iterate over all glyphs in the layout - Point aPos; - sal_GlyphId aGlyphId; - SvpGlyphPeer& rGlyphPeer = SvpGlyphCache::GetInstance().GetPeer(); - for( int nStart = 0; rSalLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); ) - { - int nLevel = aGlyphId >> GF_FONTSHIFT; - DBG_ASSERT( nLevel < MAX_FALLBACK, "SvpGDI: invalid glyph fallback level" ); - ServerFont* pSF = m_pServerFont[ nLevel ]; - if( !pSF ) - continue; - - // get the glyph's alpha mask and adjust the drawing position - aGlyphId &= GF_IDXMASK; - B2IPoint aDstPoint( aPos.X(), aPos.Y() ); - BitmapDeviceSharedPtr aAlphaMask - = rGlyphPeer.GetGlyphBmp( *pSF, aGlyphId, m_eTextFmt, aDstPoint ); - if( !aAlphaMask ) // ignore empty glyphs - continue; - - // blend text color into target using the glyph's mask - const B2IBox aSrcRect( B2ITuple(0,0), aAlphaMask->getSize() ); - const B2IBox aClipRect( aDstPoint, aAlphaMask->getSize() ); - - SvpSalGraphics::ClipUndoHandle aUndo( this ); - if( !isClippedSetup( aClipRect, aUndo ) ) - m_aDevice->drawMaskedColor( m_aTextColor, aAlphaMask, - aSrcRect, aDstPoint, m_aClipMap ); - } + m_xTextRenderImpl->DrawServerFontLayout(rSalLayout ); } void SvpSalGraphics::SetTextColor( SalColor nSalColor ) { - m_aTextColor = basebmp::Color( nSalColor ); + m_xTextRenderImpl->SetTextColor(nSalColor); } SystemFontData SvpSalGraphics::GetSysFontData( int nFallbacklevel ) const { - SystemFontData aSysFontData; + return m_xTextRenderImpl->GetSysFontData(nFallbacklevel); +} - if (nFallbacklevel >= MAX_FALLBACK) nFallbacklevel = MAX_FALLBACK - 1; - if (nFallbacklevel < 0 ) nFallbacklevel = 0; +void SvpSalGraphics::BlendTextColor(const basebmp::Color &rTextColor, const basebmp::BitmapDeviceSharedPtr &rAlphaMask, + const basegfx::B2IPoint &rDstPoint) +{ + // blend text color into target using the glyph's mask + const basegfx::B2IBox aSrcRect(basegfx::B2ITuple(0,0), rAlphaMask->getSize()); + const basegfx::B2IBox aClipRect(rDstPoint, rAlphaMask->getSize()); + + SvpSalGraphics::ClipUndoHandle aUndo(this); + if (isClippedSetup(aClipRect, aUndo)) + return; - aSysFontData.nSize = sizeof( SystemFontData ); - aSysFontData.nFontId = 0; - aSysFontData.nFontFlags = 0; - aSysFontData.bFakeBold = false; - aSysFontData.bFakeItalic = false; - aSysFontData.bAntialias = true; - return aSysFontData; + m_aDevice->drawMaskedColor(rTextColor, rAlphaMask, aSrcRect, rDstPoint, m_aClipMap); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/headless/svptextrender.cxx b/vcl/headless/svptextrender.cxx new file mode 100644 index 0000000..d28de18 --- /dev/null +++ b/vcl/headless/svptextrender.cxx @@ -0,0 +1,496 @@ +/* -*- 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 <sal/types.h> + +#include <cassert> + +#include <basebmp/scanlineformats.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/range/b2drange.hxx> +#include <basegfx/range/b2ibox.hxx> +#include <rtl/instance.hxx> +#include <tools/debug.hxx> +#include <vcl/sysdata.hxx> + +#include "generic/geninst.h" +#include "generic/genpspgraphics.h" +#include "generic/glyphcache.hxx" +#include "headless/svpbmp.hxx" +#include "headless/svpgdi.hxx" +#include "headless/svptextrender.hxx" +#include "impfont.hxx" +#include "outfont.hxx" +#include "PhysicalFontFace.hxx" + +class PhysicalFontCollection; + +using namespace basegfx; +using namespace basebmp; + +class SvpGlyphPeer : public GlyphCachePeer +{ +public: + SvpGlyphPeer() {} + + BitmapDeviceSharedPtr GetGlyphBmp( ServerFont&, sal_GlyphId, + basebmp::Format nBmpFormat, B2IPoint& rTargetPos ); + +protected: + virtual void RemovingFont( ServerFont& ) SAL_OVERRIDE; + virtual void RemovingGlyph( GlyphData& ) SAL_OVERRIDE; + + class SvpGcpHelper + { + public: + RawBitmap maRawBitmap; + BitmapDeviceSharedPtr maBitmapDev; + }; +}; + +class SvpGlyphCache : public GlyphCache +{ +public: + SvpGlyphCache( SvpGlyphPeer& rPeer ) : GlyphCache( rPeer) {} + SvpGlyphPeer& GetPeer() { return reinterpret_cast<SvpGlyphPeer&>( mrPeer ); } + static SvpGlyphCache& GetInstance(); +}; + +namespace +{ + struct GlyphCacheHolder + { + private: + SvpGlyphPeer* m_pSvpGlyphPeer; + SvpGlyphCache* m_pSvpGlyphCache; + public: + GlyphCacheHolder() + { + m_pSvpGlyphPeer = new SvpGlyphPeer(); + m_pSvpGlyphCache = new SvpGlyphCache( *m_pSvpGlyphPeer ); + } + void release() + { + delete m_pSvpGlyphCache; + delete m_pSvpGlyphPeer; + m_pSvpGlyphCache = NULL; + m_pSvpGlyphPeer = NULL; + } + SvpGlyphCache& getGlyphCache() + { + return *m_pSvpGlyphCache; + } + ~GlyphCacheHolder() + { + release(); + } + }; + + struct theGlyphCacheHolder : + public rtl::Static<GlyphCacheHolder, theGlyphCacheHolder> + {}; +} + +SvpGlyphCache& SvpGlyphCache::GetInstance() +{ + return theGlyphCacheHolder::get().getGlyphCache(); +} + +BitmapDeviceSharedPtr SvpGlyphPeer::GetGlyphBmp( ServerFont& rServerFont, + sal_GlyphId aGlyphId, basebmp::Format nBmpFormat, B2IPoint& rTargetPos ) +{ + GlyphData& rGlyphData = rServerFont.GetGlyphData( aGlyphId ); + + if( rGlyphData.ExtDataRef().meInfo != nBmpFormat ) + { + SvpGcpHelper* pGcpHelper = static_cast<SvpGcpHelper*>( + rGlyphData.ExtDataRef().mpData); + bool bNew = pGcpHelper == 0; + if( bNew ) + pGcpHelper = new SvpGcpHelper; + + // get glyph bitmap in matching format + bool bFound = false; + switch( nBmpFormat ) + { + case FORMAT_ONE_BIT_LSB_GREY: + bFound = rServerFont.GetGlyphBitmap1( aGlyphId, pGcpHelper->maRawBitmap ); + break; + case FORMAT_EIGHT_BIT_GREY: + bFound = rServerFont.GetGlyphBitmap8( aGlyphId, pGcpHelper->maRawBitmap ); + break; + default: + OSL_FAIL( "SVP GCP::GetGlyphBmp(): illegal scanline format"); + // fall back to black&white mask + nBmpFormat = FORMAT_ONE_BIT_LSB_GREY; + bFound = false; + break; + } + + // return .notdef glyph if needed + if( !bFound && (aGlyphId != 0) ) + { + if( bNew ) + delete pGcpHelper; + return GetGlyphBmp( rServerFont, 0, nBmpFormat, rTargetPos ); + } + + // construct alpha mask from raw bitmap + if (pGcpHelper->maRawBitmap.mnScanlineSize && pGcpHelper->maRawBitmap.mnHeight) + { + const B2IVector aSize( + pGcpHelper->maRawBitmap.mnScanlineSize, + pGcpHelper->maRawBitmap.mnHeight ); + static PaletteMemorySharedVector aDummyPAL; + pGcpHelper->maBitmapDev = createBitmapDevice( aSize, true, nBmpFormat, aSize.getX(), pGcpHelper->maRawBitmap.mpBits, aDummyPAL ); + } + + rGlyphData.ExtDataRef().meInfo = nBmpFormat; + rGlyphData.ExtDataRef().mpData = pGcpHelper; + } + + SvpGcpHelper* pGcpHelper = static_cast<SvpGcpHelper*>( + rGlyphData.ExtDataRef().mpData); + assert(pGcpHelper != 0); + rTargetPos += B2IPoint( pGcpHelper->maRawBitmap.mnXOffset, pGcpHelper->maRawBitmap.mnYOffset ); + return pGcpHelper->maBitmapDev; +} + +void SvpGlyphPeer::RemovingFont( ServerFont& ) +{ + // nothing to do: no font resources held in SvpGlyphPeer +} + +void SvpGlyphPeer::RemovingGlyph( GlyphData& rGlyphData ) +{ + SvpGcpHelper* pGcpHelper = static_cast<SvpGcpHelper*>( + rGlyphData.ExtDataRef().mpData); + rGlyphData.ExtDataRef().meInfo = basebmp::FORMAT_NONE; + rGlyphData.ExtDataRef().mpData = 0; + delete pGcpHelper; +} + +SvpTextRender::SvpTextRender(SvpSalGraphics& rParent) + : m_rParent(rParent) + , m_aTextColor(COL_BLACK) + , m_eTextFmt(basebmp::FORMAT_EIGHT_BIT_GREY) +{ + for( int i = 0; i < MAX_FALLBACK; ++i ) + m_pServerFont[i] = NULL; +} + +sal_uInt16 SvpTextRender::SetFont( FontSelectPattern* pIFSD, int nFallbackLevel ) +{ + // release all no longer needed font resources + for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i ) + { + if( m_pServerFont[i] != NULL ) + { + // old server side font is no longer referenced + SvpGlyphCache::GetInstance().UncacheFont( *m_pServerFont[i] ); + m_pServerFont[i] = NULL; + } + } + + // return early if there is no new font + if( !pIFSD ) + return 0; + + // handle the request for a non-native X11-font => use the GlyphCache + ServerFont* pServerFont = SvpGlyphCache::GetInstance().CacheFont( *pIFSD ); + if( !pServerFont ) + return SAL_SETFONT_BADFONT; + + // check selected font + if( !pServerFont->TestFont() ) + { + SvpGlyphCache::GetInstance().UncacheFont( *pServerFont ); + return SAL_SETFONT_BADFONT; + } + + // update SalGraphics font settings + m_pServerFont[ nFallbackLevel ] = pServerFont; + return SAL_SETFONT_USEDRAWTEXTARRAY; +} + +void SvpTextRender::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLevel ) +{ + if( nFallbackLevel >= MAX_FALLBACK ) + return; + + if( m_pServerFont[nFallbackLevel] != NULL ) + { + long rDummyFactor; + m_pServerFont[nFallbackLevel]->FetchFontMetric( *pMetric, rDummyFactor ); + } +} + +const FontCharMapPtr SvpTextRender::GetFontCharMap() const +{ + if( !m_pServerFont[0] ) + return NULL; + + const FontCharMapPtr pFCMap = m_pServerFont[0]->GetFontCharMap(); + return pFCMap; +} + +bool SvpTextRender::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const +{ + if (!m_pServerFont[0]) + return false; + + return m_pServerFont[0]->GetFontCapabilities(rFontCapabilities); +} + +void SvpTextRender::GetDevFontList( PhysicalFontCollection* pFontCollection ) +{ + GlyphCache& rGC = SvpGlyphCache::GetInstance(); + + psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); + psp::FastPrintFontInfo aInfo; + ::std::list< psp::fontID > aList; + rMgr.getFontList( aList ); + ::std::list< psp::fontID >::iterator it; + for( it = aList.begin(); it != aList.end(); ++it ) + { + if( !rMgr.getFontFastInfo( *it, aInfo ) ) + continue; + + // normalize face number to the GlyphCache + int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID ); + + // inform GlyphCache about this font provided by the PsPrint subsystem + ImplDevFontAttributes aDFA = GenPspGraphics::Info2DevFontAttributes( aInfo ); + aDFA.mnQuality += 4096; + const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID ); + rGC.AddFontFile( rFileName, nFaceNum, aInfo.m_nID, aDFA ); + } + + // announce glyphcache fonts + rGC.AnnounceFonts( pFontCollection ); + + // register platform specific font substitutions if available + SalGenericInstance::RegisterFontSubstitutors( pFontCollection ); + + ImplGetSVData()->maGDIData.mbNativeFontConfig = true; +} + +void SvpTextRender::ClearDevFontCache() +{ + GlyphCache& rGC = SvpGlyphCache::GetInstance(); + rGC.ClearFontCache(); +} + +bool SvpTextRender::AddTempDevFont( PhysicalFontCollection*, + const OUString&, const OUString& ) +{ + return false; +} + +bool SvpTextRender::CreateFontSubset( + const OUString& rToFile, + const PhysicalFontFace* pFont, + const sal_GlyphId* pGlyphIds, + const sal_uInt8* pEncoding, + sal_Int32* pWidths, + int nGlyphCount, + FontSubsetInfo& rInfo + ) +{ + // in this context the pFont->GetFontId() is a valid PSP + // font since they are the only ones left after the PDF + // export has filtered its list of subsettable fonts (for + // which this method was created). The correct way would + // be to have the GlyphCache search for the PhysicalFontFace pFont + psp::fontID aFont = pFont->GetFontId(); + + psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); + bool bSuccess = rMgr.createFontSubset( rInfo, + aFont, + rToFile, + pGlyphIds, + pEncoding, + pWidths, + nGlyphCount ); + return bSuccess; +} + +const Ucs2SIntMap* SvpTextRender::GetFontEncodingVector( const PhysicalFontFace* pFont, const Ucs2OStrMap** pNonEncoded, std::set<sal_Unicode> const** ppPriority) +{ + // in this context the pFont->GetFontId() is a valid PSP + // font since they are the only ones left after the PDF + // export has filtered its list of subsettable fonts (for + // which this method was created). The correct way would + // be to have the GlyphCache search for the PhysicalFontFace pFont + psp::fontID aFont = pFont->GetFontId(); + return GenPspGraphics::DoGetFontEncodingVector(aFont, pNonEncoded, ppPriority); +} + +const void* SvpTextRender::GetEmbedFontData( + const PhysicalFontFace* pFont, + const sal_Ucs* pUnicodes, + sal_Int32* pWidths, + size_t nLen, + FontSubsetInfo& rInfo, + long* pDataLen + ) +{ + // in this context the pFont->GetFontId() is a valid PSP + // font since they are the only ones left after the PDF + // export has filtered its list of subsettable fonts (for + // which this method was created). The correct way would + // be to have the GlyphCache search for the PhysicalFontFace pFont + psp::fontID aFont = pFont->GetFontId(); + return GenPspGraphics::DoGetEmbedFontData( aFont, pUnicodes, pWidths, nLen, rInfo, pDataLen ); +} + +void SvpTextRender::FreeEmbedFontData( const void* pData, long nLen ) +{ + GenPspGraphics::DoFreeEmbedFontData( pData, nLen ); +} + +void SvpTextRender::GetGlyphWidths( const PhysicalFontFace* pFont, + bool bVertical, + Int32Vector& rWidths, + Ucs2UIntMap& rUnicodeEnc ) +{ + // in this context the pFont->GetFontId() is a valid PSP + // font since they are the only ones left after the PDF + // export has filtered its list of subsettable fonts (for + // which this method was created). The correct way would + // be to have the GlyphCache search for the PhysicalFontFace pFont + psp::fontID aFont = pFont->GetFontId(); + GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc ); +} + +bool SvpTextRender::GetGlyphBoundRect( sal_GlyphId aGlyphId, Rectangle& rRect ) +{ + const int nLevel = aGlyphId >> GF_FONTSHIFT; + if( nLevel >= MAX_FALLBACK ) + return false; + + ServerFont* pSF = m_pServerFont[ nLevel ]; + if( !pSF ) + return false; + + aGlyphId &= GF_IDXMASK; + const GlyphMetric& rGM = pSF->GetGlyphMetric( aGlyphId ); + rRect = Rectangle( rGM.GetOffset(), rGM.GetSize() ); + return true; +} + +bool SvpTextRender::GetGlyphOutline( sal_GlyphId aGlyphId, B2DPolyPolygon& rPolyPoly ) +{ + const int nLevel = aGlyphId >> GF_FONTSHIFT; + if( nLevel >= MAX_FALLBACK ) + return false; + + const ServerFont* pSF = m_pServerFont[ nLevel ]; + if( !pSF ) + return false; + + aGlyphId &= GF_IDXMASK; + if( pSF->GetGlyphOutline( aGlyphId, rPolyPoly ) ) + return true; + + return false; +} + +SalLayout* SvpTextRender::GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) +{ + GenericSalLayout* pLayout = NULL; + + if( m_pServerFont[ nFallbackLevel ] ) + pLayout = new ServerFontLayout( *m_pServerFont[ nFallbackLevel ] ); + + return pLayout; +} + +void SvpTextRender::DrawServerFontLayout( const ServerFontLayout& rSalLayout ) +{ + // iterate over all glyphs in the layout + Point aPos; + sal_GlyphId aGlyphId; + SvpGlyphPeer& rGlyphPeer = SvpGlyphCache::GetInstance().GetPeer(); + for( int nStart = 0; rSalLayout.GetNextGlyphs( 1, &aGlyphId, aPos, nStart ); ) + { + int nLevel = aGlyphId >> GF_FONTSHIFT; + DBG_ASSERT( nLevel < MAX_FALLBACK, "SvpGDI: invalid glyph fallback level" ); + ServerFont* pSF = m_pServerFont[ nLevel ]; + if( !pSF ) + continue; + + // get the glyph's alpha mask and adjust the drawing position + aGlyphId &= GF_IDXMASK; + B2IPoint aDstPoint( aPos.X(), aPos.Y() ); + BitmapDeviceSharedPtr aAlphaMask + = rGlyphPeer.GetGlyphBmp( *pSF, aGlyphId, m_eTextFmt, aDstPoint ); + if( !aAlphaMask ) // ignore empty glyphs + continue; + + // blend text color into target using the glyph's mask + m_rParent.BlendTextColor(m_aTextColor, aAlphaMask, aDstPoint); + } +} + +void SvpTextRender::SetTextColor( SalColor nSalColor ) +{ + m_aTextColor = basebmp::Color( nSalColor ); +} + +SystemFontData SvpTextRender::GetSysFontData( int nFallbacklevel ) const +{ + SystemFontData aSysFontData; + + if (nFallbacklevel >= MAX_FALLBACK) nFallbacklevel = MAX_FALLBACK - 1; + if (nFallbacklevel < 0 ) nFallbacklevel = 0; + + aSysFontData.nSize = sizeof( SystemFontData ); + aSysFontData.nFontId = 0; + aSysFontData.nFontFlags = 0; + aSysFontData.bFakeBold = false; + aSysFontData.bFakeItalic = false; + aSysFontData.bAntialias = true; + return aSysFontData; +} + +void SvpTextRender::setDevice( basebmp::BitmapDeviceSharedPtr& rDevice ) +{ + // determine matching bitmap format for masks + basebmp::Format nDeviceFmt = rDevice ? rDevice->getScanlineFormat() : basebmp::FORMAT_EIGHT_BIT_GREY; + switch( nDeviceFmt ) + { + case basebmp::FORMAT_EIGHT_BIT_GREY: + case basebmp::FORMAT_SIXTEEN_BIT_LSB_TC_MASK: + case basebmp::FORMAT_SIXTEEN_BIT_MSB_TC_MASK: + case basebmp::FORMAT_TWENTYFOUR_BIT_TC_MASK: + case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRX: + case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_BGRA: + case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_ARGB: + case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_ABGR: + case basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA: + m_eTextFmt = basebmp::FORMAT_EIGHT_BIT_GREY; + break; + default: + m_eTextFmt = basebmp::FORMAT_ONE_BIT_LSB_GREY; + break; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/devicetextrender.hxx b/vcl/inc/devicetextrender.hxx new file mode 100644 index 0000000..3880e88 --- /dev/null +++ b/vcl/inc/devicetextrender.hxx @@ -0,0 +1,24 @@ +/* -*- 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_DEVICETEXTRENDER_HXX +#define INCLUDED_VCL_INC_DEVICETEXTRENDER_HXX + +#include <basebmp/bitmapdevice.hxx> +#include "textrender.hxx" + +class VCL_DLLPUBLIC DeviceTextRenderImpl : public TextRenderImpl +{ +public: + virtual void setDevice(basebmp::BitmapDeviceSharedPtr& rDevice) = 0; +}; + +#endif + +/* vim:set tabstop=4 shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/headless/svpgdi.hxx b/vcl/inc/headless/svpgdi.hxx index d429b80..b811a55 100644 --- a/vcl/inc/headless/svpgdi.hxx +++ b/vcl/inc/headless/svpgdi.hxx @@ -27,6 +27,7 @@ #include "salgdi.hxx" #include "sallayout.hxx" +#include "devicetextrender.hxx" #ifdef IOS #define SvpSalGraphics AquaSalGraphics @@ -48,15 +49,14 @@ class SvpSalGraphics : public SalGraphics basebmp::DrawMode m_aDrawMode; - // These fields are used only when we use FreeType to draw into a - // headless backend, i.e. not on iOS. - basebmp::Color m_aTextColor; - ServerFont* m_pServerFont[ MAX_FALLBACK ]; - basebmp::Format m_eTextFmt; - protected: basegfx::B2IVector GetSize() { return m_aOrigDevice->getSize(); } +public: + void setDevice(basebmp::BitmapDeviceSharedPtr& rDevice); + void BlendTextColor(const basebmp::Color &rTextColor, const basebmp::BitmapDeviceSharedPtr &rAlphaMask, + const basegfx::B2IPoint &rDstPoint); + private: bool m_bClipSetup; struct ClipUndoHandle { @@ -68,11 +68,9 @@ private: bool isClippedSetup( const basegfx::B2IBox &aRange, ClipUndoHandle &rUndo ); void ensureClip(); -public: - void setDevice( basebmp::BitmapDeviceSharedPtr& rDevice ); - protected: - vcl::Region m_aClipRegion; + vcl::Region m_aClipRegion; + std::unique_ptr<DeviceTextRenderImpl> m_xTextRenderImpl; protected: virtual bool blendBitmap( const SalTwoRect&, const SalBitmap& rBitmap ) SAL_OVERRIDE; diff --git a/vcl/inc/headless/svptextrender.hxx b/vcl/inc/headless/svptextrender.hxx new file mode 100644 index 0000000..a4a9415 --- /dev/null +++ b/vcl/inc/headless/svptextrender.hxx @@ -0,0 +1,82 @@ +/* -*- 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 . + */ + +#ifndef INCLUDED_VCL_INC_HEADLESS_SVPTEXTRENDER_HXX +#define INCLUDED_VCL_INC_HEADLESS_SVPTEXTRENDER_HXX + +#include "devicetextrender.hxx" +#include <vcl/region.hxx> +#include <deque> + +class VCL_DLLPUBLIC SvpTextRender : public DeviceTextRenderImpl +{ +private: + SvpSalGraphics& m_rParent; + // These fields are used only when we use FreeType to draw into a + // headless backend, i.e. not on iOS. + basebmp::Color m_aTextColor; + basebmp::Format m_eTextFmt; + ServerFont* m_pServerFont[ MAX_FALLBACK ]; +public: + SvpTextRender(SvpSalGraphics& rParent); + virtual void setDevice(basebmp::BitmapDeviceSharedPtr& rDevice) SAL_OVERRIDE; + + virtual void SetTextColor( SalColor nSalColor ) SAL_OVERRIDE; + virtual sal_uInt16 SetFont( FontSelectPattern*, int nFallbackLevel ) SAL_OVERRIDE; + virtual void GetFontMetric( ImplFontMetricData*, int nFallbackLevel ) SAL_OVERRIDE; + virtual const FontCharMapPtr GetFontCharMap() const SAL_OVERRIDE; + virtual bool GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const SAL_OVERRIDE; + virtual void GetDevFontList( PhysicalFontCollection* ) SAL_OVERRIDE; + virtual void ClearDevFontCache() SAL_OVERRIDE; + virtual bool AddTempDevFont( PhysicalFontCollection*, const OUString& rFileURL, const OUString& rFontName ) SAL_OVERRIDE; + virtual bool CreateFontSubset( + const OUString& rToFile, + const PhysicalFontFace*, + const sal_GlyphId* pGlyphIDs, + const sal_uInt8* pEncoding, + sal_Int32* pWidths, + int nGlyphs, + FontSubsetInfo& rInfo) SAL_OVERRIDE; + + virtual const Ucs2SIntMap* GetFontEncodingVector( const PhysicalFontFace*, const Ucs2OStrMap** ppNonEncoded, std::set<sal_Unicode> const**) SAL_OVERRIDE; + virtual const void* GetEmbedFontData( + const PhysicalFontFace*, + const sal_Ucs* pUnicodes, + sal_Int32* pWidths, + size_t nLen, + FontSubsetInfo& rInfo, + long* pDataLen ) SAL_OVERRIDE; + + virtual void FreeEmbedFontData( const void* pData, long nDataLen ) SAL_OVERRIDE; + virtual void GetGlyphWidths( + const PhysicalFontFace*, + bool bVertical, + Int32Vector& rWidths, + Ucs2UIntMap& rUnicodeEnc ) SAL_OVERRIDE; + + virtual bool GetGlyphBoundRect( sal_GlyphId nIndex, Rectangle& ) SAL_OVERRIDE; + virtual bool GetGlyphOutline( sal_GlyphId nIndex, ::basegfx::B2DPolyPolygon& ) SAL_OVERRIDE; + virtual SalLayout* GetTextLayout( ImplLayoutArgs&, int nFallbackLevel ) SAL_OVERRIDE; + virtual void DrawServerFontLayout( const ServerFontLayout& ) SAL_OVERRIDE; + virtual SystemFontData GetSysFontData( int nFallbackLevel ) const SAL_OVERRIDE; +}; + +#endif // INCLUDED_VCL_INC_HEADLESS_SVPTEXTRENDER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits