diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /vcl/unx/generic/print/genpspgraphics.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vcl/unx/generic/print/genpspgraphics.cxx')
-rw-r--r-- | vcl/unx/generic/print/genpspgraphics.cxx | 1006 |
1 files changed, 1006 insertions, 0 deletions
diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx new file mode 100644 index 000000000..235f45eb8 --- /dev/null +++ b/vcl/unx/generic/print/genpspgraphics.cxx @@ -0,0 +1,1006 @@ +/* -*- 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/config.h> +#include <sal/log.hxx> + +#include <vector> + +#include <sal/types.h> + +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/stat.h> + +#include <i18nlangtag/mslangid.hxx> +#include <vcl/bitmapaccess.hxx> +#include <jobdata.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include <vcl/sysdata.hxx> +#include <vcl/fontcharmap.hxx> +#include <config_cairo_canvas.h> + +#include <fontsubset.hxx> +#include <unx/freetype_glyphcache.hxx> +#include <unx/geninst.h> +#include <unx/genpspgraphics.h> +#include <unx/printergfx.hxx> +#include <langboost.hxx> +#include <fontinstance.hxx> +#include <fontattributes.hxx> +#include <impfontmetricdata.hxx> +#include <PhysicalFontCollection.hxx> +#include <PhysicalFontFace.hxx> +#include <salbmp.hxx> +#include <sallayout.hxx> + +using namespace psp; + +// ----- Implementation of PrinterBmp by means of SalBitmap/BitmapBuffer --------------- + +namespace { + +class SalPrinterBmp : public psp::PrinterBmp +{ +private: + BitmapBuffer* mpBmpBuffer; + + FncGetPixel mpFncGetPixel; + Scanline mpScanAccess; + sal_PtrDiff mnScanOffset; + +public: + explicit SalPrinterBmp (BitmapBuffer* pBitmap); + + virtual sal_uInt32 GetPaletteColor (sal_uInt32 nIdx) const override; + virtual sal_uInt32 GetPaletteEntryCount () const override; + virtual sal_uInt32 GetPixelRGB (sal_uInt32 nRow, sal_uInt32 nColumn) const override; + virtual sal_uInt8 GetPixelGray (sal_uInt32 nRow, sal_uInt32 nColumn) const override; + virtual sal_uInt8 GetPixelIdx (sal_uInt32 nRow, sal_uInt32 nColumn) const override; + virtual sal_uInt32 GetDepth () const override; +}; + + bool Bitmap32IsPreMultipled() + { + auto pBackendCapabilities = ImplGetSVData()->mpDefInst->GetBackendCapabilities(); + return pBackendCapabilities->mbSupportsBitmap32; + } +} + +SalPrinterBmp::SalPrinterBmp (BitmapBuffer* pBuffer) + : mpBmpBuffer(pBuffer) +{ + assert(mpBmpBuffer && "SalPrinterBmp::SalPrinterBmp () can't acquire Bitmap"); + + // calibrate scanline buffer + if( mpBmpBuffer->mnFormat & ScanlineFormat::TopDown ) + { + mpScanAccess = mpBmpBuffer->mpBits; + mnScanOffset = mpBmpBuffer->mnScanlineSize; + } + else + { + mpScanAccess = mpBmpBuffer->mpBits + + (mpBmpBuffer->mnHeight - 1) * mpBmpBuffer->mnScanlineSize; + mnScanOffset = - mpBmpBuffer->mnScanlineSize; + } + + // request read access to the pixels + switch( RemoveScanline( mpBmpBuffer->mnFormat ) ) + { + case ScanlineFormat::N1BitMsbPal: + mpFncGetPixel = BitmapReadAccess::GetPixelForN1BitMsbPal; break; + case ScanlineFormat::N1BitLsbPal: + mpFncGetPixel = BitmapReadAccess::GetPixelForN1BitLsbPal; break; + case ScanlineFormat::N4BitMsnPal: + mpFncGetPixel = BitmapReadAccess::GetPixelForN4BitMsnPal; break; + case ScanlineFormat::N4BitLsnPal: + mpFncGetPixel = BitmapReadAccess::GetPixelForN4BitLsnPal; break; + case ScanlineFormat::N8BitPal: + mpFncGetPixel = BitmapReadAccess::GetPixelForN8BitPal; break; + case ScanlineFormat::N8BitTcMask: + mpFncGetPixel = BitmapReadAccess::GetPixelForN8BitTcMask; break; + case ScanlineFormat::N24BitTcBgr: + mpFncGetPixel = BitmapReadAccess::GetPixelForN24BitTcBgr; break; + case ScanlineFormat::N24BitTcRgb: + mpFncGetPixel = BitmapReadAccess::GetPixelForN24BitTcRgb; break; + case ScanlineFormat::N32BitTcAbgr: + if (Bitmap32IsPreMultipled()) + mpFncGetPixel = BitmapReadAccess::GetPixelForN32BitTcAbgr; + else + mpFncGetPixel = BitmapReadAccess::GetPixelForN32BitTcXbgr; + break; + case ScanlineFormat::N32BitTcArgb: + if (Bitmap32IsPreMultipled()) + mpFncGetPixel = BitmapReadAccess::GetPixelForN32BitTcArgb; + else + mpFncGetPixel = BitmapReadAccess::GetPixelForN32BitTcXrgb; + break; + case ScanlineFormat::N32BitTcBgra: + if (Bitmap32IsPreMultipled()) + mpFncGetPixel = BitmapReadAccess::GetPixelForN32BitTcBgra; + else + mpFncGetPixel = BitmapReadAccess::GetPixelForN32BitTcBgrx; + break; + case ScanlineFormat::N32BitTcRgba: + if (Bitmap32IsPreMultipled()) + mpFncGetPixel = BitmapReadAccess::GetPixelForN32BitTcRgba; + else + mpFncGetPixel = BitmapReadAccess::GetPixelForN32BitTcRgbx; + break; + case ScanlineFormat::N32BitTcMask: + mpFncGetPixel = BitmapReadAccess::GetPixelForN32BitTcMask; break; + default: + OSL_FAIL("Error: SalPrinterBmp::SalPrinterBmp() unknown bitmap format"); + mpFncGetPixel = nullptr; + break; + } +} + +sal_uInt32 +SalPrinterBmp::GetDepth () const +{ + sal_uInt32 nDepth; + + switch (mpBmpBuffer->mnBitCount) + { + case 1: + nDepth = 1; + break; + + case 4: + case 8: + nDepth = 8; + break; + + case 24: + case 32: + nDepth = 24; + break; + + default: + nDepth = 1; + assert(false && "Error: unsupported bitmap depth in SalPrinterBmp::GetDepth()"); + break; + } + + return nDepth; +} + +sal_uInt32 +SalPrinterBmp::GetPaletteEntryCount () const +{ + return mpBmpBuffer->maPalette.GetEntryCount (); +} + +sal_uInt32 +SalPrinterBmp::GetPaletteColor(sal_uInt32 nIdx) const +{ + BitmapColor aColor(mpBmpBuffer->maPalette[nIdx]); + + return ((aColor.GetBlue()) & 0x000000ff) + | ((aColor.GetGreen() << 8) & 0x0000ff00) + | ((aColor.GetRed() << 16) & 0x00ff0000); +} + +sal_uInt32 +SalPrinterBmp::GetPixelRGB (sal_uInt32 nRow, sal_uInt32 nColumn) const +{ + Scanline pScan = mpScanAccess + nRow * mnScanOffset; + BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask); + + if (!!mpBmpBuffer->maPalette) + GetPaletteColor(aColor.GetIndex()); + + return ((aColor.GetBlue()) & 0x000000ff) + | ((aColor.GetGreen() << 8) & 0x0000ff00) + | ((aColor.GetRed() << 16) & 0x00ff0000); +} + +sal_uInt8 +SalPrinterBmp::GetPixelGray (sal_uInt32 nRow, sal_uInt32 nColumn) const +{ + Scanline pScan = mpScanAccess + nRow * mnScanOffset; + BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask); + + if (!!mpBmpBuffer->maPalette) + aColor = mpBmpBuffer->maPalette[aColor.GetIndex()]; + + return ( aColor.GetBlue() * 28UL + + aColor.GetGreen() * 151UL + + aColor.GetRed() * 77UL ) >> 8; + +} + +sal_uInt8 +SalPrinterBmp::GetPixelIdx (sal_uInt32 nRow, sal_uInt32 nColumn) const +{ + Scanline pScan = mpScanAccess + nRow * mnScanOffset; + BitmapColor aColor = mpFncGetPixel (pScan, nColumn, mpBmpBuffer->maColorMask); + + if (!!mpBmpBuffer->maPalette) + return aColor.GetIndex(); + else + return 0; +} + +/******************************************************* + * GenPspGraphics * + *******************************************************/ +GenPspGraphics::GenPspGraphics() + : m_pJobData( nullptr ), + m_pPrinterGfx( nullptr ) +{ +} + +void GenPspGraphics::Init(psp::JobData* pJob, psp::PrinterGfx* pGfx) +{ + m_pJobData = pJob; + m_pPrinterGfx = pGfx; + SetLayout( SalLayoutFlags::NONE ); +} + +GenPspGraphics::~GenPspGraphics() +{ + ReleaseFonts(); +} + +void GenPspGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY ) +{ + if (m_pJobData != nullptr) + { + int x = m_pJobData->m_aContext.getRenderResolution(); + + rDPIX = x; + rDPIY = x; + } +} + +sal_uInt16 GenPspGraphics::GetBitCount() const +{ + return m_pPrinterGfx->GetBitCount(); +} + +long GenPspGraphics::GetGraphicsWidth() const +{ + return 0; +} + +void GenPspGraphics::ResetClipRegion() +{ + m_pPrinterGfx->ResetClipRegion(); +} + +bool GenPspGraphics::setClipRegion( const vcl::Region& i_rClip ) +{ + // TODO: support polygonal clipregions here + RectangleVector aRectangles; + i_rClip.GetRegionRectangles(aRectangles); + m_pPrinterGfx->BeginSetClipRegion(); + + for (auto const& rectangle : aRectangles) + { + const long nW(rectangle.GetWidth()); + + if(nW) + { + const long nH(rectangle.GetHeight()); + + if(nH) + { + m_pPrinterGfx->UnionClipRegion( + rectangle.Left(), + rectangle.Top(), + nW, + nH); + } + } + } + + m_pPrinterGfx->EndSetClipRegion(); + + //m_pPrinterGfx->BeginSetClipRegion( i_rClip.GetRectCount() ); + + //ImplRegionInfo aInfo; + //long nX, nY, nW, nH; + //bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH ); + //while( bRegionRect ) + //{ + // if ( nW && nH ) + // { + // m_pPrinterGfx->UnionClipRegion( nX, nY, nW, nH ); + // } + // bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH ); + //} + //m_pPrinterGfx->EndSetClipRegion(); + return true; +} + +void GenPspGraphics::SetLineColor() +{ + m_pPrinterGfx->SetLineColor (); +} + +void GenPspGraphics::SetLineColor( Color nColor ) +{ + psp::PrinterColor aColor (nColor.GetRed(), + nColor.GetGreen(), + nColor.GetBlue()); + m_pPrinterGfx->SetLineColor (aColor); +} + +void GenPspGraphics::SetFillColor() +{ + m_pPrinterGfx->SetFillColor (); +} + +void GenPspGraphics::SetFillColor( Color nColor ) +{ + psp::PrinterColor aColor (nColor.GetRed(), + nColor.GetGreen(), + nColor.GetBlue()); + m_pPrinterGfx->SetFillColor (aColor); +} + +void GenPspGraphics::SetROPLineColor( SalROPColor ) +{ + SAL_WARN( "vcl", "Error: PrinterGfx::SetROPLineColor() not implemented" ); +} + +void GenPspGraphics::SetROPFillColor( SalROPColor ) +{ + SAL_WARN( "vcl", "Error: PrinterGfx::SetROPFillColor() not implemented" ); +} + +void GenPspGraphics::SetXORMode( bool bSet, bool ) +{ + SAL_WARN_IF( bSet, "vcl", "Error: PrinterGfx::SetXORMode() not implemented" ); +} + +void GenPspGraphics::drawPixel( long nX, long nY ) +{ + m_pPrinterGfx->DrawPixel (Point(nX, nY)); +} + +void GenPspGraphics::drawPixel( long nX, long nY, Color nColor ) +{ + psp::PrinterColor aColor (nColor.GetRed(), + nColor.GetGreen(), + nColor.GetBlue()); + m_pPrinterGfx->DrawPixel (Point(nX, nY), aColor); +} + +void GenPspGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) +{ + m_pPrinterGfx->DrawLine (Point(nX1, nY1), Point(nX2, nY2)); +} + +void GenPspGraphics::drawRect( long nX, long nY, long nDX, long nDY ) +{ + m_pPrinterGfx->DrawRect (tools::Rectangle(Point(nX, nY), Size(nDX, nDY))); +} + +void GenPspGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint *pPtAry ) +{ + m_pPrinterGfx->DrawPolyLine (nPoints, reinterpret_cast<const Point *>(pPtAry)); +} + +void GenPspGraphics::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) +{ + // Point must be equal to SalPoint! see include/vcl/salgtype.hxx + m_pPrinterGfx->DrawPolygon (nPoints, reinterpret_cast<const Point *>(pPtAry)); +} + +void GenPspGraphics::drawPolyPolygon( sal_uInt32 nPoly, + const sal_uInt32 *pPoints, + PCONSTSALPOINT *pPtAry ) +{ + m_pPrinterGfx->DrawPolyPolygon (nPoly, pPoints, reinterpret_cast<const Point**>(pPtAry)); +} + +bool GenPspGraphics::drawPolyPolygon( + const basegfx::B2DHomMatrix& /*rObjectToDevice*/, + const basegfx::B2DPolyPolygon&, + double /*fTransparency*/) +{ + // TODO: implement and advertise OutDevSupportType::B2DDraw support + return false; +} + +bool GenPspGraphics::drawPolyLine( + const basegfx::B2DHomMatrix& /* rObjectToDevice */, + const basegfx::B2DPolygon&, + double /*fTransparency*/, + double /*fLineWidth*/, + const std::vector< double >* /*pStroke*/, // MM01 + basegfx::B2DLineJoin /*eJoin*/, + css::drawing::LineCap /*eLineCap*/, + double /*fMiterMinimumAngle*/, + bool /* bPixelSnapHairline */) +{ + // TODO: a PS printer can draw B2DPolyLines almost directly + return false; +} + +bool GenPspGraphics::drawPolyLineBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const PolyFlags* pFlgAry ) +{ + m_pPrinterGfx->DrawPolyLineBezier (nPoints, reinterpret_cast<Point const *>(pPtAry), pFlgAry); + return true; +} + +bool GenPspGraphics::drawPolygonBezier( sal_uInt32 nPoints, const SalPoint* pPtAry, const PolyFlags* pFlgAry ) +{ + m_pPrinterGfx->DrawPolygonBezier (nPoints, reinterpret_cast<Point const *>(pPtAry), pFlgAry); + return true; +} + +bool GenPspGraphics::drawPolyPolygonBezier( sal_uInt32 nPoly, + const sal_uInt32* pPoints, + const SalPoint* const* pPtAry, + const PolyFlags* const* pFlgAry ) +{ + // Point must be equal to SalPoint! see include/vcl/salgtype.hxx + m_pPrinterGfx->DrawPolyPolygonBezier (nPoly, pPoints, reinterpret_cast<Point const * const *>(pPtAry), pFlgAry); + return true; +} + +void GenPspGraphics::invert( sal_uInt32, + const SalPoint*, + SalInvert ) +{ + SAL_WARN( "vcl", "Error: PrinterGfx::Invert() not implemented" ); +} + +bool GenPspGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, sal_uInt32 nSize ) +{ + return m_pPrinterGfx->DrawEPS( tools::Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ), pPtr, nSize ); +} + +void GenPspGraphics::copyBits( const SalTwoRect&, + SalGraphics* ) +{ + OSL_FAIL( "Error: PrinterGfx::CopyBits() not implemented" ); +} + +void GenPspGraphics::copyArea ( long,long,long,long,long,long,bool ) +{ + OSL_FAIL( "Error: PrinterGfx::CopyArea() not implemented" ); +} + +void GenPspGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) +{ + tools::Rectangle aSrc (Point(rPosAry.mnSrcX, rPosAry.mnSrcY), + Size(rPosAry.mnSrcWidth, rPosAry.mnSrcHeight)); + tools::Rectangle aDst (Point(rPosAry.mnDestX, rPosAry.mnDestY), + Size(rPosAry.mnDestWidth, rPosAry.mnDestHeight)); + + BitmapBuffer* pBuffer= const_cast<SalBitmap&>(rSalBitmap).AcquireBuffer(BitmapAccessMode::Read); + + SalPrinterBmp aBmp (pBuffer); + m_pPrinterGfx->DrawBitmap (aDst, aSrc, aBmp); + + const_cast<SalBitmap&>(rSalBitmap).ReleaseBuffer (pBuffer, BitmapAccessMode::Read); +} + +void GenPspGraphics::drawBitmap( const SalTwoRect&, + const SalBitmap&, + const SalBitmap& ) +{ + OSL_FAIL("Error: no PrinterGfx::DrawBitmap() for transparent bitmap"); +} + +void GenPspGraphics::drawMask( const SalTwoRect&, + const SalBitmap &, + Color ) +{ + OSL_FAIL("Error: PrinterGfx::DrawMask() not implemented"); +} + +std::shared_ptr<SalBitmap> GenPspGraphics::getBitmap( long, long, long, long ) +{ + SAL_INFO("vcl", "Warning: PrinterGfx::GetBitmap() not implemented"); + return nullptr; +} + +Color GenPspGraphics::getPixel( long, long ) +{ + OSL_FAIL("Warning: PrinterGfx::GetPixel() not implemented"); + return 0; +} + +void GenPspGraphics::invert(long,long,long,long,SalInvert) +{ + OSL_FAIL("Warning: PrinterGfx::Invert() not implemented"); +} + +namespace { + +class ImplPspFontData : public FreetypeFontFace +{ +private: + sal_IntPtr mnFontId; + +public: + explicit ImplPspFontData( const psp::FastPrintFontInfo& ); + virtual sal_IntPtr GetFontId() const override { return mnFontId; } +}; + +} + +ImplPspFontData::ImplPspFontData(const psp::FastPrintFontInfo& rInfo) +: FreetypeFontFace(nullptr, GenPspGraphics::Info2FontAttributes(rInfo)), + mnFontId( rInfo.m_nID ) +{} + +namespace { + +class PspSalLayout : public GenericSalLayout +{ +public: + PspSalLayout(psp::PrinterGfx&, LogicalFontInstance &rFontInstance); + + void InitFont() const final override; + +private: + ::psp::PrinterGfx& mrPrinterGfx; + sal_IntPtr mnFontID; + int mnFontHeight; + int mnFontWidth; + bool mbVertical; + bool mbArtItalic; + bool mbArtBold; +}; + +} + +PspSalLayout::PspSalLayout(::psp::PrinterGfx& rGfx, LogicalFontInstance &rFontInstance) +: GenericSalLayout(rFontInstance) +, mrPrinterGfx(rGfx) +{ + mnFontID = mrPrinterGfx.GetFontID(); + mnFontHeight = mrPrinterGfx.GetFontHeight(); + mnFontWidth = mrPrinterGfx.GetFontWidth(); + mbVertical = mrPrinterGfx.GetFontVertical(); + mbArtItalic = mrPrinterGfx.GetArtificialItalic(); + mbArtBold = mrPrinterGfx.GetArtificialBold(); +} + +void PspSalLayout::InitFont() const +{ + GenericSalLayout::InitFont(); + mrPrinterGfx.SetFont(mnFontID, mnFontHeight, mnFontWidth, + mnOrientation, mbVertical, mbArtItalic, mbArtBold); +} + +void GenPspGraphics::DrawTextLayout(const GenericSalLayout& rLayout) +{ + const GlyphItem* pGlyph; + Point aPos; + int nStart = 0; + while (rLayout.GetNextGlyph(&pGlyph, aPos, nStart)) + m_pPrinterGfx->DrawGlyph(aPos, *pGlyph); +} + +FontCharMapRef GenPspGraphics::GetFontCharMap() const +{ + if (!m_pFreetypeFont[0]) + return nullptr; + + return m_pFreetypeFont[0]->GetFreetypeFont().GetFontCharMap(); +} + +bool GenPspGraphics::GetFontCapabilities(vcl::FontCapabilities &rFontCapabilities) const +{ + if (!m_pFreetypeFont[0]) + return false; + + return m_pFreetypeFont[0]->GetFreetypeFont().GetFontCapabilities(rFontCapabilities); +} + +void GenPspGraphics::SetFont(LogicalFontInstance *pFontInstance, int nFallbackLevel) +{ + // release all fonts that are to be overridden + for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i ) + { + // old server side font is no longer referenced + m_pFreetypeFont[i] = nullptr; + } + + // return early if there is no new font + if (!pFontInstance) + return; + + sal_IntPtr nID = pFontInstance->GetFontFace()->GetFontId(); + + const FontSelectPattern& rEntry = pFontInstance->GetFontSelectPattern(); + + // determine which font attributes need to be emulated + bool bArtItalic = false; + bool bArtBold = false; + if( rEntry.GetItalic() == ITALIC_OBLIQUE || rEntry.GetItalic() == ITALIC_NORMAL ) + { + FontItalic eItalic = m_pPrinterGfx->GetFontMgr().getFontItalic( nID ); + if( eItalic != ITALIC_NORMAL && eItalic != ITALIC_OBLIQUE ) + bArtItalic = true; + } + int nWeight = static_cast<int>(rEntry.GetWeight()); + int nRealWeight = static_cast<int>(m_pPrinterGfx->GetFontMgr().getFontWeight( nID )); + if( nRealWeight <= int(WEIGHT_MEDIUM) && nWeight > int(WEIGHT_MEDIUM) ) + { + bArtBold = true; + } + + // also set the serverside font for layouting + // requesting a font provided by builtin rasterizer + FreetypeFontInstance* pFreetypeFont = static_cast<FreetypeFontInstance*>(pFontInstance); + m_pFreetypeFont[ nFallbackLevel ] = pFreetypeFont; + + // ignore fonts with e.g. corrupted font files + if (!m_pFreetypeFont[nFallbackLevel]->GetFreetypeFont().TestFont()) + m_pFreetypeFont[nFallbackLevel] = nullptr; + + // set the printer font + m_pPrinterGfx->SetFont( nID, + rEntry.mnHeight, + rEntry.mnWidth, + rEntry.mnOrientation, + rEntry.mbVertical, + bArtItalic, + bArtBold + ); +} + +void GenPspGraphics::SetTextColor( Color nColor ) +{ + psp::PrinterColor aColor (nColor.GetRed(), + nColor.GetGreen(), + nColor.GetBlue()); + m_pPrinterGfx->SetTextColor (aColor); +} + +bool GenPspGraphics::AddTempDevFont( PhysicalFontCollection*, const OUString&,const OUString& ) +{ + return false; +} + +bool GenPspGraphics::AddTempDevFontHelper( PhysicalFontCollection* pFontCollection, + const OUString& rFileURL, + const OUString& rFontName) +{ + // inform PSP font manager + psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); + std::vector<psp::fontID> aFontIds = rMgr.addFontFile( rFileURL ); + if( aFontIds.empty() ) + return false; + + FreetypeManager& rFreetypeManager = FreetypeManager::get(); + for (auto const& elem : aFontIds) + { + // prepare font data + psp::FastPrintFontInfo aInfo; + rMgr.getFontFastInfo( elem, aInfo ); + aInfo.m_aFamilyName = rFontName; + + // inform glyph cache of new font + FontAttributes aDFA = GenPspGraphics::Info2FontAttributes( aInfo ); + aDFA.IncreaseQualityBy( 5800 ); + + int nFaceNum = rMgr.getFontFaceNumber( aInfo.m_nID ); + int nVariantNum = rMgr.getFontFaceVariation( aInfo.m_nID ); + + const OString& rFileName = rMgr.getFontFileSysPath( aInfo.m_nID ); + rFreetypeManager.AddFontFile(rFileName, nFaceNum, nVariantNum, aInfo.m_nID, aDFA); + } + + // announce new font to device's font list + rFreetypeManager.AnnounceFonts(pFontCollection); + return true; +} + +void GenPspGraphics::GetDevFontList( PhysicalFontCollection *pFontCollection ) +{ + ::std::vector< psp::fontID > aList; + psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); + rMgr.getFontList( aList ); + + psp::FastPrintFontInfo aInfo; + for (auto const& elem : aList) + if (rMgr.getFontFastInfo (elem, aInfo)) + AnnounceFonts( pFontCollection, aInfo ); + + // register platform specific font substitutions if available + SalGenericInstance::RegisterFontSubstitutors( pFontCollection ); +} + +void GenPspGraphics::ClearDevFontCache() +{ + FreetypeManager::get().ClearFontCache(); +} + +void GenPspGraphics::GetFontMetric(ImplFontMetricDataRef& rxFontMetric, int nFallbackLevel) +{ + if (nFallbackLevel >= MAX_FALLBACK) + return; + + if (m_pFreetypeFont[nFallbackLevel]) + m_pFreetypeFont[nFallbackLevel]->GetFreetypeFont().GetFontMetric(rxFontMetric); +} + +std::unique_ptr<GenericSalLayout> GenPspGraphics::GetTextLayout(int nFallbackLevel) +{ + assert(m_pFreetypeFont[nFallbackLevel]); + if (!m_pFreetypeFont[nFallbackLevel]) + return nullptr; + return std::make_unique<PspSalLayout>(*m_pPrinterGfx, *m_pFreetypeFont[nFallbackLevel]); +} + +bool GenPspGraphics::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 FreetypeManager 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; +} + +void GenPspGraphics::GetGlyphWidths( const PhysicalFontFace* pFont, + bool bVertical, + std::vector< sal_Int32 >& 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 FreetypeManager search for the PhysicalFontFace pFont + psp::fontID aFont = pFont->GetFontId(); + GenPspGraphics::DoGetGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc ); +} + +void GenPspGraphics::DoGetGlyphWidths( psp::fontID aFont, + bool bVertical, + std::vector< sal_Int32 >& rWidths, + Ucs2UIntMap& rUnicodeEnc ) +{ + psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); + rMgr.getGlyphWidths( aFont, bVertical, rWidths, rUnicodeEnc ); +} + +FontAttributes GenPspGraphics::Info2FontAttributes( const psp::FastPrintFontInfo& rInfo ) +{ + FontAttributes aDFA; + aDFA.SetFamilyName( rInfo.m_aFamilyName ); + aDFA.SetStyleName( rInfo.m_aStyleName ); + aDFA.SetFamilyType( rInfo.m_eFamilyStyle ); + aDFA.SetWeight( rInfo.m_eWeight ); + aDFA.SetItalic( rInfo.m_eItalic ); + aDFA.SetWidthType( rInfo.m_eWidth ); + aDFA.SetPitch( rInfo.m_ePitch ); + aDFA.SetSymbolFlag( rInfo.m_aEncoding == RTL_TEXTENCODING_SYMBOL ); + aDFA.SetQuality(512); + + // add font family name aliases + for (auto const& alias : rInfo.m_aAliases) + aDFA.AddMapName(alias); + +#if OSL_DEBUG_LEVEL > 2 + if( aDFA.GetMapNames().getLength() > 0 ) + { + SAL_INFO( "vcl.fonts", "using alias names " << aDFA.GetMapNames() << " for font family " << aDFA.GetFamilyName() ); + } +#endif + + return aDFA; +} + +namespace vcl +{ + const char* getLangBoost() + { + const char* pLangBoost; + const LanguageType eLang = Application::GetSettings().GetUILanguageTag().getLanguageType(); + if (eLang == LANGUAGE_JAPANESE) + pLangBoost = "jan"; + else if (MsLangId::isKorean(eLang)) + pLangBoost = "kor"; + else if (MsLangId::isSimplifiedChinese(eLang)) + pLangBoost = "zhs"; + else if (MsLangId::isTraditionalChinese(eLang)) + pLangBoost = "zht"; + else + pLangBoost = nullptr; + return pLangBoost; + } +} + +void GenPspGraphics::AnnounceFonts( PhysicalFontCollection* pFontCollection, const psp::FastPrintFontInfo& aInfo ) +{ + int nQuality = 0; + + psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); + OString aFileName( rMgr.getFontFileSysPath( aInfo.m_nID ) ); + int nPos = aFileName.lastIndexOf( '_' ); + if( nPos == -1 || aFileName[nPos+1] == '.' ) + nQuality += 5; + else + { + static const char* pLangBoost = nullptr; + static bool bOnce = true; + if( bOnce ) + { + bOnce = false; + pLangBoost = vcl::getLangBoost(); + } + + if( pLangBoost ) + if( aFileName.copy( nPos+1, 3 ).equalsIgnoreAsciiCase( pLangBoost ) ) + nQuality += 10; + } + + rtl::Reference<ImplPspFontData> pFD(new ImplPspFontData( aInfo )); + pFD->IncreaseQualityBy( nQuality ); + pFontCollection->Add( pFD.get() ); +} + +bool GenPspGraphics::blendBitmap( const SalTwoRect&, const SalBitmap& ) +{ + return false; +} + +bool GenPspGraphics::blendAlphaBitmap( const SalTwoRect&, const SalBitmap&, const SalBitmap&, const SalBitmap& ) +{ + return false; +} + +bool GenPspGraphics::drawAlphaBitmap( const SalTwoRect&, + const SalBitmap&, + const SalBitmap& ) +{ + return false; +} + +bool GenPspGraphics::drawTransformedBitmap( + const basegfx::B2DPoint&, + const basegfx::B2DPoint&, + const basegfx::B2DPoint&, + const SalBitmap&, + const SalBitmap*) +{ + // here direct support for transformed bitmaps can be implemented + return false; +} + +bool GenPspGraphics::drawAlphaRect( long, long, long, long, sal_uInt8 ) +{ + return false; +} + +SystemGraphicsData GenPspGraphics::GetGraphicsData() const +{ + return SystemGraphicsData(); +} + +#if ENABLE_CAIRO_CANVAS + +bool GenPspGraphics::SupportsCairo() const +{ + return false; +} + +cairo::SurfaceSharedPtr GenPspGraphics::CreateSurface(const cairo::CairoSurfaceSharedPtr& /*rSurface*/) const +{ + return cairo::SurfaceSharedPtr(); +} + +cairo::SurfaceSharedPtr GenPspGraphics::CreateSurface(const OutputDevice& /*rRefDevice*/, int /*x*/, int /*y*/, int /*width*/, int /*height*/) const +{ + return cairo::SurfaceSharedPtr(); +} + +cairo::SurfaceSharedPtr GenPspGraphics::CreateBitmapSurface(const OutputDevice& /*rRefDevice*/, const BitmapSystemData& /*rData*/, const Size& /*rSize*/) const +{ + return cairo::SurfaceSharedPtr(); +} + +css::uno::Any GenPspGraphics::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& /*rSurface*/, const basegfx::B2ISize& /*rSize*/) const +{ + return css::uno::Any(); +} + +SystemFontData GenPspGraphics::GetSysFontData( int /* nFallbacklevel */ ) const +{ + return SystemFontData(); +} + +#endif // ENABLE_CAIRO_CANVAS + +bool GenPspGraphics::supportsOperation( OutDevSupportType ) const +{ + return false; +} + +void GenPspGraphics::DoFreeEmbedFontData( const void* pData, long nLen ) +{ + if( pData ) + munmap( const_cast<void *>(pData), nLen ); +} + +const void* GenPspGraphics::DoGetEmbedFontData(psp::fontID aFont, long* pDataLen) +{ + + psp::PrintFontManager& rMgr = psp::PrintFontManager::get(); + + OString aSysPath = rMgr.getFontFileSysPath( aFont ); + + int fd = open( aSysPath.getStr(), O_RDONLY ); + if( fd < 0 ) + return nullptr; + struct stat aStat; + if( fstat( fd, &aStat ) ) + { + close( fd ); + return nullptr; + } + void* pFile = mmap( nullptr, aStat.st_size, PROT_READ, MAP_SHARED, fd, 0 ); + close( fd ); + if( pFile == MAP_FAILED ) + return nullptr; + *pDataLen = aStat.st_size; + + return pFile; +} + +void GenPspGraphics::FreeEmbedFontData( const void* pData, long nLen ) +{ + DoFreeEmbedFontData( pData, nLen ); +} + +const void* GenPspGraphics::GetEmbedFontData(const PhysicalFontFace* pFont, 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 FreetypeManager search for the PhysicalFontFace pFont + psp::fontID aFont = pFont->GetFontId(); + return DoGetEmbedFontData(aFont, pDataLen); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |