diff options
-rw-r--r-- | vcl/inc/font/PhysicalFontFace.hxx | 13 | ||||
-rw-r--r-- | vcl/inc/pdf/pdfwriter_impl.hxx | 15 | ||||
-rw-r--r-- | vcl/source/font/PhysicalFontFace.cxx | 37 | ||||
-rw-r--r-- | vcl/source/fontsubset/sft.cxx | 6 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 206 |
5 files changed, 214 insertions, 63 deletions
diff --git a/vcl/inc/font/PhysicalFontFace.hxx b/vcl/inc/font/PhysicalFontFace.hxx index 5c4ab2eea046..3297feff87dc 100644 --- a/vcl/inc/font/PhysicalFontFace.hxx +++ b/vcl/inc/font/PhysicalFontFace.hxx @@ -67,6 +67,11 @@ public: { } + RawFontData(const RawFontData& rOther) + : mpBlob(hb_blob_reference(rOther.mpBlob)) + { + } + ~RawFontData() { hb_blob_destroy(mpBlob); } RawFontData& operator=(const RawFontData& rOther) @@ -166,10 +171,15 @@ public: bool CreateFontSubset(std::vector<sal_uInt8>&, const sal_GlyphId*, const sal_uInt8*, const int, FontSubsetInfo&) const; + bool IsColorFont() const { return HasColorLayers() || HasColorBitmaps(); } + bool HasColorLayers() const; const ColorPalette& GetColorPalette(size_t) const; std::vector<ColorLayer> GetGlyphColorLayers(sal_GlyphId) const; + bool HasColorBitmaps() const; + RawFontData GetGlyphColorBitmap(sal_GlyphId, tools::Rectangle&) const; + uint32_t UnitsPerEm() const { return hb_face_get_upem(GetHbFace()); } OUString GetName(NameID, const LanguageTag&) const; @@ -184,12 +194,15 @@ public: protected: mutable hb_face_t* mpHbFace; + mutable hb_font_t* mpHbUnscaledFont; mutable FontCharMapRef mxCharMap; mutable vcl::FontCapabilities maFontCapabilities; mutable bool mbFontCapabilitiesRead; mutable std::vector<ColorPalette> maColorPalettes; explicit PhysicalFontFace(const FontAttributes&); + + hb_font_t* GetHbUnscaledFont() const; }; } diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx index 942d57a26fbb..afb80c2aa403 100644 --- a/vcl/inc/pdf/pdfwriter_impl.hxx +++ b/vcl/inc/pdf/pdfwriter_impl.hxx @@ -297,6 +297,8 @@ class GlyphEmit sal_uInt8 m_nSubsetGlyphID; sal_Int32 m_nGlyphWidth; std::vector<ColorLayer> m_aColorLayers; + font::RawFontData m_aColorBitmap; + tools::Rectangle m_aRect; public: GlyphEmit() : m_nSubsetGlyphID(0), m_nGlyphWidth(0) @@ -312,6 +314,17 @@ public: void addColorLayer(ColorLayer aLayer) { m_aColorLayers.push_back(aLayer); } const std::vector<ColorLayer>& getColorLayers() const { return m_aColorLayers; } + void setColorBitmap(font::RawFontData aData, tools::Rectangle aRect) + { + m_aColorBitmap = aData; + m_aRect = aRect; + } + const font::RawFontData& getColorBitmap(tools::Rectangle& rRect) const + { + rRect = m_aRect; + return m_aColorBitmap; + } + void addCode( sal_Ucs i_cCode ) { m_CodeUnits.push_back(i_cCode); @@ -866,6 +879,7 @@ i12626 /* tries to find the bitmap by its id and returns its emit data if exists, else creates a new emit data block */ + const BitmapEmit& createBitmapEmit( const BitmapEx& rBitmapEx, const Graphic& rGraphic, std::list<BitmapEmit>& rBitmaps, ResourceDict& rResourceDict, std::list<StreamRedirect>& rOutputStreams ); const BitmapEmit& createBitmapEmit( const BitmapEx& rBitmapEx, const Graphic& rGraphic ); /* writes the Do operation inside the content stream */ @@ -906,6 +920,7 @@ i12626 return m_nFontDictObject; } /* push resource into current (redirected) resource dict */ + static void pushResource( ResourceKind eKind, const OString& rResource, sal_Int32 nObject, ResourceDict& rResourceDict, std::list<StreamRedirect>& rOutputStreams ); void pushResource( ResourceKind eKind, const OString& rResource, sal_Int32 nObject ); void appendBuildinFontsToDict( OStringBuffer& rDict ) const; diff --git a/vcl/source/font/PhysicalFontFace.cxx b/vcl/source/font/PhysicalFontFace.cxx index 411f2d59ef5d..337995964389 100644 --- a/vcl/source/font/PhysicalFontFace.cxx +++ b/vcl/source/font/PhysicalFontFace.cxx @@ -43,6 +43,7 @@ namespace vcl::font PhysicalFontFace::PhysicalFontFace(const FontAttributes& rDFA) : FontAttributes(rDFA) , mpHbFace(nullptr) + , mpHbUnscaledFont(nullptr) , mbFontCapabilitiesRead(false) { // StarSymbol is a unicode font, but it still deserves the symbol flag @@ -55,6 +56,8 @@ PhysicalFontFace::~PhysicalFontFace() { if (mpHbFace) hb_face_destroy(mpHbFace); + if (mpHbUnscaledFont) + hb_font_destroy(mpHbUnscaledFont); } sal_Int32 PhysicalFontFace::CompareIgnoreSize(const PhysicalFontFace& rOther) const @@ -235,6 +238,13 @@ hb_face_t* PhysicalFontFace::GetHbFace() const return mpHbFace; } +hb_font_t* PhysicalFontFace::GetHbUnscaledFont() const +{ + if (mpHbUnscaledFont == nullptr) + mpHbUnscaledFont = hb_font_create(GetHbFace()); + return mpHbUnscaledFont; +} + FontCharMapRef PhysicalFontFace::GetFontCharMap() const { if (mxCharMap.is()) @@ -347,6 +357,9 @@ const ColorPalette& PhysicalFontFace::GetColorPalette(size_t nIndex) const std::vector<ColorLayer> PhysicalFontFace::GetGlyphColorLayers(sal_GlyphId nGlyphIndex) const { + if (!HasColorLayers()) + return {}; + const auto pHbFace = GetHbFace(); auto nLayers = hb_ot_color_glyph_get_layers(pHbFace, nGlyphIndex, 0, nullptr, nullptr); @@ -362,6 +375,30 @@ std::vector<ColorLayer> PhysicalFontFace::GetGlyphColorLayers(sal_GlyphId nGlyph return aLayers; } +bool PhysicalFontFace::HasColorBitmaps() const { return hb_ot_color_has_png(GetHbFace()); } + +RawFontData PhysicalFontFace::GetGlyphColorBitmap(sal_GlyphId nGlyphIndex, + tools::Rectangle& rRect) const +{ + if (!HasColorBitmaps()) + return {}; + + hb_font_t* pHbFont = GetHbUnscaledFont(); + auto aData = RawFontData(hb_ot_color_glyph_reference_png(pHbFont, nGlyphIndex)); + if (!aData.empty()) + { + hb_glyph_extents_t aExtents; + if (hb_font_get_glyph_extents(pHbFont, nGlyphIndex, &aExtents)) + { + auto aPoint = Point(aExtents.x_bearing, aExtents.y_bearing + aExtents.height); + auto aSize = Size(aExtents.width, -aExtents.height); + rRect = tools::Rectangle(aPoint, aSize); + } + } + + return aData; +} + OUString PhysicalFontFace::GetName(NameID aNameID, const LanguageTag& rLanguageTag) const { auto pHbFace = GetHbFace(); diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx index 4c52eaa45df2..f0141898eaa1 100644 --- a/vcl/source/fontsubset/sft.cxx +++ b/vcl/source/fontsubset/sft.cxx @@ -1284,7 +1284,7 @@ SFErrCodes AbstractTrueTypeFont::initialize() sal_uInt32 AbstractTrueTypeFont::glyphOffset(sal_uInt32 glyphID) const { - if (m_aGlyphOffsets.empty()) // the O_CFF and Bitmap cases + if (m_aGlyphOffsets.empty()) // the O_CFF case return 0; return m_aGlyphOffsets[glyphID]; } @@ -1329,9 +1329,7 @@ SFErrCodes AbstractTrueTypeFont::indexGlyphData() /* TODO: implement to get subsetting */ } else { - // Bitmap font, accept for now. - m_aGlyphOffsets.clear(); - /* TODO: implement to get subsetting */ + return SFErrCodes::TtFormat; } table = this->table(O_hhea, table_size); diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 5e6955a0a45b..83887db1a4dc 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -54,6 +54,7 @@ #include <sal/log.hxx> #include <svl/urihelper.hxx> #include <tools/fract.hxx> +#include <tools/stream.hxx> #include <tools/helpers.hxx> #include <tools/stream.hxx> #include <tools/urlobj.hxx> @@ -72,6 +73,7 @@ #include <vcl/svapp.hxx> #include <vcl/virdev.hxx> #include <vcl/filter/pdfdocument.hxx> +#include <vcl/filter/PngImageReader.hxx> #include <comphelper/hash.hxx> #include <svdata.hxx> @@ -2505,7 +2507,7 @@ bool PDFWriterImpl::emitType3Font(const vcl::font::PhysicalFontFace* pFace, } aLine.append(">>\n"); - aLine.append("/Encoding<</Differences[1"); + aLine.append("/Encoding<</Type/Encoding/Differences[1"); for (auto i = 1u; i < nGlyphs; i++) aLine.append(" /g" + OString::number(i)); aLine.append("]>>\n"); @@ -2530,9 +2532,9 @@ bool PDFWriterImpl::emitType3Font(const vcl::font::PhysicalFontFace* pFace, aLine.append(" 0 R\n"); } - auto nFontResources = createObject(); + auto nResources = createObject(); aLine.append("/Resources "); - aLine.append(nFontResources); + aLine.append(nResources); aLine.append(" 0 R\n"); if (nToUnicodeStream) @@ -2549,7 +2551,11 @@ bool PDFWriterImpl::emitType3Font(const vcl::font::PhysicalFontFace* pFace, return false; std::set<sal_Int32> aUsedFonts; - std::set<sal_uInt8> aUsedAlpha; + std::list<BitmapEmit> aUsedBitmaps; + std::map<sal_uInt8, sal_Int32> aUsedAlpha; + ResourceDict aResourceDict; + std::list<StreamRedirect> aOutputStreams; + for (auto i = 1u; i < nGlyphs; i++) { auto nStream = pGlyphStreams[i]; @@ -2565,8 +2571,8 @@ bool PDFWriterImpl::emitType3Font(const vcl::font::PhysicalFontFace* pFace, { aUsedFonts.insert(rLayer.m_nFontID); - // 0xFFFF is a special value means foreground color. aContents.append("q "); + // 0xFFFF is a special value means foreground color. if (rLayer.m_nColorIndex != 0xFFFF) { auto aColor(aPalette[rLayer.m_nColorIndex]); @@ -2575,10 +2581,20 @@ bool PDFWriterImpl::emitType3Font(const vcl::font::PhysicalFontFace* pFace, if (aColor.GetAlpha() != 0xFF && m_aContext.Version >= PDFWriter::PDFVersion::PDF_1_4) { - aContents.append("/GS"); - appendHex(aColor.GetAlpha(), aContents); - aContents.append(" gs "); - aUsedAlpha.insert(aColor.GetAlpha()); + auto nAlpha = aColor.GetAlpha(); + OStringBuffer aName(16); + aName.append("GS"); + appendHex(nAlpha, aName); + + aContents.append("/" + aName + " gs "); + + if (aUsedAlpha.find(nAlpha) == aUsedAlpha.end()) + { + auto nObject = createObject(); + aUsedAlpha[nAlpha] = nObject; + pushResource(ResourceKind::ExtGState, aName.makeStringAndClear(), + nObject, aResourceDict, aOutputStreams); + } } } aContents.append("BT "); @@ -2591,6 +2607,31 @@ bool PDFWriterImpl::emitType3Font(const vcl::font::PhysicalFontFace* pFace, aContents.append("Q\n"); } + tools::Rectangle aRect; + const auto& rBitmapData = rGlyph.getColorBitmap(aRect); + if (!rBitmapData.empty()) + { + SvMemoryStream aStream(const_cast<uint8_t*>(rBitmapData.data()), rBitmapData.size(), + StreamMode::READ); + vcl::PngImageReader aReader(aStream); + auto aBitmapEmit = createBitmapEmit(std::move(aReader.read()), Graphic(), + aUsedBitmaps, aResourceDict, aOutputStreams); + + auto nObject = aBitmapEmit.m_aReferenceXObject.getObject(); + aContents.append("q "); + aContents.append(aRect.GetWidth()); + aContents.append(" 0 0 "); + aContents.append(aRect.GetHeight()); + aContents.append(" "); + aContents.append(aRect.getX()); + aContents.append(" "); + aContents.append(aRect.getY()); + aContents.append(" cm "); + aContents.append("/Im"); + aContents.append(nObject); + aContents.append(" Do Q\n"); + } + aLine.setLength(0); aLine.append(nStream); aLine.append(" 0 obj\n<</Length "); @@ -2601,18 +2642,16 @@ bool PDFWriterImpl::emitType3Font(const vcl::font::PhysicalFontFace* pFace, if (!writeBuffer(aContents.getStr(), aContents.getLength())) return false; aLine.setLength(0); - aLine.append("endstream\n" - "endobj\n\n"); + aLine.append("endstream\nendobj\n\n"); if (!writeBuffer(aLine.getStr(), aLine.getLength())) return false; } - if (!updateObject(nFontResources)) - return false; + // write font dict + auto nFontDict = createObject(); aLine.setLength(0); - aLine.append(nFontResources); - aLine.append(" 0 obj <<\n"); - aLine.append("/Font <<\n"); + aLine.append(nFontDict); + aLine.append(" 0 obj\n<<"); for (auto nFontID : aUsedFonts) { aLine.append("/F"); @@ -2621,21 +2660,52 @@ bool PDFWriterImpl::emitType3Font(const vcl::font::PhysicalFontFace* pFace, aLine.append(rFontIDToObject[nFontID]); aLine.append(" 0 R"); } - aLine.append("\n>>\n"); + aLine.append(">>\nendobj\n\n"); + if (!updateObject(nFontDict)) + return false; + if (!writeBuffer(aLine.getStr(), aLine.getLength())) + return false; + + // write ExtGState objects if (!aUsedAlpha.empty()) { - aLine.append("/ExtGState <<\n"); - for (auto nAlpha : aUsedAlpha) + for (const auto & [ nAlpha, nObject ] : aUsedAlpha) { - aLine.append("/GS"); - appendHex(nAlpha, aLine); - aLine.append(" <</ca "); - appendDouble(nAlpha / 255., aLine); - aLine.append(">>\n"); + aLine.setLength(0); + aLine.append(nObject); + aLine.append(" 0 obj\n<<"); + if (m_bIsPDF_A1) + { + aLine.append("/CA 1.0/ca 1.0"); + m_aErrors.insert(PDFWriter::Warning_Transparency_Omitted_PDFA); + } + else + { + aLine.append("/CA "); + appendDouble(nAlpha / 255., aLine); + aLine.append("/ca "); + appendDouble(nAlpha / 255., aLine); + } + aLine.append(">>\nendobj\n\n"); + if (!updateObject(nObject)) + return false; + if (!writeBuffer(aLine.getStr(), aLine.getLength())) + return false; } - aLine.append(">>\n"); } - aLine.append(">>\nendobj\n\n"); + + // write bitmap objects + for (auto& aBitmap : aUsedBitmaps) + writeBitmapObject(aBitmap); + + // write resources dict + aLine.setLength(0); + aLine.append(nResources); + aLine.append(" 0 obj\n"); + aResourceDict.append(aLine, nFontDict); + aLine.append("endobj\n\n"); + if (!updateObject(nResources)) + return false; if (!writeBuffer(aLine.getStr(), aLine.getLength())) return false; @@ -4108,7 +4178,7 @@ void PDFWriterImpl::createDefaultCheckBoxAppearance( PDFWidget& rBox, const PDFW sal_uInt8 nMappedGlyph; sal_Int32 nMappedFontObject; - registerGlyph(nGlyphId, pDevFont, { cMark }, nGlyphWidth, nMappedGlyph, nMappedFontObject, pDevFont->HasColorLayers()); + registerGlyph(nGlyphId, pDevFont, { cMark }, nGlyphWidth, nMappedGlyph, nMappedFontObject, pDevFont->IsColorFont()); appendNonStrokingColor( replaceColor( rWidget.TextColor, rSettings.GetRadioCheckTextColor() ), aDA ); aDA.append( ' ' ); @@ -6057,9 +6127,11 @@ void PDFWriterImpl::registerGlyph(const sal_GlyphId nFontGlyphId, { if (bColor) { - // Font has color layers, check if this glyph has color layers. + // Font has colors, check if this glyph has color layers or bitmap. + tools::Rectangle aRect; auto aLayers = pFace->GetGlyphColorLayers(nFontGlyphId); - if (!aLayers.empty()) + auto aBitmap = pFace->GetGlyphColorBitmap(nFontGlyphId, aRect); + if (!aLayers.empty() || !aBitmap.empty()) { auto& rSubset = m_aType3Fonts[pFace]; auto it = rSubset.m_aMapping.find(nFontGlyphId); @@ -6092,15 +6164,21 @@ void PDFWriterImpl::registerGlyph(const sal_GlyphId nFontGlyphId, rNewGlyphEmit.addCode(nCode); // add color layers to the glyphs - for (const auto& aLayer : aLayers) + if (!aLayers.empty()) { - sal_uInt8 nLayerGlyph; - sal_Int32 nLayerFontID; - registerGlyph(aLayer.nGlyphIndex, pFace, rCodeUnits, nGlyphWidth, nLayerGlyph, - nLayerFontID); + for (const auto& aLayer : aLayers) + { + sal_uInt8 nLayerGlyph; + sal_Int32 nLayerFontID; + registerGlyph(aLayer.nGlyphIndex, pFace, rCodeUnits, nGlyphWidth, + nLayerGlyph, nLayerFontID); - rNewGlyphEmit.addColorLayer({ nLayerFontID, nLayerGlyph, aLayer.nColorIndex }); + rNewGlyphEmit.addColorLayer( + { nLayerFontID, nLayerGlyph, aLayer.nColorIndex }); + } } + else if (!aBitmap.empty()) + rNewGlyphEmit.setColorBitmap(aBitmap, aRect); // add new glyph to font mapping Glyph& rNewGlyph = rSubset.m_aMapping[nFontGlyphId]; @@ -6569,7 +6647,7 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool sal_uInt8 nMappedGlyph; sal_Int32 nMappedFontObject; - registerGlyph(nGlyphId, pFont, aCodeUnits, nGlyphWidth, nMappedGlyph, nMappedFontObject, pDevFont->HasColorLayers()); + registerGlyph(nGlyphId, pFont, aCodeUnits, nGlyphWidth, nMappedGlyph, nMappedFontObject, pDevFont->IsColorFont()); int nCharPos = -1; if (bUseActualText || pGlyph->IsInCluster()) @@ -7673,7 +7751,7 @@ void PDFWriterImpl::drawTransparent( const tools::PolyPolygon& rPolyPoly, sal_uI pushResource( ResourceKind::ExtGState, aExtName, m_aTransparentObjects.back().m_nExtGStateObject ); } -void PDFWriterImpl::pushResource( ResourceKind eKind, const OString& rResource, sal_Int32 nObject ) +void PDFWriterImpl::pushResource(ResourceKind eKind, const OString& rResource, sal_Int32 nObject, ResourceDict& rResourceDict, std::list<StreamRedirect>& rOutputStreams) { if( nObject < 0 ) return; @@ -7681,28 +7759,33 @@ void PDFWriterImpl::pushResource( ResourceKind eKind, const OString& rResource, switch( eKind ) { case ResourceKind::XObject: - m_aGlobalResourceDict.m_aXObjects[ rResource ] = nObject; - if( ! m_aOutputStreams.empty() ) - m_aOutputStreams.front().m_aResourceDict.m_aXObjects[ rResource ] = nObject; + rResourceDict.m_aXObjects[rResource] = nObject; + if (!rOutputStreams.empty()) + rOutputStreams.front().m_aResourceDict.m_aXObjects[rResource] = nObject; break; case ResourceKind::ExtGState: - m_aGlobalResourceDict.m_aExtGStates[ rResource ] = nObject; - if( ! m_aOutputStreams.empty() ) - m_aOutputStreams.front().m_aResourceDict.m_aExtGStates[ rResource ] = nObject; + rResourceDict.m_aExtGStates[rResource] = nObject; + if (!rOutputStreams.empty()) + rOutputStreams.front().m_aResourceDict.m_aExtGStates[rResource] = nObject; break; case ResourceKind::Shading: - m_aGlobalResourceDict.m_aShadings[ rResource ] = nObject; - if( ! m_aOutputStreams.empty() ) - m_aOutputStreams.front().m_aResourceDict.m_aShadings[ rResource ] = nObject; + rResourceDict.m_aShadings[rResource] = nObject; + if (!rOutputStreams.empty()) + rOutputStreams.front().m_aResourceDict.m_aShadings[rResource] = nObject; break; case ResourceKind::Pattern: - m_aGlobalResourceDict.m_aPatterns[ rResource ] = nObject; - if( ! m_aOutputStreams.empty() ) - m_aOutputStreams.front().m_aResourceDict.m_aPatterns[ rResource ] = nObject; + rResourceDict.m_aPatterns[rResource] = nObject; + if (!rOutputStreams.empty()) + rOutputStreams.front().m_aResourceDict.m_aPatterns[rResource] = nObject; break; } } +void PDFWriterImpl::pushResource( ResourceKind eKind, const OString& rResource, sal_Int32 nObject ) +{ + pushResource(eKind, rResource, nObject, m_aGlobalResourceDict, m_aOutputStreams); +} + void PDFWriterImpl::beginRedirect( SvStream* pStream, const tools::Rectangle& rTargetRect ) { push( PushFlags::ALL ); @@ -9479,7 +9562,7 @@ void PDFWriterImpl::drawBitmap( const Point& rDestPoint, const Size& rDestSize, writeBuffer( aLine.getStr(), aLine.getLength() ); } -const BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx& i_rBitmap, const Graphic& rGraphic ) +const BitmapEmit& PDFWriterImpl::createBitmapEmit(const BitmapEx& i_rBitmap, const Graphic& rGraphic, std::list<BitmapEmit>& rBitmaps, ResourceDict& rResourceDict, std::list<StreamRedirect>& rOutputStreams) { BitmapEx aBitmap( i_rBitmap ); auto ePixelFormat = aBitmap.GetBitmap().getPixelFormat(); @@ -9495,26 +9578,31 @@ const BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx& i_rBitmap, co aID.m_nMaskChecksum = 0; if( aBitmap.IsAlpha() ) aID.m_nMaskChecksum = aBitmap.GetAlpha().GetChecksum(); - std::list< BitmapEmit >::const_iterator it = std::find_if(m_aBitmaps.begin(), m_aBitmaps.end(), + std::list<BitmapEmit>::const_iterator it = std::find_if(rBitmaps.begin(), rBitmaps.end(), [&](const BitmapEmit& arg) { return aID == arg.m_aID; }); - if( it == m_aBitmaps.end() ) + if (it == rBitmaps.end()) { - m_aBitmaps.push_front( BitmapEmit() ); - m_aBitmaps.front().m_aID = aID; - m_aBitmaps.front().m_aBitmap = aBitmap; + rBitmaps.push_front(BitmapEmit()); + rBitmaps.front().m_aID = aID; + rBitmaps.front().m_aBitmap = aBitmap; if (!rGraphic.getVectorGraphicData() || rGraphic.getVectorGraphicData()->getType() != VectorGraphicDataType::Pdf || m_aContext.UseReferenceXObject) - m_aBitmaps.front().m_nObject = createObject(); - createEmbeddedFile(rGraphic, m_aBitmaps.front().m_aReferenceXObject, m_aBitmaps.front().m_nObject); - it = m_aBitmaps.begin(); + rBitmaps.front().m_nObject = createObject(); + createEmbeddedFile(rGraphic, rBitmaps.front().m_aReferenceXObject, rBitmaps.front().m_nObject); + it = rBitmaps.begin(); } sal_Int32 nObject = it->m_aReferenceXObject.getObject(); OString aObjName = "Im" + OString::number(nObject); - pushResource( ResourceKind::XObject, aObjName, nObject ); + pushResource(ResourceKind::XObject, aObjName, nObject, rResourceDict, rOutputStreams); return *it; } +const BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx& i_rBitmap, const Graphic& rGraphic ) +{ + return createBitmapEmit(i_rBitmap, rGraphic, m_aBitmaps, m_aGlobalResourceDict, m_aOutputStreams); +} + void PDFWriterImpl::drawBitmap( const Point& rDestPoint, const Size& rDestSize, const Bitmap& rBitmap, const Graphic& rGraphic ) { MARK( "drawBitmap (Bitmap)" ); |