~ubuntu-branches/ubuntu/saucy/libmspub/saucy

« back to all changes in this revision

Viewing changes to src/lib/MSPUBCollector.cpp

  • Committer: Package Import Robot
  • Author(s): Rene Engelhard
  • Date: 2013-05-13 18:39:21 UTC
  • mfrom: (3.1.4 sid)
  • Revision ID: package-import@ubuntu.com-20130513183921-7kkhuk8dld8a11yt
Tags: 0.0.6-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
  m_shapeInfosBySeqNum[seqNum].m_pictureRecolor = recolor;
56
56
}
57
57
 
 
58
void libmspub::MSPUBCollector::setShapePictureBrightness(unsigned seqNum,
 
59
    int brightness)
 
60
{
 
61
  m_shapeInfosBySeqNum[seqNum].m_pictureBrightness = brightness;
 
62
}
 
63
 
 
64
void libmspub::MSPUBCollector::setShapePictureContrast(unsigned seqNum,
 
65
    int contrast)
 
66
{
 
67
  m_shapeInfosBySeqNum[seqNum].m_pictureContrast = contrast;
 
68
}
 
69
 
58
70
void libmspub::MSPUBCollector::setShapeBeginArrow(unsigned seqNum,
59
71
    const Arrow &arrow)
60
72
{
222
234
  m_shapeInfosBySeqNum[seqNum].m_customShape = shape;
223
235
}
224
236
 
 
237
void libmspub::MSPUBCollector::setShapeClipPath(unsigned seqNum, const std::vector<libmspub::Vertex> &clip)
 
238
{
 
239
  m_shapeInfosBySeqNum[seqNum].m_clipPath = clip;
 
240
}
 
241
 
225
242
void libmspub::MSPUBCollector::beginGroup()
226
243
{
227
244
  ShapeGroupElement *tmp = new ShapeGroupElement(m_currentShapeGroup);
328
345
 
329
346
boost::optional<std::vector<libmspub::TextParagraph> > libmspub::MSPUBCollector::getShapeText(const ShapeInfo &info) const
330
347
{
331
 
  if (info.m_textId.is_initialized())
 
348
  if (!!info.m_textId)
332
349
  {
333
350
    unsigned stringId = info.m_textId.get();
334
351
    const std::vector<TextParagraph> *ptr_str = getIfExists_const(m_textStringsById, stringId);
345
362
  ShapeInfo *ptr_info = getIfExists(m_shapeInfosBySeqNum, elt.getSeqNum());
346
363
  if (ptr_info)
347
364
  {
348
 
    if (ptr_info->m_imgIndex.is_initialized())
 
365
    if (!!ptr_info->m_imgIndex)
349
366
    {
350
367
      unsigned index = ptr_info->m_imgIndex.get();
 
368
      int rot = 0;
 
369
      if (!!ptr_info->m_innerRotation)
 
370
        rot = ptr_info->m_innerRotation.get();
351
371
      if (index - 1 < m_images.size())
352
372
      {
353
 
        ptr_info->m_fill = boost::shared_ptr<const Fill>(new ImgFill(index, this, false));
 
373
        ptr_info->m_fill = boost::shared_ptr<const Fill>(new ImgFill(index, this, false, rot));
354
374
      }
355
375
    }
356
376
    elt.setShapeInfo(*ptr_info);
382
402
  bool hasStroke = false;
383
403
  bool hasBorderArt = false;
384
404
  boost::optional<unsigned> maybeBorderImg = info.m_borderImgIndex;
385
 
  if (maybeBorderImg.is_initialized() && !info.m_lines.empty())
 
405
  if (!!maybeBorderImg && !info.m_lines.empty())
386
406
  {
387
407
    hasStroke = true;
388
408
    hasBorderArt = true;
401
421
  WPXString fill = graphicsProps["draw:fill"] ? graphicsProps["draw:fill"]->getStr() : "none";
402
422
  bool hasFill = fill != "none";
403
423
  boost::optional<std::vector<TextParagraph> > maybeText = getShapeText(info);
404
 
  bool hasText = maybeText.is_initialized();
 
424
  bool hasText = !!maybeText;
405
425
  bool makeLayer = hasBorderArt ||
406
426
                   (hasStroke && hasFill) || (hasStroke && hasText) || (hasFill && hasText);
407
427
  if (makeLayer)
408
428
  {
409
 
    m_painter->startLayer(WPXPropertyList());
 
429
    if (info.m_clipPath.size() > 0)
 
430
    {
 
431
      const Coordinate &coord = info.m_coordinates.get_value_or(Coordinate());
 
432
      double x, y, height, width;
 
433
      x = coord.getXIn(m_width);
 
434
      y = coord.getYIn(m_height);
 
435
      height = coord.getHeightIn();
 
436
      width = coord.getWidthIn();
 
437
      m_painter->startLayer(calcClipPath(info.m_clipPath, x, y, height, width, foldedTransform, info.getCustomShape()));
 
438
    }
 
439
    else
 
440
      m_painter->startLayer(WPXPropertyList());
410
441
  }
411
442
  graphicsProps.insert("draw:stroke", "none");
412
443
  const Coordinate &coord = info.m_coordinates.get_value_or(Coordinate());
413
444
  BorderPosition borderPosition =
414
445
    hasBorderArt ? INSIDE_SHAPE : info.m_borderPosition.get_value_or(HALF_INSIDE_SHAPE);
415
446
  ShapeType type;
416
 
  if (info.m_cropType.is_initialized())
 
447
  if (!!info.m_cropType)
417
448
  {
418
449
    type = info.m_cropType.get();
419
450
  }
421
452
  {
422
453
    type = info.m_type.get_value_or(RECTANGLE);
423
454
  }
424
 
  
 
455
 
425
456
  if (hasFill)
426
457
  {
427
458
    double x, y, height, width;
441
472
        width -= 2 * borderImgWidth;
442
473
      }
443
474
    }
444
 
    if (info.m_pictureRecolor.is_initialized())
 
475
    if (!!info.m_pictureRecolor)
445
476
    {
446
477
      Color obc = info.m_pictureRecolor.get().getFinalColor(m_paletteColors);
447
478
      graphicsProps.insert("draw:color-mode", "greyscale");
452
483
      graphicsProps.insert("draw:green",
453
484
                           static_cast<double>(obc.g) / 255.0, WPX_PERCENT);
454
485
    }
 
486
    if (!!info.m_pictureBrightness)
 
487
      graphicsProps.insert("draw:luminance", static_cast<double>(info.m_pictureBrightness.get() + 32768.0) / 65536.0, WPX_PERCENT);
455
488
    bool shadowPropsInserted = false;
456
 
    if (info.m_shadow.is_initialized())
 
489
    if (!!info.m_shadow)
457
490
    {
458
491
      const Shadow &s = info.m_shadow.get();
459
492
      if (!needsEmulation(s))
460
493
      {
461
494
        shadowPropsInserted = true;
462
495
        graphicsProps.insert("draw:shadow", "visible");
463
 
        graphicsProps.insert("draw:shadow-offset-x",
464
 
                             static_cast<double>(s.m_offsetXInEmu) / EMUS_IN_INCH);
465
 
        graphicsProps.insert("draw:shadow-offset-y",
466
 
                             static_cast<double>(s.m_offsetYInEmu) / EMUS_IN_INCH);
467
 
        graphicsProps.insert("draw:shadow-color",
468
 
                             getColorString(s.m_color.getFinalColor(m_paletteColors)));
469
 
        graphicsProps.insert("draw:shadow-opacity",
470
 
                             s.m_opacity, WPX_PERCENT);
 
496
        graphicsProps.insert("draw:shadow-offset-x", static_cast<double>(s.m_offsetXInEmu) / EMUS_IN_INCH);
 
497
        graphicsProps.insert("draw:shadow-offset-y", static_cast<double>(s.m_offsetYInEmu) / EMUS_IN_INCH);
 
498
        graphicsProps.insert("draw:shadow-color", getColorString(s.m_color.getFinalColor(m_paletteColors)));
 
499
        graphicsProps.insert("draw:shadow-opacity", s.m_opacity, WPX_PERCENT);
471
500
      }
472
501
      // TODO: Emulate shadows that don't conform
473
502
      // to LibreOffice's range of possible shadows.
477
506
    writeCustomShape(type, graphicsProps, m_painter, x, y, height, width,
478
507
                     true, foldedTransform,
479
508
                     std::vector<Line>(), boost::bind(&libmspub::MSPUBCollector::getCalculationValue, this, info, _1, false, adjustValues), m_paletteColors, info.getCustomShape());
480
 
    if (info.m_pictureRecolor.is_initialized())
 
509
    if (!!info.m_pictureRecolor)
481
510
    {
482
511
      graphicsProps.remove("draw:color-mode");
483
512
      graphicsProps.remove("draw:red");
484
513
      graphicsProps.remove("draw:blue");
485
514
      graphicsProps.remove("draw:green");
486
515
    }
 
516
    if (!!info.m_pictureBrightness)
 
517
      graphicsProps.remove("draw:luminance");
487
518
    if (shadowPropsInserted)
488
519
    {
489
520
      graphicsProps.remove("draw:shadow");
528
559
        }
529
560
        double borderVertPadding = borderVertTotalPadding / (numImagesVert - 1);
530
561
        double borderHorizPadding = borderHorizTotalPadding / (numImagesHoriz - 1);
531
 
        const BorderArtInfo &ba = m_borderImages[maybeBorderImg.get()];
532
 
        if (!ba.m_offsets.empty())
 
562
        if (maybeBorderImg.get() < m_borderImages.size())
533
563
        {
534
 
          WPXPropertyList baProps;
535
 
          baProps.insert("draw:stroke", "none");
536
 
          baProps.insert("draw:fill", "solid");
537
 
          baProps.insert("draw:fill-color", "#ffffff");
538
 
          m_painter->setStyle(baProps, WPXPropertyListVector());
539
 
          WPXPropertyList topRectProps;
540
 
          topRectProps.insert("svg:x", x);
541
 
          topRectProps.insert("svg:y", y);
542
 
          topRectProps.insert("svg:height", borderImgWidth);
543
 
          topRectProps.insert("svg:width", width);
544
 
          m_painter->drawRectangle(topRectProps);
545
 
          WPXPropertyList rightRectProps;
546
 
          rightRectProps.insert("svg:x", x + width - borderImgWidth);
547
 
          rightRectProps.insert("svg:y", y);
548
 
          rightRectProps.insert("svg:height", height);
549
 
          rightRectProps.insert("svg:width", borderImgWidth);
550
 
          m_painter->drawRectangle(rightRectProps);
551
 
          WPXPropertyList botRectProps;
552
 
          botRectProps.insert("svg:x", x);
553
 
          botRectProps.insert("svg:y", y + height - borderImgWidth);
554
 
          botRectProps.insert("svg:height", borderImgWidth);
555
 
          botRectProps.insert("svg:width", width);
556
 
          m_painter->drawRectangle(botRectProps);
557
 
          WPXPropertyList leftRectProps;
558
 
          leftRectProps.insert("svg:x", x);
559
 
          leftRectProps.insert("svg:y", y);
560
 
          leftRectProps.insert("svg:height", height);
561
 
          leftRectProps.insert("svg:width", borderImgWidth);
562
 
          m_painter->drawRectangle(leftRectProps);
563
 
          std::vector<unsigned>::const_iterator iOffset = ba.m_offsets.begin();
564
 
          boost::optional<Color> oneBitColor;
565
 
          if (info.m_lineBackColor.is_initialized())
566
 
          {
567
 
            oneBitColor = info.m_lineBackColor.get().getFinalColor(m_paletteColors);
568
 
          }
569
 
          // top left
570
 
          unsigned iOrdOff = find(ba.m_offsetsOrdered.begin(),
571
 
                                  ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
572
 
          if (iOrdOff < ba.m_images.size())
573
 
          {
574
 
            const BorderImgInfo &bi = ba.m_images[iOrdOff];
575
 
            writeImage(x, y, borderImgWidth, borderImgWidth,
576
 
                       bi.m_type, bi.m_imgBlob, oneBitColor);
577
 
          }
578
 
          if (iOffset + 1 != ba.m_offsets.end())
579
 
          {
580
 
            ++iOffset;
581
 
          }
582
 
          // top
583
 
          iOrdOff = find(ba.m_offsetsOrdered.begin(),
584
 
                         ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
585
 
          if (iOrdOff < ba.m_images.size())
586
 
          {
587
 
            const BorderImgInfo &bi = ba.m_images[iOrdOff];
588
 
            for (unsigned iTop = 1; iTop < numImagesHoriz - 1; ++iTop)
589
 
            {
590
 
              double imgX = stretch ?
591
 
                            x + borderImgWidth + (iTop - 1) * stretchedImgWidth :
592
 
                            x + iTop * (borderImgWidth + borderHorizPadding);
593
 
              writeImage(imgX, y,
594
 
                         borderImgWidth, stretchedImgWidth,
595
 
                         bi.m_type, bi.m_imgBlob, oneBitColor);
596
 
            }
597
 
          }
598
 
          if (iOffset + 1 != ba.m_offsets.end())
599
 
          {
600
 
            ++iOffset;
601
 
          }
602
 
          // top right
603
 
          iOrdOff = find(ba.m_offsetsOrdered.begin(),
604
 
                         ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
605
 
          if (iOrdOff < ba.m_images.size())
606
 
          {
607
 
            const BorderImgInfo &bi = ba.m_images[iOrdOff];
608
 
            writeImage(x + width - borderImgWidth, y,
609
 
                       borderImgWidth, borderImgWidth,
610
 
                       bi.m_type, bi.m_imgBlob, oneBitColor);
611
 
          }
612
 
          if (iOffset + 1 != ba.m_offsets.end())
613
 
          {
614
 
            ++iOffset;
615
 
          }
616
 
          // right
617
 
          iOrdOff = find(ba.m_offsetsOrdered.begin(),
618
 
                         ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
619
 
          if (iOrdOff < ba.m_images.size())
620
 
          {
621
 
            const BorderImgInfo &bi = ba.m_images[iOrdOff];
622
 
            for (unsigned iRight = 1; iRight < numImagesVert - 1; ++iRight)
623
 
            {
624
 
              double imgY = stretch ?
625
 
                            y + borderImgWidth + (iRight - 1) * stretchedImgHeight :
626
 
                            y + iRight * (borderImgWidth + borderVertPadding);
 
564
          const BorderArtInfo &ba = m_borderImages[maybeBorderImg.get()];
 
565
          if (!ba.m_offsets.empty())
 
566
          {
 
567
            WPXPropertyList baProps;
 
568
            baProps.insert("draw:stroke", "none");
 
569
            baProps.insert("draw:fill", "solid");
 
570
            baProps.insert("draw:fill-color", "#ffffff");
 
571
            m_painter->setStyle(baProps, WPXPropertyListVector());
 
572
            WPXPropertyList topRectProps;
 
573
            topRectProps.insert("svg:x", x);
 
574
            topRectProps.insert("svg:y", y);
 
575
            topRectProps.insert("svg:height", borderImgWidth);
 
576
            topRectProps.insert("svg:width", width);
 
577
            m_painter->drawRectangle(topRectProps);
 
578
            WPXPropertyList rightRectProps;
 
579
            rightRectProps.insert("svg:x", x + width - borderImgWidth);
 
580
            rightRectProps.insert("svg:y", y);
 
581
            rightRectProps.insert("svg:height", height);
 
582
            rightRectProps.insert("svg:width", borderImgWidth);
 
583
            m_painter->drawRectangle(rightRectProps);
 
584
            WPXPropertyList botRectProps;
 
585
            botRectProps.insert("svg:x", x);
 
586
            botRectProps.insert("svg:y", y + height - borderImgWidth);
 
587
            botRectProps.insert("svg:height", borderImgWidth);
 
588
            botRectProps.insert("svg:width", width);
 
589
            m_painter->drawRectangle(botRectProps);
 
590
            WPXPropertyList leftRectProps;
 
591
            leftRectProps.insert("svg:x", x);
 
592
            leftRectProps.insert("svg:y", y);
 
593
            leftRectProps.insert("svg:height", height);
 
594
            leftRectProps.insert("svg:width", borderImgWidth);
 
595
            m_painter->drawRectangle(leftRectProps);
 
596
            std::vector<unsigned>::const_iterator iOffset = ba.m_offsets.begin();
 
597
            boost::optional<Color> oneBitColor;
 
598
            if (!!info.m_lineBackColor)
 
599
            {
 
600
              oneBitColor = info.m_lineBackColor.get().getFinalColor(m_paletteColors);
 
601
            }
 
602
            // top left
 
603
            unsigned iOrdOff = find(ba.m_offsetsOrdered.begin(),
 
604
                                    ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
 
605
            if (iOrdOff < ba.m_images.size())
 
606
            {
 
607
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
 
608
              writeImage(x, y, borderImgWidth, borderImgWidth,
 
609
                        bi.m_type, bi.m_imgBlob, oneBitColor);
 
610
            }
 
611
            if (iOffset + 1 != ba.m_offsets.end())
 
612
            {
 
613
              ++iOffset;
 
614
            }
 
615
            // top
 
616
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
 
617
                          ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
 
618
            if (iOrdOff < ba.m_images.size())
 
619
            {
 
620
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
 
621
              for (unsigned iTop = 1; iTop < numImagesHoriz - 1; ++iTop)
 
622
              {
 
623
                double imgX = stretch ?
 
624
                              x + borderImgWidth + (iTop - 1) * stretchedImgWidth :
 
625
                              x + iTop * (borderImgWidth + borderHorizPadding);
 
626
                writeImage(imgX, y,
 
627
                          borderImgWidth, stretchedImgWidth,
 
628
                          bi.m_type, bi.m_imgBlob, oneBitColor);
 
629
              }
 
630
            }
 
631
            if (iOffset + 1 != ba.m_offsets.end())
 
632
            {
 
633
              ++iOffset;
 
634
            }
 
635
            // top right
 
636
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
 
637
                          ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
 
638
            if (iOrdOff < ba.m_images.size())
 
639
            {
 
640
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
 
641
              writeImage(x + width - borderImgWidth, y,
 
642
                        borderImgWidth, borderImgWidth,
 
643
                        bi.m_type, bi.m_imgBlob, oneBitColor);
 
644
            }
 
645
            if (iOffset + 1 != ba.m_offsets.end())
 
646
            {
 
647
              ++iOffset;
 
648
            }
 
649
            // right
 
650
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
 
651
                          ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
 
652
            if (iOrdOff < ba.m_images.size())
 
653
            {
 
654
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
 
655
              for (unsigned iRight = 1; iRight < numImagesVert - 1; ++iRight)
 
656
              {
 
657
                double imgY = stretch ?
 
658
                              y + borderImgWidth + (iRight - 1) * stretchedImgHeight :
 
659
                              y + iRight * (borderImgWidth + borderVertPadding);
 
660
                writeImage(x + width - borderImgWidth,
 
661
                          imgY,
 
662
                          stretchedImgHeight, borderImgWidth,
 
663
                          bi.m_type, bi.m_imgBlob, oneBitColor);
 
664
              }
 
665
            }
 
666
            if (iOffset + 1 != ba.m_offsets.end())
 
667
            {
 
668
              ++iOffset;
 
669
            }
 
670
            // bottom right
 
671
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
 
672
                          ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
 
673
            if (iOrdOff < ba.m_images.size())
 
674
            {
 
675
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
627
676
              writeImage(x + width - borderImgWidth,
628
 
                         imgY,
629
 
                         stretchedImgHeight, borderImgWidth,
630
 
                         bi.m_type, bi.m_imgBlob, oneBitColor);
631
 
            }
632
 
          }
633
 
          if (iOffset + 1 != ba.m_offsets.end())
634
 
          {
635
 
            ++iOffset;
636
 
          }
637
 
          // bottom right
638
 
          iOrdOff = find(ba.m_offsetsOrdered.begin(),
639
 
                         ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
640
 
          if (iOrdOff < ba.m_images.size())
641
 
          {
642
 
            const BorderImgInfo &bi = ba.m_images[iOrdOff];
643
 
            writeImage(x + width - borderImgWidth,
644
 
                       y + height - borderImgWidth,
645
 
                       borderImgWidth, borderImgWidth,
646
 
                       bi.m_type, bi.m_imgBlob, oneBitColor);
647
 
          }
648
 
          if (iOffset + 1 != ba.m_offsets.end())
649
 
          {
650
 
            ++iOffset;
651
 
          }
652
 
          // bottom
653
 
          iOrdOff = find(ba.m_offsetsOrdered.begin(),
654
 
                         ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
655
 
          if (iOrdOff < ba.m_images.size())
656
 
          {
657
 
            const BorderImgInfo &bi = ba.m_images[iOrdOff];
658
 
            for (unsigned iBot = 1; iBot < numImagesHoriz - 1; ++iBot)
659
 
            {
660
 
              double imgX = stretch ?
661
 
                            x + width - borderImgWidth - iBot * stretchedImgWidth :
662
 
                            x + width - borderImgWidth - iBot * (borderImgWidth + borderHorizPadding);
663
 
              writeImage(
664
 
                imgX, y + height - borderImgWidth,
665
 
                borderImgWidth, stretchedImgWidth,
666
 
                bi.m_type, bi.m_imgBlob, oneBitColor);
667
 
            }
668
 
          }
669
 
          if (iOffset + 1 != ba.m_offsets.end())
670
 
          {
671
 
            ++iOffset;
672
 
          }
673
 
          // bottom left
674
 
          iOrdOff = find(ba.m_offsetsOrdered.begin(),
675
 
                         ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
676
 
          if (iOrdOff < ba.m_images.size())
677
 
          {
678
 
            const BorderImgInfo &bi = ba.m_images[iOrdOff];
679
 
            writeImage(x, y + height - borderImgWidth,
680
 
                       borderImgWidth, borderImgWidth,
681
 
                       bi.m_type, bi.m_imgBlob, oneBitColor);
682
 
          }
683
 
          if (iOffset + 1 != ba.m_offsets.end())
684
 
          {
685
 
            ++iOffset;
686
 
          }
687
 
          // left
688
 
          iOrdOff = find(ba.m_offsetsOrdered.begin(),
689
 
                         ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
690
 
          if (iOrdOff < ba.m_images.size())
691
 
          {
692
 
            const BorderImgInfo &bi = ba.m_images[iOrdOff];
693
 
            for (unsigned iLeft = 1; iLeft < numImagesVert - 1; ++iLeft)
694
 
            {
695
 
              double imgY = stretch ?
696
 
                            y + height - borderImgWidth - iLeft * stretchedImgHeight :
697
 
                            y + height - borderImgWidth -
698
 
                            iLeft * (borderImgWidth + borderVertPadding);
699
 
              writeImage(x, imgY, stretchedImgHeight, borderImgWidth,
700
 
                         bi.m_type, bi.m_imgBlob, oneBitColor);
 
677
                        y + height - borderImgWidth,
 
678
                        borderImgWidth, borderImgWidth,
 
679
                        bi.m_type, bi.m_imgBlob, oneBitColor);
 
680
            }
 
681
            if (iOffset + 1 != ba.m_offsets.end())
 
682
            {
 
683
              ++iOffset;
 
684
            }
 
685
            // bottom
 
686
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
 
687
                          ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
 
688
            if (iOrdOff < ba.m_images.size())
 
689
            {
 
690
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
 
691
              for (unsigned iBot = 1; iBot < numImagesHoriz - 1; ++iBot)
 
692
              {
 
693
                double imgX = stretch ?
 
694
                              x + width - borderImgWidth - iBot * stretchedImgWidth :
 
695
                              x + width - borderImgWidth - iBot * (borderImgWidth + borderHorizPadding);
 
696
                writeImage(
 
697
                  imgX, y + height - borderImgWidth,
 
698
                  borderImgWidth, stretchedImgWidth,
 
699
                  bi.m_type, bi.m_imgBlob, oneBitColor);
 
700
              }
 
701
            }
 
702
            if (iOffset + 1 != ba.m_offsets.end())
 
703
            {
 
704
              ++iOffset;
 
705
            }
 
706
            // bottom left
 
707
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
 
708
                          ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
 
709
            if (iOrdOff < ba.m_images.size())
 
710
            {
 
711
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
 
712
              writeImage(x, y + height - borderImgWidth,
 
713
                        borderImgWidth, borderImgWidth,
 
714
                        bi.m_type, bi.m_imgBlob, oneBitColor);
 
715
            }
 
716
            if (iOffset + 1 != ba.m_offsets.end())
 
717
            {
 
718
              ++iOffset;
 
719
            }
 
720
            // left
 
721
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
 
722
                          ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
 
723
            if (iOrdOff < ba.m_images.size())
 
724
            {
 
725
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
 
726
              for (unsigned iLeft = 1; iLeft < numImagesVert - 1; ++iLeft)
 
727
              {
 
728
                double imgY = stretch ?
 
729
                              y + height - borderImgWidth - iLeft * stretchedImgHeight :
 
730
                              y + height - borderImgWidth -
 
731
                              iLeft * (borderImgWidth + borderVertPadding);
 
732
                writeImage(x, imgY, stretchedImgHeight, borderImgWidth,
 
733
                          bi.m_type, bi.m_imgBlob, oneBitColor);
 
734
              }
701
735
            }
702
736
          }
703
737
        }
713
747
      height = strokeCoord.getHeightIn();
714
748
      width = strokeCoord.getWidthIn();
715
749
      graphicsProps.insert("draw:fill", "none");
716
 
      if (info.m_dash.is_initialized() && !info.m_dash.get().m_dots.empty())
 
750
      if (!!info.m_dash && !info.m_dash.get().m_dots.empty())
717
751
      {
718
752
        const Dash &dash = info.m_dash.get();
719
753
        graphicsProps.insert("draw:stroke", "dash");
724
758
          graphicsProps.insert("svg:stroke-linecap", "round");
725
759
          break;
726
760
        case RECT_DOT:
727
 
          graphicsProps.insert("svg:stroke-linecap", "rect");
 
761
          graphicsProps.insert("svg:stroke-linecap", "butt");
728
762
          break;
729
763
        default:
730
764
          break;
734
768
          WPXString dots;
735
769
          dots.sprintf("draw:dots%d", i + 1);
736
770
          graphicsProps.insert(dots.cstr(), static_cast<int>(dash.m_dots[i].m_count));
737
 
          if (dash.m_dots[i].m_length.is_initialized())
 
771
          if (!!dash.m_dots[i].m_length)
738
772
          {
739
773
            WPXString length;
740
774
            length.sprintf("draw:dots%d-length", i + 1);
774
808
    props.insert("fo:padding-top", (double)margins.m_top / EMUS_IN_INCH);
775
809
    props.insert("fo:padding-right", (double)margins.m_right / EMUS_IN_INCH);
776
810
    props.insert("fo:padding-bottom", (double)margins.m_bottom / EMUS_IN_INCH);
777
 
    if(info.m_verticalAlign.is_initialized())
 
811
    if(!!info.m_verticalAlign)
778
812
    {
779
813
      switch (info.m_verticalAlign.get())
780
814
      {
790
824
        break;
791
825
      }
792
826
    }
 
827
    if (info.m_numColumns)
 
828
    {
 
829
      unsigned ncols = info.m_numColumns.get_value_or(0);
 
830
      if (ncols > 0)
 
831
        props.insert("fo:column-count", (int)ncols);
 
832
    }
 
833
    if (info.m_columnSpacing)
 
834
    {
 
835
      unsigned ngap = info.m_columnSpacing;
 
836
      if (ngap > 0)
 
837
        props.insert("fo:column-gap", (double)ngap / EMUS_IN_INCH);
 
838
    }
793
839
    m_painter->startTextObject(props, WPXPropertyListVector());
794
840
    for (unsigned i_lines = 0; i_lines < text.size(); ++i_lines)
795
841
    {
818
864
 
819
865
const char *libmspub::MSPUBCollector::getCalculatedEncoding() const
820
866
{
821
 
  if (m_calculatedEncoding.is_initialized())
 
867
  if (!!m_calculatedEncoding)
822
868
  {
823
869
    return m_calculatedEncoding.get();
824
870
  }
889
935
    boost::optional<Color> oneBitColor) const
890
936
{
891
937
  WPXPropertyList props;
892
 
  if (oneBitColor.is_initialized())
 
938
  if (!!oneBitColor)
893
939
  {
894
940
    Color obc = oneBitColor.get();
895
941
    props.insert("draw:color-mode", "greyscale");
1032
1078
void libmspub::MSPUBCollector::setShapeRotation(unsigned seqNum, double rotation)
1033
1079
{
1034
1080
  m_shapeInfosBySeqNum[seqNum].m_rotation = rotation;
 
1081
  m_shapeInfosBySeqNum[seqNum].m_innerRotation = (int)rotation;
1035
1082
}
1036
1083
 
1037
1084
void libmspub::MSPUBCollector::setShapeFlip(unsigned seqNum, bool flipVertical, bool flipHorizontal)
1108
1155
WPXPropertyList libmspub::MSPUBCollector::getParaStyleProps(const ParagraphStyle &style, boost::optional<unsigned> defaultParaStyleIndex) const
1109
1156
{
1110
1157
  ParagraphStyle _nothing;
1111
 
  const ParagraphStyle &defaultStyle = defaultParaStyleIndex.is_initialized() && defaultParaStyleIndex.get() < m_defaultParaStyles.size() ? m_defaultParaStyles[defaultParaStyleIndex.get()] : _nothing;
 
1158
  const ParagraphStyle &defaultStyle = !!defaultParaStyleIndex && defaultParaStyleIndex.get() < m_defaultParaStyles.size() ? m_defaultParaStyles[defaultParaStyleIndex.get()] : _nothing;
1112
1159
  WPXPropertyList ret;
1113
1160
  Alignment align = style.m_align.get_value_or(
1114
1161
                      defaultStyle.m_align.get_value_or(LEFT));
1147
1194
                             defaultStyle.m_spaceAfterEmu.get_value_or(0));
1148
1195
  unsigned spaceBeforeEmu = style.m_spaceBeforeEmu.get_value_or(
1149
1196
                              defaultStyle.m_spaceBeforeEmu.get_value_or(0));
1150
 
  unsigned firstLineIndentEmu = style.m_firstLineIndentEmu.get_value_or(
1151
 
                                  defaultStyle.m_firstLineIndentEmu.get_value_or(0));
 
1197
  int firstLineIndentEmu = style.m_firstLineIndentEmu.get_value_or(
 
1198
                             defaultStyle.m_firstLineIndentEmu.get_value_or(0));
1152
1199
  unsigned leftIndentEmu = style.m_leftIndentEmu.get_value_or(
1153
1200
                             defaultStyle.m_leftIndentEmu.get_value_or(0));
1154
1201
  unsigned rightIndentEmu = style.m_rightIndentEmu.get_value_or(
1173
1220
  {
1174
1221
    ret.insert("fo:margin-right", (double)rightIndentEmu / EMUS_IN_INCH);
1175
1222
  }
 
1223
  unsigned dropCapLines = style.m_dropCapLines.get_value_or(
 
1224
                            defaultStyle.m_dropCapLines.get_value_or(0));
 
1225
  if (dropCapLines != 0)
 
1226
  {
 
1227
    ret.insert("style:drop-cap", (int)dropCapLines);
 
1228
  }
 
1229
  unsigned dropCapLetters = style.m_dropCapLetters.get_value_or(
 
1230
                              defaultStyle.m_dropCapLetters.get_value_or(0));
 
1231
  if (dropCapLetters != 0)
 
1232
  {
 
1233
    ret.insert("style:length", (int)dropCapLetters);
 
1234
  }
1176
1235
  return ret;
1177
1236
}
1178
1237
 
1179
1238
WPXPropertyList libmspub::MSPUBCollector::getCharStyleProps(const CharacterStyle &style, boost::optional<unsigned> defaultCharStyleIndex) const
1180
1239
{
1181
1240
  CharacterStyle _nothing = CharacterStyle(false, false, false);
1182
 
  if (!defaultCharStyleIndex.is_initialized())
 
1241
  if (!defaultCharStyleIndex)
1183
1242
  {
1184
1243
    defaultCharStyleIndex = 0;
1185
1244
  }
1197
1256
  {
1198
1257
    ret.insert("style:text-underline-type", "single");
1199
1258
  }
1200
 
  if (style.textSizeInPt.is_initialized())
 
1259
  if (!!style.textSizeInPt)
1201
1260
  {
1202
1261
    ret.insert("fo:font-size", style.textSizeInPt.get() / POINTS_IN_INCH);
1203
1262
  }
1204
 
  else if (defaultCharStyle.textSizeInPt.is_initialized())
 
1263
  else if (!!defaultCharStyle.textSizeInPt)
1205
1264
  {
1206
1265
    ret.insert("fo:font-size", defaultCharStyle.textSizeInPt.get()
1207
1266
               / POINTS_IN_INCH);
1218
1277
  {
1219
1278
    ret.insert("fo:color", getColorString(Color(0, 0, 0)));  // default color is black
1220
1279
  }
1221
 
  if (style.fontIndex.is_initialized() &&
 
1280
  if (!!style.fontIndex &&
1222
1281
      style.fontIndex.get() < m_fonts.size())
1223
1282
  {
1224
1283
    WPXString str;
1226
1285
                     getCalculatedEncoding());
1227
1286
    ret.insert("style:font-name", str);
1228
1287
  }
1229
 
  else if (defaultCharStyle.fontIndex.is_initialized() &&
 
1288
  else if (!!defaultCharStyle.fontIndex &&
1230
1289
           defaultCharStyle.fontIndex.get() < m_fonts.size())
1231
1290
  {
1232
1291
    WPXString str;
1316
1375
  {
1317
1376
    m_painter->startGraphics(pageProps);
1318
1377
    boost::optional<unsigned> masterSeqNum = getMasterPageSeqNum(pageSeqNum);
1319
 
    bool hasMaster = masterSeqNum.is_initialized();
 
1378
    bool hasMaster = !!masterSeqNum;
1320
1379
    if (hasMaster)
1321
1380
    {
1322
1381
      writePageBackground(masterSeqNum.get());
1442
1501
 
1443
1502
bool libmspub::MSPUBCollector::addImage(unsigned index, ImgType type, WPXBinaryData img)
1444
1503
{
1445
 
  MSPUB_DEBUG_MSG(("Image at index %d and of type 0x%x added.\n", index, type));
1446
1504
  while (m_images.size() < index)
1447
1505
  {
1448
1506
    m_images.push_back(std::pair<ImgType, WPXBinaryData>(UNKNOWN, WPXBinaryData()));
1449
1507
  }
1450
 
  m_images[index - 1] = std::pair<ImgType, WPXBinaryData>(type, img);
1451
 
  return true;
 
1508
  if (index > 0)
 
1509
  {
 
1510
    MSPUB_DEBUG_MSG(("Image at index %d and of type 0x%x added.\n", index, type));
 
1511
    m_images[index - 1] = std::pair<ImgType, WPXBinaryData>(type, img);
 
1512
  }
 
1513
  else
 
1514
  {
 
1515
    MSPUB_DEBUG_MSG(("0 is not a valid index for image, ignoring.\n"));
 
1516
  }
 
1517
  return index > 0;
1452
1518
}
1453
1519
 
1454
1520
WPXBinaryData *libmspub::MSPUBCollector::addBorderImage(ImgType type,