View | Details | Raw Unified | Return to issue 109708
Collapse All | Expand All

(-)a/sdext/source/pdfimport/wrapper/wrapper.cxx (-5 / +126 lines)
Lines 147-152 Link Here
147
147
148
class Parser
148
class Parser
149
{
149
{
150
    // The variable contains value of minimal area that can
151
    // be displayed using internal object filling. Sometimes
152
    // a problem occurs, when object is to narrow and edges
153
    // are close to themselves. It implies small filling area
154
    // and objects are not visible then. The solution is to
155
    // draw object borders that time. 
156
    // TODO: this value shouldn't be hardcoded. The user
157
    // should be able to choose proper value.
158
    const double minAreaThreshold;
159
150
    typedef std::hash_map< sal_Int64,
160
    typedef std::hash_map< sal_Int64,
151
                           FontAttributes > FontMapType;
161
                           FontAttributes > FontMapType;
152
162
Lines 168-173 Link Here
168
    void           readBinaryData( uno::Sequence<sal_Int8>& rBuf );
178
    void           readBinaryData( uno::Sequence<sal_Int8>& rBuf );
169
179
170
    uno::Reference<rendering::XPolyPolygon2D> readPath();
180
    uno::Reference<rendering::XPolyPolygon2D> readPath();
181
    /**
182
     * \brief Reads path and count the area of the smallest rectangle containing it.
183
     *
184
     * Function reads path and counts area of it. It's used
185
     * when EOFILLPATH occurs to check if the area is big 
186
     * enough to draw it using internal filling. Otherwise
187
     * we need to add object borders by calling strokePath.
188
     * The decision is taken by comparing area value to 
189
     * minAreaThreshold variable.
190
     *
191
     * @param area will contain the value of smallest rectangle
192
     * containing the path.
193
     * @return reference to the path.
194
     **/
195
    uno::Reference<rendering::XPolyPolygon2D> readPath(double & area);
171
196
172
    void                 readChar();
197
    void                 readChar();
173
    void                 readLineCap();
198
    void                 readLineCap();
Lines 199-205 Link Here
199
        m_aLine(),
224
        m_aLine(),
200
        m_aFontMap(101),
225
        m_aFontMap(101),
201
        m_nNextToken(-1),
226
        m_nNextToken(-1),
202
        m_nCharIndex(-1)
227
        m_nCharIndex(-1),
228
	minAreaThreshold(300.0)
203
    {}
229
    {}
204
230
205
    void parseLine( const ::rtl::OString& rLine );
231
    void parseLine( const ::rtl::OString& rLine );
Lines 265-270 Link Here
265
    return m_aLine.getToken(m_nNextToken,' ',m_nCharIndex);
291
    return m_aLine.getToken(m_nNextToken,' ',m_nCharIndex);
266
}
292
}
267
293
294
268
void Parser::readInt32( sal_Int32& o_Value )
295
void Parser::readInt32( sal_Int32& o_Value )
269
{
296
{
270
    o_Value = readNextToken().toInt32();
297
    o_Value = readNextToken().toInt32();
Lines 368-375 Link Here
368
395
369
    return static_cast<rendering::XLinePolyPolygon2D*>(
396
    return static_cast<rendering::XLinePolyPolygon2D*>(
370
        new basegfx::unotools::UnoPolyPolygon(aResult));
397
        new basegfx::unotools::UnoPolyPolygon(aResult));
398
} 
399
400
uno::Reference<rendering::XPolyPolygon2D> Parser::readPath(double & area)
401
{
402
    const rtl::OString aSubPathMarker( "subpath" );
403
404
    if( 0 != readNextToken().compareTo( aSubPathMarker ) )
405
        OSL_PRECOND(false, "broken path");
406
407
    basegfx::B2DPolyPolygon aResult;
408
409
    double xmax = 0.0;
410
    double ymax = 0.0;
411
    double xmin = INT_MAX;
412
    double ymin = INT_MAX;
413
    double width = 0.0;
414
    double heigth = 0.0;
415
416
    while( m_nCharIndex != -1 )
417
    {
418
        basegfx::B2DPolygon aSubPath;
419
420
        sal_Int32 nClosedFlag;
421
        readInt32( nClosedFlag );
422
        aSubPath.setClosed( nClosedFlag != 0 );
423
424
        sal_Int32 nContiguousControlPoints(0);
425
        sal_Int32 nDummy=m_nCharIndex;
426
        rtl::OString aCurrToken( m_aLine.getToken(m_nNextToken,' ',nDummy) );
427
428
        while( m_nCharIndex != -1 && 0 != aCurrToken.compareTo(aSubPathMarker) )
429
        {
430
            sal_Int32 nCurveFlag;
431
            double    nX, nY;
432
            readDouble( nX );
433
            readDouble( nY );
434
            readInt32(  nCurveFlag );
435
436
            if(nX < xmin)
437
                xmin = nX;
438
            if(nX > xmax)
439
                xmax = nX;
440
            if(nY < ymin)
441
                ymin = nY;
442
            if(nY > ymax)
443
                ymax = nY;
444
445
            aSubPath.append(basegfx::B2DPoint(nX,nY));
446
            if( nCurveFlag )
447
            {
448
                ++nContiguousControlPoints;
449
            }
450
            else if( nContiguousControlPoints )
451
            {
452
                OSL_PRECOND(nContiguousControlPoints==2,"broken bezier path");
453
454
                // have two control points before us. the current one
455
                // is a normal point - thus, convert previous points
456
                // into bezier segment
457
                const sal_uInt32 nPoints( aSubPath.count() );
458
                const basegfx::B2DPoint aCtrlA( aSubPath.getB2DPoint(nPoints-3) );
459
                const basegfx::B2DPoint aCtrlB( aSubPath.getB2DPoint(nPoints-2) );
460
                const basegfx::B2DPoint aEnd( aSubPath.getB2DPoint(nPoints-1) );
461
                aSubPath.remove(nPoints-3, 3);
462
                aSubPath.appendBezierSegment(aCtrlA, aCtrlB, aEnd);
463
464
                nContiguousControlPoints=0;
465
            }
466
467
            // one token look-ahead (new subpath or more points?
468
            nDummy=m_nCharIndex;
469
            aCurrToken = m_aLine.getToken(m_nNextToken,' ',nDummy);
470
        }
471
472
        aResult.append( aSubPath );
473
        if( m_nCharIndex != -1 )
474
			readNextToken();
475
    }
476
477
    width = xmax - xmin;
478
    heigth = ymax - ymin;
479
    area = width * heigth;
480
481
    return static_cast<rendering::XLinePolyPolygon2D*>(
482
        new basegfx::unotools::UnoPolyPolygon(aResult));
371
}
483
}
372
484
485
373
void Parser::readChar()
486
void Parser::readChar()
374
{
487
{
375
    geometry::Matrix2D aUnoMatrix;
488
    geometry::Matrix2D aUnoMatrix;
Lines 437-443 Link Here
437
        case 0: nJoin = rendering::PathJoinType::MITER; break;
550
        case 0: nJoin = rendering::PathJoinType::MITER; break;
438
        case 1: nJoin = rendering::PathJoinType::ROUND; break;
551
        case 1: nJoin = rendering::PathJoinType::ROUND; break;
439
        case 2: nJoin = rendering::PathJoinType::BEVEL; break;
552
        case 2: nJoin = rendering::PathJoinType::BEVEL; break;
440
    }
553
    } 
441
    m_pSink->setLineJoin(nJoin);
554
    m_pSink->setLineJoin(nJoin);
442
}
555
}
443
556
Lines 775-781 Link Here
775
    OSL_PRECOND( m_pSink,         "Invalid sink" );
888
    OSL_PRECOND( m_pSink,         "Invalid sink" );
776
    OSL_PRECOND( m_pErr,          "Invalid filehandle" );
889
    OSL_PRECOND( m_pErr,          "Invalid filehandle" );
777
    OSL_PRECOND( m_xContext.is(), "Invalid service factory" );
890
    OSL_PRECOND( m_xContext.is(), "Invalid service factory" );
778
    
891
 
779
    m_nNextToken = 0; m_nCharIndex = 0; m_aLine = rLine;
892
    m_nNextToken = 0; m_nCharIndex = 0; m_aLine = rLine;
780
    uno::Reference<rendering::XPolyPolygon2D> xPoly;
893
    uno::Reference<rendering::XPolyPolygon2D> xPoly;
781
    const ::rtl::OString& rCmd = readNextToken();
894
    const ::rtl::OString& rCmd = readNextToken();
Lines 805-813 Link Here
805
        case EOCLIPPATH:
918
        case EOCLIPPATH:
806
            m_pSink->intersectEoClip(readPath()); break;
919
            m_pSink->intersectEoClip(readPath()); break;
807
        case EOFILLPATH:
920
        case EOFILLPATH:
808
            m_pSink->eoFillPath(readPath()); break;
921
        {
922
            double area;
923
            uno::Reference<rendering::XPolyPolygon2D> path = readPath(area); 
924
            m_pSink->eoFillPath(path);
925
            // if area is smaller than required, add borders.
926
            if(area < minAreaThreshold)
927
                m_pSink->strokePath(path);
928
            break;
929
        }
809
        case FILLPATH:
930
        case FILLPATH:
810
            m_pSink->fillPath(readPath()); break;
931
            m_pSink->fillPath(readPath()); break; 
811
        case RESTORESTATE:
932
        case RESTORESTATE:
812
            m_pSink->popState(); break;
933
            m_pSink->popState(); break;
813
        case SAVESTATE:
934
        case SAVESTATE:

Return to issue 109708