[Libreoffice-commits] core.git: Branch 'feature/cib_contract139' - 2 commits - drawinglayer/source vcl/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Fri Mar 22 07:07:49 UTC 2019


Rebased ref, commits from common ancestor:
commit 36eaf9ef8be056151a6a83dc63eaecf154e90a99
Author:     Katarina Behrens <Katarina.Behrens at cib.de>
AuthorDate: Thu Mar 21 13:27:03 2019 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Fri Mar 22 08:06:39 2019 +0100

    Nested list L must be a child of parent's LBody
    
    Implement this as
    https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf#G13.2259746
    describes. The example implementation in Annex H8.2
    https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf#G21.1021285
    where nested L is a sibling of its parent LI contradicts the
    specification and is prolly wrong
    
    Change-Id: I2bd4a6692ac0cbe02ff6f1746656f104de3fe1f2

diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index c2259341781c..036b8d14e8ea 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -555,6 +555,35 @@ namespace drawinglayer
             }
         }
 
+        void VclMetafileProcessor2D::popListItem()
+        {
+            if (!maListElements.empty())
+            {
+                if (maListElements.top() == vcl::PDFWriter::LIBody)
+                {
+                    maListElements.pop();
+                    mpPDFExtOutDevData->EndStructureElement();
+                }
+                if (maListElements.top() == vcl::PDFWriter::ListItem)
+                {
+                    maListElements.pop();
+                    mpPDFExtOutDevData->EndStructureElement();
+                }
+            }
+        }
+
+        void VclMetafileProcessor2D::popList()
+        {
+            if (!maListElements.empty())
+            {
+                if (maListElements.top() == vcl::PDFWriter::List)
+                {
+                    maListElements.pop();
+                    mpPDFExtOutDevData->EndStructureElement();
+                }
+            }
+        }
+
         // init static break iterator
         uno::Reference< css::i18n::XBreakIterator > VclMetafileProcessor2D::mxBreakIterator;
 
@@ -1233,7 +1262,10 @@ namespace drawinglayer
 
             // this is a part of list item, start LILabel ( = bullet)
             if(mbInListItem)
+            {
+                maListElements.push(vcl::PDFWriter::LILabel);
                 mpPDFExtOutDevData->BeginStructureElement(vcl::PDFWriter::LILabel);
+            }
 
             // process recursively and add MetaFile comment
             process(rBulletPrimitive);
@@ -1241,8 +1273,12 @@ namespace drawinglayer
 
             if(mbInListItem)
             {
-                mpPDFExtOutDevData->EndStructureElement(); // end LILabel
-                mbBulletPresent = true;
+                if (maListElements.top() == vcl::PDFWriter::LILabel)
+                {
+                    maListElements.pop();
+                    mpPDFExtOutDevData->EndStructureElement(); // end LILabel
+                    mbBulletPresent = true;
+                }
             }
         }
 
@@ -1286,29 +1322,41 @@ namespace drawinglayer
                 if(nNewOutlineLevel > mnCurrentOutlineLevel)
                 {
                     // increase List level
-                    for(sal_Int16 a(mnCurrentOutlineLevel); a != nNewOutlineLevel; a++)
+                    for(sal_Int16 a(mnCurrentOutlineLevel); a != nNewOutlineLevel; ++a)
                     {
+                        maListElements.push(vcl::PDFWriter::List);
                         mpPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::List );
                     }
                 }
                 else // if(nNewOutlineLevel < mnCurrentOutlineLevel)
                 {
-                    // decrease List level
-                    for(sal_Int16 a(mnCurrentOutlineLevel); a != nNewOutlineLevel; a--)
+                    // close list levels below nNewOutlineLevel completely by removing
+                    // list items as well as list tag itself
+                    for(sal_Int16 a(nNewOutlineLevel); a < mnCurrentOutlineLevel; ++a)
                     {
-                        mpPDFExtOutDevData->EndStructureElement();
+                        popListItem(); // end LBody and LI
+                        popList(); // end L
                     }
-                }
+
+                    // on nNewOutlineLevel close the previous list item
+                    popListItem();
+                 }
 
                 // Remember new current OutlineLevel
                 mnCurrentOutlineLevel = nNewOutlineLevel;
             }
+            else // the same list level
+            {
+                // close the previous list item
+                popListItem();
+            }
 
             const bool bDumpAsListItem(-1 != mnCurrentOutlineLevel);
 
             if(bDumpAsListItem)
             {
                 // Dump as ListItem
+                maListElements.push(vcl::PDFWriter::ListItem);
                 mpPDFExtOutDevData->BeginStructureElement( vcl::PDFWriter::ListItem );
                 mbInListItem = true;
             }
@@ -1323,10 +1371,7 @@ namespace drawinglayer
             mpMetaFile->AddAction(new MetaCommentAction(aCommentString));
 
             if(bDumpAsListItem)
-            {
-                mpPDFExtOutDevData->EndStructureElement(); // end ListItem
                 mbInListItem = false;
-            }
             else
                 mpPDFExtOutDevData->EndStructureElement(); // end Paragraph
         }
@@ -1343,8 +1388,11 @@ namespace drawinglayer
             if (mnCurrentOutlineLevel >= 0 )
             {
                 // end any opened List structure elements
-                for(sal_Int16 i(0); i <= mnCurrentOutlineLevel; ++i)
-                    mpPDFExtOutDevData->EndStructureElement();
+                for(sal_Int16 a(0); a <= mnCurrentOutlineLevel; ++a)
+                {
+                    popListItem();
+                    popList();
+                }
             }
 
             mpMetaFile->AddAction(new MetaCommentAction(aCommentStringB));
@@ -1359,16 +1407,16 @@ namespace drawinglayer
             // this is a 2nd portion of list item
             // bullet has been already processed, start LIBody
             if (mbInListItem && mbBulletPresent)
+            {
+                maListElements.push(vcl::PDFWriter::LIBody);
                 mpPDFExtOutDevData->BeginStructureElement(vcl::PDFWriter::LIBody);
+            }
 
             // directdraw of text simple portion; use default processing
             RenderTextSimpleOrDecoratedPortionPrimitive2D(rTextCandidate);
 
             if (mbInListItem && mbBulletPresent)
-            {
-                mpPDFExtOutDevData->EndStructureElement(); // end LIBody
                 mbBulletPresent = false;
-            }
 
             // restore DrawMode
             mpOutputDevice->SetDrawMode(nOriginalDrawMode);
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
index 3b9f39f804a6..a5f9a7fd9597 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.hxx
@@ -20,6 +20,8 @@
 #ifndef INCLUDED_DRAWINGLAYER_SOURCE_PROCESSOR2D_VCLMETAFILEPROCESSOR2D_HXX
 #define INCLUDED_DRAWINGLAYER_SOURCE_PROCESSOR2D_VCLMETAFILEPROCESSOR2D_HXX
 
+#include <stack>
+
 #include <drawinglayer/drawinglayerdllapi.h>
 
 #include "vclprocessor2d.hxx"
@@ -112,6 +114,8 @@ namespace drawinglayer
                 const attribute::LineStartEndAttribute* pEnd);
             void impStartSvtGraphicStroke(SvtGraphicStroke const * pSvtGraphicStroke);
             void impEndSvtGraphicStroke(SvtGraphicStroke* pSvtGraphicStroke);
+            void popListItem();
+            void popList();
 
             void processGraphicPrimitive2D(const primitive2d::GraphicPrimitive2D& rGraphicPrimitive);
             void processControlPrimitive2D(const primitive2d::ControlPrimitive2D& rControlPrimitive);
@@ -177,6 +181,8 @@ namespace drawinglayer
             bool mbInListItem;
             bool mbBulletPresent;
 
+            std::stack<vcl::PDFWriter::StructElement> maListElements;
+
         protected:
             /*  the local processor for BasePrimitive2D-Implementation based primitives,
                 called from the common process()-implementation
commit d3f21588d3d1402bee42d5374ed060a7e26b7b91
Author:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
AuthorDate: Thu Mar 14 00:36:37 2019 +0100
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Fri Mar 22 08:06:39 2019 +0100

    Fix pdf validation error 'glyph width in dict and font inconsistent'
    
    Previous code was writing hard-coded '1000' as glyph width for any type1
    font subsetting - since actual type2 width info only became available
    during subsequent convertOneTypeOp() parsing.
    
    Catch was, that loop sometimes already modifies the output buffer
    (whenever glyph path info was given), so we fix that by first padding
    out 5 bytes for the width (size of integers are sadly variable), then
    parsing Type2 glyph code, and in the end putting in the actual width
    value we then know.
    
    Can't put hsbw type1 op last, since standard requires that to be first
    (and can only be given _once_).
    
    Could be re-done nicer by buffering Type2 glyph data, then writing it.
    Left as an exercise for the reader.
    
    Conflicts:
            vcl/source/fontsubset/cff.cxx
    
    Change-Id: I64ffaa32ded2f0a7c06311d1e0426cf358308a0a

diff --git a/vcl/source/fontsubset/cff.cxx b/vcl/source/fontsubset/cff.cxx
index 13ed076d1ff6..aa6d09f8d992 100644
--- a/vcl/source/fontsubset/cff.cxx
+++ b/vcl/source/fontsubset/cff.cxx
@@ -1099,29 +1099,41 @@ int CffSubsetterContext::convert2Type1Ops( CffLocal* pCffLocal, const U8* const
     *(mpWritePtr++) = 0x44;
     *(mpWritePtr++) = 0x55;
     *(mpWritePtr++) = ' ';
-#if 1 // convert the Type2 charstring to Type1
+
+    // convert the Type2 charstring to Type1
     mpReadPtr = pT2Ops;
     mpReadEnd = pT2Ops + nT2Len;
     // prepend "hsbw" or "sbw"
     // TODO: only emit hsbw when charwidth is known
-    // TODO: remove charwidth from T2 stack
-    writeType1Val( 0); // TODO: aSubsetterContext.getLeftSideBearing();
-    writeType1Val( 1000/*###getCharWidth()###*/);
-    writeTypeOp( TYPE1OP::HSBW);
-mbNeedClose = false;
-mbIgnoreHints = false;
-mnHintSize=mnHorzHintSize=mnStackIdx=0; maCharWidth=-1;//#######
-mnCntrMask = 0;
+    writeType1Val(0); // TODO: aSubsetterContext.getLeftSideBearing();
+    U8* pCharWidthPtr=mpWritePtr; // need to overwrite that later
+    // pad out 5 bytes for the char width with default val 1000 (to be
+    // filled with the actual value below)
+    *(mpWritePtr++) = 255;
+    *(mpWritePtr++) = static_cast<U8>(0);
+    *(mpWritePtr++) = static_cast<U8>(0);
+    *(mpWritePtr++) = static_cast<U8>(250);
+    *(mpWritePtr++) = static_cast<U8>(124);
+    writeTypeOp(TYPE1OP::HSBW);
+    mbNeedClose = false;
+    mbIgnoreHints = false;
+    mnHintSize=mnHorzHintSize=mnStackIdx=0; maCharWidth=-1;//#######
+    mnCntrMask = 0;
     while( mpReadPtr < mpReadEnd)
         convertOneTypeOp();
-//  if( bActivePath)
-//      writeTypeOp( TYPE1OP::CLOSEPATH);
-//  if( bSubRoutine)
-//      writeTypeOp( TYPE1OP::RETURN);
-#else // useful for manually encoding charstrings
-    mpWritePtr = pT1Ops;
-    mpWritePtr += sprintf( (char*)mpWritePtr, "OOo_\x8b\x8c\x0c\x10\x0b");
-#endif
+    if( maCharWidth != -1 )
+    {
+        // overwrite earlier charWidth value, which we only now have
+        // parsed out of mpReadPtr buffer (by way of
+        // convertOneTypeOp()s above)
+        const int nInt = static_cast<int>(maCharWidth);
+        *(pCharWidthPtr++) = 255;
+        *(pCharWidthPtr++) = static_cast<U8>(nInt >> 24);
+        *(pCharWidthPtr++) = static_cast<U8>(nInt >> 16);
+        *(pCharWidthPtr++) = static_cast<U8>(nInt >> 8);
+        *(pCharWidthPtr++) = static_cast<U8>(nInt);
+    }
+
     const int nType1Len = mpWritePtr - pT1Ops;
 
     // encrypt the Type1 charstring


More information about the Libreoffice-commits mailing list