Blame src/lib/MSPUBCollector.cpp

Packit Service 7605e7
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
Packit Service 7605e7
/*
Packit Service 7605e7
 * This file is part of the libmspub project.
Packit Service 7605e7
 *
Packit Service 7605e7
 * This Source Code Form is subject to the terms of the Mozilla Public
Packit Service 7605e7
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit Service 7605e7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
Packit Service 7605e7
 */
Packit Service 7605e7
Packit Service 7605e7
#include "MSPUBCollector.h"
Packit Service 7605e7
Packit Service 7605e7
#include <algorithm>
Packit Service 7605e7
#include <functional>
Packit Service 7605e7
#include <math.h>
Packit Service 7605e7
#include <memory>
Packit Service 7605e7
Packit Service 7605e7
#include <boost/multi_array.hpp>
Packit Service 7605e7
Packit Service 7605e7
#include <unicode/ucsdet.h>
Packit Service 7605e7
#include <unicode/uloc.h>
Packit Service 7605e7
Packit Service 7605e7
#include "Arrow.h"
Packit Service 7605e7
#include "Coordinate.h"
Packit Service 7605e7
#include "Dash.h"
Packit Service 7605e7
#include "Fill.h"
Packit Service 7605e7
#include "Line.h"
Packit Service 7605e7
#include "Margins.h"
Packit Service 7605e7
#include "MSPUBConstants.h"
Packit Service 7605e7
#include "MSPUBTypes.h"
Packit Service 7605e7
#include "PolygonUtils.h"
Packit Service 7605e7
#include "Shadow.h"
Packit Service 7605e7
#include "ShapeGroupElement.h"
Packit Service 7605e7
#include "TableInfo.h"
Packit Service 7605e7
#include "VectorTransformation2D.h"
Packit Service 7605e7
#include "libmspub_utils.h"
Packit Service 7605e7
Packit Service 7605e7
namespace libmspub
Packit Service 7605e7
{
Packit Service 7605e7
Packit Service 7605e7
using namespace std::placeholders;
Packit Service 7605e7
Packit Service 7605e7
namespace
Packit Service 7605e7
{
Packit Service 7605e7
Packit Service 7605e7
static void separateTabsAndInsertText(librevenge::RVNGDrawingInterface *iface, const librevenge::RVNGString &text)
Packit Service 7605e7
{
Packit Service 7605e7
  if (!iface || text.empty())
Packit Service 7605e7
    return;
Packit Service 7605e7
  librevenge::RVNGString tmpText;
Packit Service 7605e7
  librevenge::RVNGString::Iter i(text);
Packit Service 7605e7
  for (i.rewind(); i.next();)
Packit Service 7605e7
  {
Packit Service 7605e7
    if (*(i()) == '\t')
Packit Service 7605e7
    {
Packit Service 7605e7
      if (!tmpText.empty())
Packit Service 7605e7
      {
Packit Service 7605e7
        if (iface)
Packit Service 7605e7
          iface->insertText(tmpText);
Packit Service 7605e7
        tmpText.clear();
Packit Service 7605e7
      }
Packit Service 7605e7
Packit Service 7605e7
      if (iface)
Packit Service 7605e7
        iface->insertTab();
Packit Service 7605e7
    }
Packit Service 7605e7
    else if (*(i()) == '\n')
Packit Service 7605e7
    {
Packit Service 7605e7
      if (!tmpText.empty())
Packit Service 7605e7
      {
Packit Service 7605e7
        if (iface)
Packit Service 7605e7
          iface->insertText(tmpText);
Packit Service 7605e7
        tmpText.clear();
Packit Service 7605e7
      }
Packit Service 7605e7
Packit Service 7605e7
      if (iface)
Packit Service 7605e7
        iface->insertLineBreak();
Packit Service 7605e7
    }
Packit Service 7605e7
    else
Packit Service 7605e7
    {
Packit Service 7605e7
      tmpText.append(i());
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
  if (iface && !tmpText.empty())
Packit Service 7605e7
    iface->insertText(tmpText);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
static void separateSpacesAndInsertText(librevenge::RVNGDrawingInterface *iface, const librevenge::RVNGString &text)
Packit Service 7605e7
{
Packit Service 7605e7
  if (!iface)
Packit Service 7605e7
    return;
Packit Service 7605e7
  if (text.empty())
Packit Service 7605e7
  {
Packit Service 7605e7
    iface->insertText(text);
Packit Service 7605e7
    return;
Packit Service 7605e7
  }
Packit Service 7605e7
  librevenge::RVNGString tmpText;
Packit Service 7605e7
  int numConsecutiveSpaces = 0;
Packit Service 7605e7
  librevenge::RVNGString::Iter i(text);
Packit Service 7605e7
  for (i.rewind(); i.next();)
Packit Service 7605e7
  {
Packit Service 7605e7
    if (*(i()) == ' ')
Packit Service 7605e7
      numConsecutiveSpaces++;
Packit Service 7605e7
    else
Packit Service 7605e7
      numConsecutiveSpaces = 0;
Packit Service 7605e7
Packit Service 7605e7
    if (numConsecutiveSpaces > 1)
Packit Service 7605e7
    {
Packit Service 7605e7
      if (!tmpText.empty())
Packit Service 7605e7
      {
Packit Service 7605e7
        separateTabsAndInsertText(iface, tmpText);
Packit Service 7605e7
        tmpText.clear();
Packit Service 7605e7
      }
Packit Service 7605e7
Packit Service 7605e7
      if (iface)
Packit Service 7605e7
        iface->insertSpace();
Packit Service 7605e7
    }
Packit Service 7605e7
    else
Packit Service 7605e7
    {
Packit Service 7605e7
      tmpText.append(i());
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
  separateTabsAndInsertText(iface, tmpText);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
struct TableLayoutCell
Packit Service 7605e7
{
Packit Service 7605e7
  TableLayoutCell()
Packit Service 7605e7
    : m_cell(0)
Packit Service 7605e7
    , m_rowSpan(0)
Packit Service 7605e7
    , m_colSpan(0)
Packit Service 7605e7
  {
Packit Service 7605e7
  }
Packit Service 7605e7
Packit Service 7605e7
  unsigned m_cell;
Packit Service 7605e7
  unsigned m_rowSpan;
Packit Service 7605e7
  unsigned m_colSpan;
Packit Service 7605e7
};
Packit Service 7605e7
Packit Service 7605e7
bool isCovered(const TableLayoutCell &cell)
Packit Service 7605e7
{
Packit Service 7605e7
  assert((cell.m_rowSpan == 0) == (cell.m_colSpan == 0));
Packit Service 7605e7
  return (cell.m_rowSpan == 0) && (cell.m_colSpan == 0);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
typedef boost::multi_array<TableLayoutCell, 2> TableLayout;
Packit Service 7605e7
Packit Service 7605e7
void createTableLayout(const std::vector<CellInfo> &cells, TableLayout &tableLayout)
Packit Service 7605e7
{
Packit Service 7605e7
  for (auto it = cells.begin(); it != cells.end(); ++it)
Packit Service 7605e7
  {
Packit Service 7605e7
    if ((it->m_endRow >= tableLayout.shape()[0]) || (it->m_endColumn >= tableLayout.shape()[1]))
Packit Service 7605e7
    {
Packit Service 7605e7
      MSPUB_DEBUG_MSG((
Packit Service 7605e7
                        "cell %u (rows %u to %u, columns %u to %u) overflows the table, ignoring\n",
Packit Service 7605e7
                        unsigned(int(it - cells.begin())),
Packit Service 7605e7
                        it->m_startRow, it->m_endRow,
Packit Service 7605e7
                        it->m_startColumn, it->m_endColumn
Packit Service 7605e7
                      ));
Packit Service 7605e7
      continue;
Packit Service 7605e7
    }
Packit Service 7605e7
    if (it->m_startRow > it->m_endRow)
Packit Service 7605e7
    {
Packit Service 7605e7
      MSPUB_DEBUG_MSG((
Packit Service 7605e7
                        "cell %u (rows %u to %u) has got negative row span, ignoring\n",
Packit Service 7605e7
                        unsigned(int(it - cells.begin())),
Packit Service 7605e7
                        it->m_startRow, it->m_endRow
Packit Service 7605e7
                      ));
Packit Service 7605e7
      continue;
Packit Service 7605e7
    }
Packit Service 7605e7
    if (it->m_startColumn > it->m_endColumn)
Packit Service 7605e7
    {
Packit Service 7605e7
      MSPUB_DEBUG_MSG((
Packit Service 7605e7
                        "cell %u (columns %u to %u) has got negative column span, ignoring\n",
Packit Service 7605e7
                        unsigned(int(it - cells.begin())),
Packit Service 7605e7
                        it->m_startColumn, it->m_endColumn
Packit Service 7605e7
                      ));
Packit Service 7605e7
      continue;
Packit Service 7605e7
    }
Packit Service 7605e7
Packit Service 7605e7
    const unsigned rowSpan = it->m_endRow - it->m_startRow + 1;
Packit Service 7605e7
    const unsigned colSpan = it->m_endColumn - it->m_startColumn + 1;
Packit Service 7605e7
Packit Service 7605e7
    if ((rowSpan == 0) != (colSpan == 0))
Packit Service 7605e7
    {
Packit Service 7605e7
      MSPUB_DEBUG_MSG((
Packit Service 7605e7
                        "cell %u (rows %u to %u, columns %u to %u) has got 0 span in one dimension, ignoring\n",
Packit Service 7605e7
                        unsigned(int(it - cells.begin())),
Packit Service 7605e7
                        it->m_startRow, it->m_endRow,
Packit Service 7605e7
                        it->m_startColumn, it->m_endColumn
Packit Service 7605e7
                      ));
Packit Service 7605e7
      continue;
Packit Service 7605e7
    }
Packit Service 7605e7
Packit Service 7605e7
    TableLayoutCell &layoutCell = tableLayout[it->m_startRow][it->m_startColumn];
Packit Service 7605e7
    layoutCell.m_cell = unsigned(int(it - cells.begin()));
Packit Service 7605e7
    layoutCell.m_rowSpan = rowSpan;
Packit Service 7605e7
    layoutCell.m_colSpan = colSpan;
Packit Service 7605e7
  }
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
typedef std::vector<std::pair<unsigned, unsigned> > ParagraphToCellMap_t;
Packit Service 7605e7
typedef std::vector<librevenge::RVNGString> SpanTexts_t;
Packit Service 7605e7
typedef std::vector<SpanTexts_t> ParagraphTexts_t;
Packit Service 7605e7
Packit Service 7605e7
void mapTableTextToCells(
Packit Service 7605e7
  const std::vector<TextParagraph> &text,
Packit Service 7605e7
  const std::vector<unsigned> &tableCellTextEnds,
Packit Service 7605e7
  const char *const encoding,
Packit Service 7605e7
  ParagraphToCellMap_t &paraToCellMap,
Packit Service 7605e7
  ParagraphTexts_t &paraTexts
Packit Service 7605e7
)
Packit Service 7605e7
{
Packit Service 7605e7
  assert(paraToCellMap.empty());
Packit Service 7605e7
  assert(paraTexts.empty());
Packit Service 7605e7
Packit Service 7605e7
  paraToCellMap.reserve(tableCellTextEnds.size());
Packit Service 7605e7
  paraTexts.reserve(tableCellTextEnds.size());
Packit Service 7605e7
Packit Service 7605e7
  unsigned firstPara = 0;
Packit Service 7605e7
  unsigned offset = 1;
Packit Service 7605e7
  for (unsigned para = 0; para != text.size() && paraToCellMap.size() < tableCellTextEnds.size(); ++para)
Packit Service 7605e7
  {
Packit Service 7605e7
    paraTexts.push_back(SpanTexts_t());
Packit Service 7605e7
    paraTexts.back().reserve(text[para].spans.size());
Packit Service 7605e7
Packit Service 7605e7
    for (unsigned i_spans = 0; i_spans != text[para].spans.size(); ++i_spans)
Packit Service 7605e7
    {
Packit Service 7605e7
      librevenge::RVNGString textString;
Packit Service 7605e7
      appendCharacters(textString, text[para].spans[i_spans].chars, encoding);
Packit Service 7605e7
      offset += textString.len();
Packit Service 7605e7
      // TODO: why do we not drop these during parse already?
Packit Service 7605e7
      if ((i_spans == text[para].spans.size() - 1) && (textString == "\r"))
Packit Service 7605e7
        continue;
Packit Service 7605e7
      paraTexts.back().push_back(textString);
Packit Service 7605e7
    }
Packit Service 7605e7
Packit Service 7605e7
    assert(paraTexts.back().size() <= text[para].spans.size());
Packit Service 7605e7
Packit Service 7605e7
    if (offset >= tableCellTextEnds[paraToCellMap.size()])
Packit Service 7605e7
    {
Packit Service 7605e7
      if (offset > tableCellTextEnds[paraToCellMap.size()])
Packit Service 7605e7
      {
Packit Service 7605e7
        MSPUB_DEBUG_MSG(("text of cell %u ends in the middle of a paragraph!\n", unsigned(paraToCellMap.size())));
Packit Service 7605e7
      }
Packit Service 7605e7
Packit Service 7605e7
      paraToCellMap.push_back(std::make_pair(firstPara, para));
Packit Service 7605e7
      firstPara = para + 1;
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
Packit Service 7605e7
  assert(paraTexts.size() == text.size());
Packit Service 7605e7
  assert(paraToCellMap.size() <= tableCellTextEnds.size());
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void fillUnderline(librevenge::RVNGPropertyList &props, const Underline underline)
Packit Service 7605e7
{
Packit Service 7605e7
  switch (underline)
Packit Service 7605e7
  {
Packit Service 7605e7
  case Underline::None:
Packit Service 7605e7
    return;
Packit Service 7605e7
  case Underline::Single:
Packit Service 7605e7
  case Underline::WordsOnly:
Packit Service 7605e7
  case Underline::Double:
Packit Service 7605e7
  case Underline::Thick:
Packit Service 7605e7
    props.insert("style:text-underline-style", "solid");
Packit Service 7605e7
    break;
Packit Service 7605e7
  case Underline::Dotted:
Packit Service 7605e7
  case Underline::ThickDot:
Packit Service 7605e7
    props.insert("style:text-underline-style", "dotted");
Packit Service 7605e7
    break;
Packit Service 7605e7
  case Underline::Dash:
Packit Service 7605e7
  case Underline::ThickDash:
Packit Service 7605e7
    props.insert("style:text-underline-style", "dash");
Packit Service 7605e7
    break;
Packit Service 7605e7
  case Underline::DotDash:
Packit Service 7605e7
  case Underline::ThickDotDash:
Packit Service 7605e7
    props.insert("style:text-underline-style", "dot-dash");
Packit Service 7605e7
    break;
Packit Service 7605e7
  case Underline::DotDotDash:
Packit Service 7605e7
  case Underline::ThickDotDotDash:
Packit Service 7605e7
    props.insert("style:text-underline-style", "dot-dot-dash");
Packit Service 7605e7
    break;
Packit Service 7605e7
  case Underline::Wave:
Packit Service 7605e7
  case Underline::ThickWave:
Packit Service 7605e7
  case Underline::DoubleWave:
Packit Service 7605e7
    props.insert("style:text-underline-style", "wave");
Packit Service 7605e7
    break;
Packit Service 7605e7
  case Underline::LongDash:
Packit Service 7605e7
  case Underline::ThickLongDash:
Packit Service 7605e7
    props.insert("style:text-underline-style", "long-dash");
Packit Service 7605e7
    break;
Packit Service 7605e7
  }
Packit Service 7605e7
Packit Service 7605e7
  switch (underline)
Packit Service 7605e7
  {
Packit Service 7605e7
  case Underline::Double:
Packit Service 7605e7
  case Underline::DoubleWave:
Packit Service 7605e7
    props.insert("style:text-underline-type", "double");
Packit Service 7605e7
    break;
Packit Service 7605e7
  default:
Packit Service 7605e7
    props.insert("style:text-underline-type", "single");
Packit Service 7605e7
    break;
Packit Service 7605e7
  }
Packit Service 7605e7
Packit Service 7605e7
  switch (underline)
Packit Service 7605e7
  {
Packit Service 7605e7
  case Underline::Thick:
Packit Service 7605e7
  case Underline::ThickWave:
Packit Service 7605e7
  case Underline::ThickDot:
Packit Service 7605e7
  case Underline::ThickDash:
Packit Service 7605e7
  case Underline::ThickDotDash:
Packit Service 7605e7
  case Underline::ThickDotDotDash:
Packit Service 7605e7
    props.insert("style:text-underline-width", "bold");
Packit Service 7605e7
    break;
Packit Service 7605e7
  default:
Packit Service 7605e7
    props.insert("style:text-underline-width", "auto");
Packit Service 7605e7
    break;
Packit Service 7605e7
  }
Packit Service 7605e7
Packit Service 7605e7
  switch (underline)
Packit Service 7605e7
  {
Packit Service 7605e7
  case Underline::WordsOnly:
Packit Service 7605e7
    props.insert("style:text-underline-mode", "skip-white-space");
Packit Service 7605e7
    break;
Packit Service 7605e7
  default:
Packit Service 7605e7
    props.insert("style:text-underline-mode", "continuous");
Packit Service 7605e7
    break;
Packit Service 7605e7
  }
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void fillLocale(librevenge::RVNGPropertyList &props, const unsigned lcid)
Packit Service 7605e7
{
Packit Service 7605e7
  char locale[ULOC_FULLNAME_CAPACITY];
Packit Service 7605e7
  UErrorCode status = U_ZERO_ERROR;
Packit Service 7605e7
  uloc_getLocaleForLCID(lcid, locale, ULOC_FULLNAME_CAPACITY, &status);
Packit Service 7605e7
  if (!U_SUCCESS(status))
Packit Service 7605e7
    return;
Packit Service 7605e7
  char component[ULOC_FULLNAME_CAPACITY];
Packit Service 7605e7
  int32_t len = uloc_getLanguage(locale, component, ULOC_FULLNAME_CAPACITY, &status);
Packit Service 7605e7
  if (U_SUCCESS(status) && len > 0)
Packit Service 7605e7
    props.insert("fo:language", component);
Packit Service 7605e7
  len = uloc_getCountry(locale, component, ULOC_FULLNAME_CAPACITY, &status);
Packit Service 7605e7
  if (U_SUCCESS(status) && len > 0)
Packit Service 7605e7
    props.insert("fo:country", component);
Packit Service 7605e7
  len = uloc_getScript(locale, component, ULOC_FULLNAME_CAPACITY, &status);
Packit Service 7605e7
  if (U_SUCCESS(status) && len > 0)
Packit Service 7605e7
    props.insert("fo:script", component);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
} // anonymous namespace
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::collectMetaData(const librevenge::RVNGPropertyList &metaData)
Packit Service 7605e7
{
Packit Service 7605e7
  m_metaData = metaData;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::addEOTFont(const librevenge::RVNGString &name, const librevenge::RVNGBinaryData &data)
Packit Service 7605e7
{
Packit Service 7605e7
  m_embeddedFonts.push_back(EmbeddedFontInfo(name, data));
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapePictureRecolor(unsigned seqNum,
Packit Service 7605e7
                                            const ColorReference &recolor)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_pictureRecolor = recolor;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapePictureBrightness(unsigned seqNum,
Packit Service 7605e7
                                               int brightness)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_pictureBrightness = brightness;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapePictureContrast(unsigned seqNum,
Packit Service 7605e7
                                             int contrast)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_pictureContrast = contrast;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeBeginArrow(unsigned seqNum,
Packit Service 7605e7
                                        const Arrow &arrow)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_beginArrow = arrow;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeVerticalTextAlign(unsigned seqNum,
Packit Service 7605e7
                                               VerticalAlign va)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_verticalAlign = va;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeEndArrow(unsigned seqNum,
Packit Service 7605e7
                                      const Arrow &arrow)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_endArrow = arrow;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeTableInfo(unsigned seqNum,
Packit Service 7605e7
                                       const TableInfo &ti)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_tableInfo = ti;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeNumColumns(unsigned seqNum,
Packit Service 7605e7
                                        unsigned numColumns)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_numColumns = numColumns;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeColumnSpacing(unsigned seqNum,
Packit Service 7605e7
                                           unsigned spacing)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_columnSpacing = spacing;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeStretchBorderArt(unsigned seqNum)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_stretchBorderArt = true;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setRectCoordProps(Coordinate coord, librevenge::RVNGPropertyList *props) const
Packit Service 7605e7
{
Packit Service 7605e7
  props->insert("svg:x", coord.getXIn(m_width));
Packit Service 7605e7
  props->insert("svg:y", coord.getYIn(m_height));
Packit Service 7605e7
  props->insert("svg:width", coord.getWidthIn());
Packit Service 7605e7
  props->insert("svg:height", coord.getHeightIn());
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
Coordinate getFudgedCoordinates(Coordinate coord, const std::vector<Line> &lines, bool makeBigger, BorderPosition borderPosition)
Packit Service 7605e7
{
Packit Service 7605e7
  Coordinate fudged = coord;
Packit Service 7605e7
  unsigned topFudge = 0;
Packit Service 7605e7
  unsigned rightFudge = 0;
Packit Service 7605e7
  unsigned bottomFudge = 0;
Packit Service 7605e7
  unsigned leftFudge = 0;
Packit Service 7605e7
  switch (borderPosition)
Packit Service 7605e7
  {
Packit Service 7605e7
  case HALF_INSIDE_SHAPE:
Packit Service 7605e7
    topFudge = (!lines.empty()) ? lines[0].m_widthInEmu / 2 : 0;
Packit Service 7605e7
    rightFudge = (lines.size() > 1) ? lines[1].m_widthInEmu / 2 : 0;
Packit Service 7605e7
    bottomFudge = (lines.size() > 2) ? lines[2].m_widthInEmu / 2 : 0;
Packit Service 7605e7
    leftFudge = (lines.size() > 3) ? lines[3].m_widthInEmu / 2 : 0;
Packit Service 7605e7
    break;
Packit Service 7605e7
  case OUTSIDE_SHAPE:
Packit Service 7605e7
    topFudge = (!lines.empty()) ? lines[0].m_widthInEmu : 0;
Packit Service 7605e7
    rightFudge = (lines.size() > 1) ? lines[1].m_widthInEmu : 0;
Packit Service 7605e7
    bottomFudge = (lines.size() > 2) ? lines[2].m_widthInEmu : 0;
Packit Service 7605e7
    leftFudge = (lines.size() > 3) ? lines[3].m_widthInEmu : 0;
Packit Service 7605e7
    break;
Packit Service 7605e7
  case INSIDE_SHAPE:
Packit Service 7605e7
  default:
Packit Service 7605e7
    break;
Packit Service 7605e7
  }
Packit Service 7605e7
  if (makeBigger)
Packit Service 7605e7
  {
Packit Service 7605e7
    fudged.m_xs -= leftFudge;
Packit Service 7605e7
    fudged.m_xe += rightFudge;
Packit Service 7605e7
    fudged.m_ys -= topFudge;
Packit Service 7605e7
    fudged.m_ye += bottomFudge;
Packit Service 7605e7
  }
Packit Service 7605e7
  else
Packit Service 7605e7
  {
Packit Service 7605e7
    fudged.m_xs += leftFudge;
Packit Service 7605e7
    fudged.m_xe -= rightFudge;
Packit Service 7605e7
    fudged.m_ys += topFudge;
Packit Service 7605e7
    fudged.m_ye -= bottomFudge;
Packit Service 7605e7
  }
Packit Service 7605e7
  return fudged;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setNextPage(unsigned pageSeqNum)
Packit Service 7605e7
{
Packit Service 7605e7
  m_pageSeqNumsOrdered.push_back(pageSeqNum);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
MSPUBCollector::MSPUBCollector(librevenge::RVNGDrawingInterface *painter) :
Packit Service 7605e7
  m_painter(painter), m_contentChunkReferences(), m_width(0), m_height(0),
Packit Service 7605e7
  m_widthSet(false), m_heightSet(false),
Packit Service 7605e7
  m_numPages(0), m_textStringsById(), m_pagesBySeqNum(),
Packit Service 7605e7
  m_images(), m_borderImages(),
Packit Service 7605e7
  m_textColors(), m_fonts(),
Packit Service 7605e7
  m_defaultCharStyles(), m_defaultParaStyles(), m_shapeTypesBySeqNum(),
Packit Service 7605e7
  m_paletteColors(), m_shapeSeqNumsOrdered(),
Packit Service 7605e7
  m_pageSeqNumsByShapeSeqNum(), m_bgShapeSeqNumsByPageSeqNum(),
Packit Service 7605e7
  m_skipIfNotBgSeqNums(),
Packit Service 7605e7
  m_currentShapeGroup(), m_topLevelShapes(),
Packit Service 7605e7
  m_groupsBySeqNum(), m_embeddedFonts(),
Packit Service 7605e7
  m_shapeInfosBySeqNum(), m_masterPages(),
Packit Service 7605e7
  m_shapesWithCoordinatesRotated90(),
Packit Service 7605e7
  m_masterPagesByPageSeqNum(),
Packit Service 7605e7
  m_tableCellTextEndsByTextId(), m_stringOffsetsByTextId(),
Packit Service 7605e7
  m_calculationValuesSeen(), m_pageSeqNumsOrdered(),
Packit Service 7605e7
  m_encodingHeuristic(false), m_allText(),
Packit Service 7605e7
  m_calculatedEncoding(),
Packit Service 7605e7
  m_metaData()
Packit Service 7605e7
{
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setTextStringOffset(
Packit Service 7605e7
  unsigned textId, unsigned offset)
Packit Service 7605e7
{
Packit Service 7605e7
  m_stringOffsetsByTextId[textId] = offset;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setTableCellTextEnds(
Packit Service 7605e7
  const unsigned textId, const std::vector<unsigned> &ends)
Packit Service 7605e7
{
Packit Service 7605e7
  m_tableCellTextEndsByTextId[textId] = ends;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::useEncodingHeuristic()
Packit Service 7605e7
{
Packit Service 7605e7
  m_encodingHeuristic = true;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeShadow(unsigned seqNum, const Shadow &shadow)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_shadow = shadow;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void noop(const CustomShape *)
Packit Service 7605e7
{
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeCoordinatesRotated90(unsigned seqNum)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapesWithCoordinatesRotated90.insert(seqNum);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeBorderImageId(unsigned seqNum, unsigned id)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_borderImgIndex = id;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeCustomPath(unsigned seqNum,
Packit Service 7605e7
                                        const DynamicCustomShape &shape)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_customShape = shape;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeClipPath(unsigned seqNum, const std::vector<Vertex> &clip)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_clipPath = clip;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::beginGroup()
Packit Service 7605e7
{
Packit Service 7605e7
  auto tmp = ShapeGroupElement::create(m_currentShapeGroup);
Packit Service 7605e7
  if (!m_currentShapeGroup)
Packit Service 7605e7
  {
Packit Service 7605e7
    m_topLevelShapes.push_back(tmp);
Packit Service 7605e7
  }
Packit Service 7605e7
  m_currentShapeGroup = tmp;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
bool MSPUBCollector::endGroup()
Packit Service 7605e7
{
Packit Service 7605e7
  if (!m_currentShapeGroup)
Packit Service 7605e7
  {
Packit Service 7605e7
    return false;
Packit Service 7605e7
  }
Packit Service 7605e7
  m_currentShapeGroup = m_currentShapeGroup->getParent();
Packit Service 7605e7
  return true;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::addShapeLine(unsigned seqNum, Line line)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_lines.push_back(line);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeBorderPosition(unsigned seqNum, BorderPosition pos)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_borderPosition = pos;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
bool MSPUBCollector::hasPage(unsigned seqNum) const
Packit Service 7605e7
{
Packit Service 7605e7
  return m_pagesBySeqNum.find(seqNum) != m_pagesBySeqNum.end();
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeMargins(unsigned seqNum, unsigned left, unsigned top, unsigned right, unsigned bottom)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_margins = Margins(left, top, right, bottom);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setPageBgShape(unsigned pageSeqNum, unsigned seqNum)
Packit Service 7605e7
{
Packit Service 7605e7
  m_bgShapeSeqNumsByPageSeqNum[pageSeqNum] = seqNum;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
bool MSPUBCollector::setCurrentGroupSeqNum(unsigned seqNum)
Packit Service 7605e7
{
Packit Service 7605e7
  if (!m_currentShapeGroup)
Packit Service 7605e7
  {
Packit Service 7605e7
    return false;
Packit Service 7605e7
  }
Packit Service 7605e7
  m_currentShapeGroup->setSeqNum(seqNum);
Packit Service 7605e7
  m_groupsBySeqNum.insert(std::make_pair(seqNum, m_currentShapeGroup));
Packit Service 7605e7
  return true;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeOrder(unsigned seqNum)
Packit Service 7605e7
{
Packit Service 7605e7
  auto tmp = ShapeGroupElement::create(m_currentShapeGroup, seqNum);
Packit Service 7605e7
  if (!m_currentShapeGroup)
Packit Service 7605e7
  {
Packit Service 7605e7
    m_topLevelShapes.push_back(tmp);
Packit Service 7605e7
  }
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::addPaletteColor(Color c)
Packit Service 7605e7
{
Packit Service 7605e7
  m_paletteColors.push_back(c);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void no_op()
Packit Service 7605e7
{
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void endShapeGroup(librevenge::RVNGDrawingInterface *painter)
Packit Service 7605e7
{
Packit Service 7605e7
  painter->endLayer();
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
std::vector<int> MSPUBCollector::getShapeAdjustValues(const ShapeInfo &info) const
Packit Service 7605e7
{
Packit Service 7605e7
  std::vector<int> ret;
Packit Service 7605e7
  std::shared_ptr<const CustomShape> ptr_shape = info.getCustomShape();
Packit Service 7605e7
  if (ptr_shape)
Packit Service 7605e7
  {
Packit Service 7605e7
    for (unsigned i = 0; i < ptr_shape->m_numDefaultAdjustValues; ++i)
Packit Service 7605e7
    {
Packit Service 7605e7
      ret.push_back(ptr_shape->mp_defaultAdjustValues[i]);
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
  for (auto i = info.m_adjustValuesByIndex.begin(); i != info.m_adjustValuesByIndex.end(); ++i)
Packit Service 7605e7
  {
Packit Service 7605e7
    unsigned index = i->first;
Packit Service 7605e7
    int adjustVal = i->second;
Packit Service 7605e7
    for (unsigned j = info.m_adjustValues.size(); j <= index; ++j)
Packit Service 7605e7
    {
Packit Service 7605e7
      ret.push_back(0);
Packit Service 7605e7
    }
Packit Service 7605e7
    ret[index] = adjustVal;
Packit Service 7605e7
  }
Packit Service 7605e7
  return ret;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
boost::optional<std::vector<TextParagraph> > MSPUBCollector::getShapeText(const ShapeInfo &info) const
Packit Service 7605e7
{
Packit Service 7605e7
  if (bool(info.m_textId))
Packit Service 7605e7
  {
Packit Service 7605e7
    unsigned stringId = info.m_textId.get();
Packit Service 7605e7
    const std::vector<TextParagraph> *ptr_str = getIfExists_const(m_textStringsById, stringId);
Packit Service 7605e7
    if (ptr_str)
Packit Service 7605e7
    {
Packit Service 7605e7
      return *ptr_str;
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
  return boost::optional<std::vector<TextParagraph> >();
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setupShapeStructures(ShapeGroupElement &elt)
Packit Service 7605e7
{
Packit Service 7605e7
  ShapeInfo *ptr_info = getIfExists(m_shapeInfosBySeqNum, elt.getSeqNum());
Packit Service 7605e7
  if (ptr_info)
Packit Service 7605e7
  {
Packit Service 7605e7
    if (bool(ptr_info->m_imgIndex))
Packit Service 7605e7
    {
Packit Service 7605e7
      unsigned index = ptr_info->m_imgIndex.get();
Packit Service 7605e7
      int rot = 0;
Packit Service 7605e7
      if (bool(ptr_info->m_innerRotation))
Packit Service 7605e7
        rot = ptr_info->m_innerRotation.get();
Packit Service 7605e7
      if (index - 1 < m_images.size())
Packit Service 7605e7
      {
Packit Service 7605e7
        ptr_info->m_fill = std::shared_ptr<const Fill>(new ImgFill(index, this, false, rot));
Packit Service 7605e7
      }
Packit Service 7605e7
    }
Packit Service 7605e7
    elt.setShapeInfo(*ptr_info);
Packit Service 7605e7
    std::pair<bool, bool> flips = ptr_info->m_flips.get_value_or(std::pair<bool, bool>(false, false));
Packit Service 7605e7
    VectorTransformation2D flipsTransform = VectorTransformation2D::fromFlips(flips.second, flips.first);
Packit Service 7605e7
    double rotation = ptr_info->m_rotation.get_value_or(0);
Packit Service 7605e7
    rotation = doubleModulo(rotation, 360);
Packit Service 7605e7
    bool rotBackwards = flips.first ^ flips.second;
Packit Service 7605e7
    VectorTransformation2D rot = VectorTransformation2D::fromCounterRadians((rotBackwards ? -rotation : rotation) * M_PI / 180);
Packit Service 7605e7
    elt.setTransform(rot * flipsTransform);
Packit Service 7605e7
  }
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
Packit Service 7605e7
std::function<void(void)> MSPUBCollector::paintShape(const ShapeInfo &info, const Coordinate &/* relativeTo*/, const VectorTransformation2D &foldedTransform, bool isGroup, const VectorTransformation2D &thisTransform) const
Packit Service 7605e7
{
Packit Service 7605e7
  std::vector<int> adjustValues = getShapeAdjustValues(info);
Packit Service 7605e7
  if (isGroup)
Packit Service 7605e7
  {
Packit Service 7605e7
    m_painter->startLayer(librevenge::RVNGPropertyList());
Packit Service 7605e7
    return std::bind(&endShapeGroup, m_painter);
Packit Service 7605e7
  }
Packit Service 7605e7
  librevenge::RVNGPropertyList graphicsProps;
Packit Service 7605e7
  if (info.m_fill)
Packit Service 7605e7
  {
Packit Service 7605e7
    info.m_fill->getProperties(&graphicsProps);
Packit Service 7605e7
  }
Packit Service 7605e7
  bool hasStroke = false;
Packit Service 7605e7
  bool hasBorderArt = false;
Packit Service 7605e7
  boost::optional<unsigned> maybeBorderImg = info.m_borderImgIndex;
Packit Service 7605e7
  if (bool(maybeBorderImg) && !info.m_lines.empty())
Packit Service 7605e7
  {
Packit Service 7605e7
    hasStroke = true;
Packit Service 7605e7
    hasBorderArt = true;
Packit Service 7605e7
  }
Packit Service 7605e7
  else
Packit Service 7605e7
  {
Packit Service 7605e7
    for (const auto &line : info.m_lines)
Packit Service 7605e7
    {
Packit Service 7605e7
      hasStroke = hasStroke || line.m_lineExists;
Packit Service 7605e7
      if (hasStroke)
Packit Service 7605e7
      {
Packit Service 7605e7
        break;
Packit Service 7605e7
      }
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
  librevenge::RVNGString fill = graphicsProps["draw:fill"] ? graphicsProps["draw:fill"]->getStr() : "none";
Packit Service 7605e7
  bool hasFill = fill != "none";
Packit Service 7605e7
  boost::optional<std::vector<TextParagraph> > maybeText = getShapeText(info);
Packit Service 7605e7
  auto hasText = bool(maybeText);
Packit Service 7605e7
  const auto isTable = bool(info.m_tableInfo);
Packit Service 7605e7
  bool makeLayer = hasBorderArt ||
Packit Service 7605e7
                   (hasStroke && hasFill) || (hasStroke && hasText) || (hasFill && hasText);
Packit Service 7605e7
  if (makeLayer)
Packit Service 7605e7
  {
Packit Service 7605e7
    if (info.m_clipPath.size() > 0)
Packit Service 7605e7
    {
Packit Service 7605e7
      const Coordinate coord = info.m_coordinates.get_value_or(Coordinate());
Packit Service 7605e7
      double x, y, height, width;
Packit Service 7605e7
      x = coord.getXIn(m_width);
Packit Service 7605e7
      y = coord.getYIn(m_height);
Packit Service 7605e7
      height = coord.getHeightIn();
Packit Service 7605e7
      width = coord.getWidthIn();
Packit Service 7605e7
      m_painter->startLayer(calcClipPath(info.m_clipPath, x, y, height, width, foldedTransform, info.getCustomShape()));
Packit Service 7605e7
    }
Packit Service 7605e7
    else
Packit Service 7605e7
      m_painter->startLayer(librevenge::RVNGPropertyList());
Packit Service 7605e7
  }
Packit Service 7605e7
  graphicsProps.insert("draw:stroke", "none");
Packit Service 7605e7
  const Coordinate coord = info.m_coordinates.get_value_or(Coordinate());
Packit Service 7605e7
  BorderPosition borderPosition =
Packit Service 7605e7
    hasBorderArt ? INSIDE_SHAPE : info.m_borderPosition.get_value_or(HALF_INSIDE_SHAPE);
Packit Service 7605e7
  ShapeType type;
Packit Service 7605e7
  if (bool(info.m_cropType))
Packit Service 7605e7
  {
Packit Service 7605e7
    type = info.m_cropType.get();
Packit Service 7605e7
  }
Packit Service 7605e7
  else
Packit Service 7605e7
  {
Packit Service 7605e7
    type = info.m_type.get_value_or(RECTANGLE);
Packit Service 7605e7
  }
Packit Service 7605e7
Packit Service 7605e7
  if (hasFill)
Packit Service 7605e7
  {
Packit Service 7605e7
    double x, y, height, width;
Packit Service 7605e7
    x = coord.getXIn(m_width);
Packit Service 7605e7
    y = coord.getYIn(m_height);
Packit Service 7605e7
    height = coord.getHeightIn();
Packit Service 7605e7
    width = coord.getWidthIn();
Packit Service 7605e7
    if (hasBorderArt)
Packit Service 7605e7
    {
Packit Service 7605e7
      double borderImgWidth =
Packit Service 7605e7
        static_cast<double>(info.m_lines[0].m_widthInEmu) / EMUS_IN_INCH;
Packit Service 7605e7
      if (height > 2 * borderImgWidth && width >= 2 * borderImgWidth)
Packit Service 7605e7
      {
Packit Service 7605e7
        x += borderImgWidth;
Packit Service 7605e7
        y += borderImgWidth;
Packit Service 7605e7
        height -= 2 * borderImgWidth;
Packit Service 7605e7
        width -= 2 * borderImgWidth;
Packit Service 7605e7
      }
Packit Service 7605e7
    }
Packit Service 7605e7
    if (bool(info.m_pictureRecolor))
Packit Service 7605e7
    {
Packit Service 7605e7
      Color obc = info.m_pictureRecolor.get().getFinalColor(m_paletteColors);
Packit Service 7605e7
      graphicsProps.insert("draw:color-mode", "greyscale");
Packit Service 7605e7
      graphicsProps.insert("draw:red",
Packit Service 7605e7
                           static_cast<double>(obc.r) / 255.0, librevenge::RVNG_PERCENT);
Packit Service 7605e7
      graphicsProps.insert("draw:blue",
Packit Service 7605e7
                           static_cast<double>(obc.b) / 255.0, librevenge::RVNG_PERCENT);
Packit Service 7605e7
      graphicsProps.insert("draw:green",
Packit Service 7605e7
                           static_cast<double>(obc.g) / 255.0, librevenge::RVNG_PERCENT);
Packit Service 7605e7
    }
Packit Service 7605e7
    if (bool(info.m_pictureBrightness))
Packit Service 7605e7
      graphicsProps.insert("draw:luminance", static_cast<double>(info.m_pictureBrightness.get() + 32768.0) / 65536.0, librevenge::RVNG_PERCENT);
Packit Service 7605e7
    bool shadowPropsInserted = false;
Packit Service 7605e7
    if (bool(info.m_shadow))
Packit Service 7605e7
    {
Packit Service 7605e7
      const Shadow &s = info.m_shadow.get();
Packit Service 7605e7
      if (!needsEmulation(s))
Packit Service 7605e7
      {
Packit Service 7605e7
        shadowPropsInserted = true;
Packit Service 7605e7
        graphicsProps.insert("draw:shadow", "visible");
Packit Service 7605e7
        graphicsProps.insert("draw:shadow-offset-x", static_cast<double>(s.m_offsetXInEmu) / EMUS_IN_INCH);
Packit Service 7605e7
        graphicsProps.insert("draw:shadow-offset-y", static_cast<double>(s.m_offsetYInEmu) / EMUS_IN_INCH);
Packit Service 7605e7
        graphicsProps.insert("draw:shadow-color", getColorString(s.m_color.getFinalColor(m_paletteColors)));
Packit Service 7605e7
        graphicsProps.insert("draw:shadow-opacity", s.m_opacity, librevenge::RVNG_PERCENT);
Packit Service 7605e7
      }
Packit Service 7605e7
      // TODO: Emulate shadows that don't conform
Packit Service 7605e7
      // to LibreOffice's range of possible shadows.
Packit Service 7605e7
    }
Packit Service 7605e7
    m_painter->setStyle(graphicsProps);
Packit Service 7605e7
Packit Service 7605e7
    writeCustomShape(type, graphicsProps, m_painter, x, y, height, width,
Packit Service 7605e7
                     true, foldedTransform,
Packit Service 7605e7
                     std::vector<Line>(), std::bind(&MSPUBCollector::getCalculationValue, this, info, _1, false, adjustValues), m_paletteColors, info.getCustomShape());
Packit Service 7605e7
    if (bool(info.m_pictureRecolor))
Packit Service 7605e7
    {
Packit Service 7605e7
      graphicsProps.remove("draw:color-mode");
Packit Service 7605e7
      graphicsProps.remove("draw:red");
Packit Service 7605e7
      graphicsProps.remove("draw:blue");
Packit Service 7605e7
      graphicsProps.remove("draw:green");
Packit Service 7605e7
    }
Packit Service 7605e7
    if (bool(info.m_pictureBrightness))
Packit Service 7605e7
      graphicsProps.remove("draw:luminance");
Packit Service 7605e7
    if (shadowPropsInserted)
Packit Service 7605e7
    {
Packit Service 7605e7
      graphicsProps.remove("draw:shadow");
Packit Service 7605e7
      graphicsProps.remove("draw:shadow-offset-x");
Packit Service 7605e7
      graphicsProps.remove("draw:shadow-offset-y");
Packit Service 7605e7
      graphicsProps.remove("draw:shadow-color");
Packit Service 7605e7
      graphicsProps.remove("draw:shadow-opacity");
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
  const std::vector<Line> &lines = info.m_lines;
Packit Service 7605e7
  if (hasStroke)
Packit Service 7605e7
  {
Packit Service 7605e7
    if (hasBorderArt && lines[0].m_widthInEmu > 0)
Packit Service 7605e7
    {
Packit Service 7605e7
      bool stretch = info.m_stretchBorderArt;
Packit Service 7605e7
      double x = coord.getXIn(m_width);
Packit Service 7605e7
      double y = coord.getYIn(m_height);
Packit Service 7605e7
      double height = coord.getHeightIn();
Packit Service 7605e7
      double width = coord.getWidthIn();
Packit Service 7605e7
      double borderImgWidth =
Packit Service 7605e7
        static_cast<double>(info.m_lines[0].m_widthInEmu) / EMUS_IN_INCH;
Packit Service 7605e7
      auto numImagesHoriz = static_cast<unsigned>(width / borderImgWidth);
Packit Service 7605e7
      auto numImagesVert = static_cast<unsigned>(height / borderImgWidth);
Packit Service 7605e7
      double borderVertTotalPadding = height - numImagesVert * borderImgWidth;
Packit Service 7605e7
      double borderHorizTotalPadding = width - numImagesHoriz * borderImgWidth;
Packit Service 7605e7
      if (numImagesHoriz >= 2 && numImagesVert >= 2)
Packit Service 7605e7
      {
Packit Service 7605e7
        auto numStretchedImagesVert = static_cast<unsigned>(0.5 + (height - 2 * borderImgWidth) / borderImgWidth);
Packit Service 7605e7
        auto numStretchedImagesHoriz = static_cast<unsigned>(0.5 + (width - 2 * borderImgWidth) / borderImgWidth);
Packit Service 7605e7
        double stretchedImgHeight = stretch ?
Packit Service 7605e7
                                    (height - 2 * borderImgWidth) / numStretchedImagesVert :
Packit Service 7605e7
                                    borderImgWidth;
Packit Service 7605e7
        double stretchedImgWidth = stretch ?
Packit Service 7605e7
                                   (width - 2 * borderImgWidth) / numStretchedImagesHoriz :
Packit Service 7605e7
                                   borderImgWidth;
Packit Service 7605e7
        if (stretch)
Packit Service 7605e7
        {
Packit Service 7605e7
          numImagesVert = 2 + numStretchedImagesVert;
Packit Service 7605e7
          numImagesHoriz = 2 + numStretchedImagesHoriz;
Packit Service 7605e7
        }
Packit Service 7605e7
        double borderVertPadding = borderVertTotalPadding / (numImagesVert - 1);
Packit Service 7605e7
        double borderHorizPadding = borderHorizTotalPadding / (numImagesHoriz - 1);
Packit Service 7605e7
        if (maybeBorderImg.get() < m_borderImages.size())
Packit Service 7605e7
        {
Packit Service 7605e7
          const BorderArtInfo &ba = m_borderImages[maybeBorderImg.get()];
Packit Service 7605e7
          if (!ba.m_offsets.empty())
Packit Service 7605e7
          {
Packit Service 7605e7
            librevenge::RVNGPropertyList baProps;
Packit Service 7605e7
            baProps.insert("draw:stroke", "none");
Packit Service 7605e7
            baProps.insert("draw:fill", "solid");
Packit Service 7605e7
            baProps.insert("draw:fill-color", "#ffffff");
Packit Service 7605e7
            m_painter->setStyle(baProps);
Packit Service 7605e7
            librevenge::RVNGPropertyList topRectProps;
Packit Service 7605e7
            topRectProps.insert("svg:x", x);
Packit Service 7605e7
            topRectProps.insert("svg:y", y);
Packit Service 7605e7
            topRectProps.insert("svg:height", borderImgWidth);
Packit Service 7605e7
            topRectProps.insert("svg:width", width);
Packit Service 7605e7
            m_painter->drawRectangle(topRectProps);
Packit Service 7605e7
            librevenge::RVNGPropertyList rightRectProps;
Packit Service 7605e7
            rightRectProps.insert("svg:x", x + width - borderImgWidth);
Packit Service 7605e7
            rightRectProps.insert("svg:y", y);
Packit Service 7605e7
            rightRectProps.insert("svg:height", height);
Packit Service 7605e7
            rightRectProps.insert("svg:width", borderImgWidth);
Packit Service 7605e7
            m_painter->drawRectangle(rightRectProps);
Packit Service 7605e7
            librevenge::RVNGPropertyList botRectProps;
Packit Service 7605e7
            botRectProps.insert("svg:x", x);
Packit Service 7605e7
            botRectProps.insert("svg:y", y + height - borderImgWidth);
Packit Service 7605e7
            botRectProps.insert("svg:height", borderImgWidth);
Packit Service 7605e7
            botRectProps.insert("svg:width", width);
Packit Service 7605e7
            m_painter->drawRectangle(botRectProps);
Packit Service 7605e7
            librevenge::RVNGPropertyList leftRectProps;
Packit Service 7605e7
            leftRectProps.insert("svg:x", x);
Packit Service 7605e7
            leftRectProps.insert("svg:y", y);
Packit Service 7605e7
            leftRectProps.insert("svg:height", height);
Packit Service 7605e7
            leftRectProps.insert("svg:width", borderImgWidth);
Packit Service 7605e7
            m_painter->drawRectangle(leftRectProps);
Packit Service 7605e7
            auto iOffset = ba.m_offsets.begin();
Packit Service 7605e7
            boost::optional<Color> oneBitColor;
Packit Service 7605e7
            if (bool(info.m_lineBackColor))
Packit Service 7605e7
            {
Packit Service 7605e7
              oneBitColor = info.m_lineBackColor.get().getFinalColor(m_paletteColors);
Packit Service 7605e7
            }
Packit Service 7605e7
            // top left
Packit Service 7605e7
            unsigned iOrdOff = find(ba.m_offsetsOrdered.begin(),
Packit Service 7605e7
                                    ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
Packit Service 7605e7
            if (iOrdOff < ba.m_images.size())
Packit Service 7605e7
            {
Packit Service 7605e7
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
Packit Service 7605e7
              writeImage(x, y, borderImgWidth, borderImgWidth,
Packit Service 7605e7
                         bi.m_type, bi.m_imgBlob, oneBitColor);
Packit Service 7605e7
            }
Packit Service 7605e7
            if (iOffset + 1 != ba.m_offsets.end())
Packit Service 7605e7
            {
Packit Service 7605e7
              ++iOffset;
Packit Service 7605e7
            }
Packit Service 7605e7
            // top
Packit Service 7605e7
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
Packit Service 7605e7
                           ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
Packit Service 7605e7
            if (iOrdOff < ba.m_images.size())
Packit Service 7605e7
            {
Packit Service 7605e7
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
Packit Service 7605e7
              for (unsigned iTop = 1; iTop < numImagesHoriz - 1; ++iTop)
Packit Service 7605e7
              {
Packit Service 7605e7
                double imgX = stretch ?
Packit Service 7605e7
                              x + borderImgWidth + (iTop - 1) * stretchedImgWidth :
Packit Service 7605e7
                              x + iTop * (borderImgWidth + borderHorizPadding);
Packit Service 7605e7
                writeImage(imgX, y,
Packit Service 7605e7
                           borderImgWidth, stretchedImgWidth,
Packit Service 7605e7
                           bi.m_type, bi.m_imgBlob, oneBitColor);
Packit Service 7605e7
              }
Packit Service 7605e7
            }
Packit Service 7605e7
            if (iOffset + 1 != ba.m_offsets.end())
Packit Service 7605e7
            {
Packit Service 7605e7
              ++iOffset;
Packit Service 7605e7
            }
Packit Service 7605e7
            // top right
Packit Service 7605e7
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
Packit Service 7605e7
                           ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
Packit Service 7605e7
            if (iOrdOff < ba.m_images.size())
Packit Service 7605e7
            {
Packit Service 7605e7
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
Packit Service 7605e7
              writeImage(x + width - borderImgWidth, y,
Packit Service 7605e7
                         borderImgWidth, borderImgWidth,
Packit Service 7605e7
                         bi.m_type, bi.m_imgBlob, oneBitColor);
Packit Service 7605e7
            }
Packit Service 7605e7
            if (iOffset + 1 != ba.m_offsets.end())
Packit Service 7605e7
            {
Packit Service 7605e7
              ++iOffset;
Packit Service 7605e7
            }
Packit Service 7605e7
            // right
Packit Service 7605e7
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
Packit Service 7605e7
                           ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
Packit Service 7605e7
            if (iOrdOff < ba.m_images.size())
Packit Service 7605e7
            {
Packit Service 7605e7
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
Packit Service 7605e7
              for (unsigned iRight = 1; iRight < numImagesVert - 1; ++iRight)
Packit Service 7605e7
              {
Packit Service 7605e7
                double imgY = stretch ?
Packit Service 7605e7
                              y + borderImgWidth + (iRight - 1) * stretchedImgHeight :
Packit Service 7605e7
                              y + iRight * (borderImgWidth + borderVertPadding);
Packit Service 7605e7
                writeImage(x + width - borderImgWidth,
Packit Service 7605e7
                           imgY,
Packit Service 7605e7
                           stretchedImgHeight, borderImgWidth,
Packit Service 7605e7
                           bi.m_type, bi.m_imgBlob, oneBitColor);
Packit Service 7605e7
              }
Packit Service 7605e7
            }
Packit Service 7605e7
            if (iOffset + 1 != ba.m_offsets.end())
Packit Service 7605e7
            {
Packit Service 7605e7
              ++iOffset;
Packit Service 7605e7
            }
Packit Service 7605e7
            // bottom right
Packit Service 7605e7
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
Packit Service 7605e7
                           ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
Packit Service 7605e7
            if (iOrdOff < ba.m_images.size())
Packit Service 7605e7
            {
Packit Service 7605e7
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
Packit Service 7605e7
              writeImage(x + width - borderImgWidth,
Packit Service 7605e7
                         y + height - borderImgWidth,
Packit Service 7605e7
                         borderImgWidth, borderImgWidth,
Packit Service 7605e7
                         bi.m_type, bi.m_imgBlob, oneBitColor);
Packit Service 7605e7
            }
Packit Service 7605e7
            if (iOffset + 1 != ba.m_offsets.end())
Packit Service 7605e7
            {
Packit Service 7605e7
              ++iOffset;
Packit Service 7605e7
            }
Packit Service 7605e7
            // bottom
Packit Service 7605e7
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
Packit Service 7605e7
                           ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
Packit Service 7605e7
            if (iOrdOff < ba.m_images.size())
Packit Service 7605e7
            {
Packit Service 7605e7
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
Packit Service 7605e7
              for (unsigned iBot = 1; iBot < numImagesHoriz - 1; ++iBot)
Packit Service 7605e7
              {
Packit Service 7605e7
                double imgX = stretch ?
Packit Service 7605e7
                              x + width - borderImgWidth - iBot * stretchedImgWidth :
Packit Service 7605e7
                              x + width - borderImgWidth - iBot * (borderImgWidth + borderHorizPadding);
Packit Service 7605e7
                writeImage(
Packit Service 7605e7
                  imgX, y + height - borderImgWidth,
Packit Service 7605e7
                  borderImgWidth, stretchedImgWidth,
Packit Service 7605e7
                  bi.m_type, bi.m_imgBlob, oneBitColor);
Packit Service 7605e7
              }
Packit Service 7605e7
            }
Packit Service 7605e7
            if (iOffset + 1 != ba.m_offsets.end())
Packit Service 7605e7
            {
Packit Service 7605e7
              ++iOffset;
Packit Service 7605e7
            }
Packit Service 7605e7
            // bottom left
Packit Service 7605e7
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
Packit Service 7605e7
                           ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
Packit Service 7605e7
            if (iOrdOff < ba.m_images.size())
Packit Service 7605e7
            {
Packit Service 7605e7
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
Packit Service 7605e7
              writeImage(x, y + height - borderImgWidth,
Packit Service 7605e7
                         borderImgWidth, borderImgWidth,
Packit Service 7605e7
                         bi.m_type, bi.m_imgBlob, oneBitColor);
Packit Service 7605e7
            }
Packit Service 7605e7
            if (iOffset + 1 != ba.m_offsets.end())
Packit Service 7605e7
            {
Packit Service 7605e7
              ++iOffset;
Packit Service 7605e7
            }
Packit Service 7605e7
            // left
Packit Service 7605e7
            iOrdOff = find(ba.m_offsetsOrdered.begin(),
Packit Service 7605e7
                           ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin();
Packit Service 7605e7
            if (iOrdOff < ba.m_images.size())
Packit Service 7605e7
            {
Packit Service 7605e7
              const BorderImgInfo &bi = ba.m_images[iOrdOff];
Packit Service 7605e7
              for (unsigned iLeft = 1; iLeft < numImagesVert - 1; ++iLeft)
Packit Service 7605e7
              {
Packit Service 7605e7
                double imgY = stretch ?
Packit Service 7605e7
                              y + height - borderImgWidth - iLeft * stretchedImgHeight :
Packit Service 7605e7
                              y + height - borderImgWidth -
Packit Service 7605e7
                              iLeft * (borderImgWidth + borderVertPadding);
Packit Service 7605e7
                writeImage(x, imgY, stretchedImgHeight, borderImgWidth,
Packit Service 7605e7
                           bi.m_type, bi.m_imgBlob, oneBitColor);
Packit Service 7605e7
              }
Packit Service 7605e7
            }
Packit Service 7605e7
          }
Packit Service 7605e7
        }
Packit Service 7605e7
      }
Packit Service 7605e7
    }
Packit Service 7605e7
    else
Packit Service 7605e7
    {
Packit Service 7605e7
      Coordinate strokeCoord = isShapeTypeRectangle(type) ?
Packit Service 7605e7
                               getFudgedCoordinates(coord, lines, true, borderPosition) : coord;
Packit Service 7605e7
      double x, y, height, width;
Packit Service 7605e7
      x = strokeCoord.getXIn(m_width);
Packit Service 7605e7
      y = strokeCoord.getYIn(m_height);
Packit Service 7605e7
      height = strokeCoord.getHeightIn();
Packit Service 7605e7
      width = strokeCoord.getWidthIn();
Packit Service 7605e7
      graphicsProps.insert("draw:fill", "none");
Packit Service 7605e7
      if (bool(info.m_dash) && !info.m_dash.get().m_dots.empty())
Packit Service 7605e7
      {
Packit Service 7605e7
        const Dash &dash = info.m_dash.get();
Packit Service 7605e7
        graphicsProps.insert("draw:stroke", "dash");
Packit Service 7605e7
        graphicsProps.insert("draw:distance", dash.m_distance, librevenge::RVNG_INCH);
Packit Service 7605e7
        switch (dash.m_dotStyle)
Packit Service 7605e7
        {
Packit Service 7605e7
        case ROUND_DOT:
Packit Service 7605e7
          graphicsProps.insert("svg:stroke-linecap", "round");
Packit Service 7605e7
          break;
Packit Service 7605e7
        case RECT_DOT:
Packit Service 7605e7
          graphicsProps.insert("svg:stroke-linecap", "butt");
Packit Service 7605e7
          break;
Packit Service 7605e7
        default:
Packit Service 7605e7
          break;
Packit Service 7605e7
        }
Packit Service 7605e7
        for (unsigned i = 0; i < dash.m_dots.size(); ++i)
Packit Service 7605e7
        {
Packit Service 7605e7
          librevenge::RVNGString dots;
Packit Service 7605e7
          dots.sprintf("draw:dots%d", i + 1);
Packit Service 7605e7
          graphicsProps.insert(dots.cstr(), static_cast<int>(dash.m_dots[i].m_count));
Packit Service 7605e7
          if (bool(dash.m_dots[i].m_length))
Packit Service 7605e7
          {
Packit Service 7605e7
            librevenge::RVNGString length;
Packit Service 7605e7
            length.sprintf("draw:dots%d-length", i + 1);
Packit Service 7605e7
            graphicsProps.insert(length.cstr(), dash.m_dots[i].m_length.get(), librevenge::RVNG_INCH);
Packit Service 7605e7
          }
Packit Service 7605e7
        }
Packit Service 7605e7
      }
Packit Service 7605e7
      else
Packit Service 7605e7
      {
Packit Service 7605e7
        graphicsProps.insert("draw:stroke", "solid");
Packit Service 7605e7
      }
Packit Service 7605e7
      m_painter->setStyle(graphicsProps);
Packit Service 7605e7
      writeCustomShape(type, graphicsProps, m_painter, x, y, height, width,
Packit Service 7605e7
                       false, foldedTransform, lines,
Packit Service 7605e7
                       std::bind(
Packit Service 7605e7
                         &MSPUBCollector::getCalculationValue, this, info, _1, false, adjustValues
Packit Service 7605e7
                       ),
Packit Service 7605e7
                       m_paletteColors, info.getCustomShape());
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
  if (hasText)
Packit Service 7605e7
  {
Packit Service 7605e7
    const std::vector<TextParagraph> &text = maybeText.get();
Packit Service 7605e7
    graphicsProps.insert("draw:fill", "none");
Packit Service 7605e7
    Coordinate textCoord = isShapeTypeRectangle(type) ?
Packit Service 7605e7
                           getFudgedCoordinates(coord, lines, false, borderPosition) : coord;
Packit Service 7605e7
    m_painter->setStyle(graphicsProps);
Packit Service 7605e7
    librevenge::RVNGPropertyList props;
Packit Service 7605e7
    setRectCoordProps(textCoord, &props;;
Packit Service 7605e7
    double textRotation = thisTransform.getRotation();
Packit Service 7605e7
    if (textRotation != 0)
Packit Service 7605e7
    {
Packit Service 7605e7
      props.insert("librevenge:rotate", textRotation * 180 / M_PI);
Packit Service 7605e7
    }
Packit Service 7605e7
Packit Service 7605e7
    if (isTable)
Packit Service 7605e7
    {
Packit Service 7605e7
      librevenge::RVNGPropertyListVector columnWidths;
Packit Service 7605e7
      for (unsigned int col : get(info.m_tableInfo).m_columnWidthsInEmu)
Packit Service 7605e7
      {
Packit Service 7605e7
        librevenge::RVNGPropertyList columnWidth;
Packit Service 7605e7
        columnWidth.insert("style:column-width", double(col) / EMUS_IN_INCH);
Packit Service 7605e7
        columnWidths.append(columnWidth);
Packit Service 7605e7
      }
Packit Service 7605e7
      props.insert("librevenge:table-columns", columnWidths);
Packit Service 7605e7
Packit Service 7605e7
      m_painter->startTableObject(props);
Packit Service 7605e7
Packit Service 7605e7
      const std::map<unsigned, std::vector<unsigned> >::const_iterator it = m_tableCellTextEndsByTextId.find(get(info.m_textId));
Packit Service 7605e7
      const std::vector<unsigned> &tableCellTextEnds = (it != m_tableCellTextEndsByTextId.end()) ? it->second : std::vector<unsigned>();
Packit Service 7605e7
Packit Service 7605e7
      TableLayout tableLayout(boost::extents[get(info.m_tableInfo).m_numRows][get(info.m_tableInfo).m_numColumns]);
Packit Service 7605e7
      createTableLayout(get(info.m_tableInfo).m_cells, tableLayout);
Packit Service 7605e7
Packit Service 7605e7
      ParagraphToCellMap_t paraToCellMap;
Packit Service 7605e7
      ParagraphTexts_t paraTexts;
Packit Service 7605e7
      mapTableTextToCells(text, tableCellTextEnds, getCalculatedEncoding(), paraToCellMap, paraTexts);
Packit Service 7605e7
Packit Service 7605e7
      for (unsigned row = 0; row != tableLayout.shape()[0]; ++row)
Packit Service 7605e7
      {
Packit Service 7605e7
        librevenge::RVNGPropertyList rowProps;
Packit Service 7605e7
        if (row < (get(info.m_tableInfo).m_rowHeightsInEmu.size()))
Packit Service 7605e7
          rowProps.insert("librevenge:row-height", double(get(info.m_tableInfo).m_rowHeightsInEmu[row]) / EMUS_IN_INCH);
Packit Service 7605e7
        m_painter->openTableRow(rowProps);
Packit Service 7605e7
Packit Service 7605e7
        for (unsigned col = 0; col != tableLayout.shape()[1]; ++col)
Packit Service 7605e7
        {
Packit Service 7605e7
          librevenge::RVNGPropertyList cellProps;
Packit Service 7605e7
          cellProps.insert("librevenge:column", int(col));
Packit Service 7605e7
          cellProps.insert("librevenge:row", int(row));
Packit Service 7605e7
Packit Service 7605e7
          if (isCovered(tableLayout[row][col]))
Packit Service 7605e7
          {
Packit Service 7605e7
            m_painter->insertCoveredTableCell(cellProps);
Packit Service 7605e7
          }
Packit Service 7605e7
          else
Packit Service 7605e7
          {
Packit Service 7605e7
            if (tableLayout[row][col].m_colSpan > 1)
Packit Service 7605e7
              cellProps.insert("table:number-columns-spanned", int(tableLayout[row][col].m_colSpan));
Packit Service 7605e7
            if (tableLayout[row][col].m_rowSpan > 1)
Packit Service 7605e7
              cellProps.insert("table:number-rows-spanned", int(tableLayout[row][col].m_rowSpan));
Packit Service 7605e7
Packit Service 7605e7
            m_painter->openTableCell(cellProps);
Packit Service 7605e7
Packit Service 7605e7
            if (tableLayout[row][col].m_cell < paraToCellMap.size())
Packit Service 7605e7
            {
Packit Service 7605e7
              const std::pair<unsigned, unsigned> &cellParas = paraToCellMap[tableLayout[row][col].m_cell];
Packit Service 7605e7
              for (unsigned para = cellParas.first; para <= cellParas.second; ++para)
Packit Service 7605e7
              {
Packit Service 7605e7
                librevenge::RVNGPropertyList paraProps = getParaStyleProps(text[para].style, text[para].style.m_defaultCharStyleIndex);
Packit Service 7605e7
                m_painter->openParagraph(paraProps);
Packit Service 7605e7
Packit Service 7605e7
                for (unsigned i_spans = 0; i_spans < paraTexts[para].size(); ++i_spans)
Packit Service 7605e7
                {
Packit Service 7605e7
                  librevenge::RVNGPropertyList charProps = getCharStyleProps(text[para].spans[i_spans].style, text[para].style.m_defaultCharStyleIndex);
Packit Service 7605e7
                  m_painter->openSpan(charProps);
Packit Service 7605e7
                  separateSpacesAndInsertText(m_painter, paraTexts[para][i_spans]);
Packit Service 7605e7
                  m_painter->closeSpan();
Packit Service 7605e7
                }
Packit Service 7605e7
Packit Service 7605e7
                m_painter->closeParagraph();
Packit Service 7605e7
              }
Packit Service 7605e7
            }
Packit Service 7605e7
Packit Service 7605e7
            m_painter->closeTableCell();
Packit Service 7605e7
          }
Packit Service 7605e7
        }
Packit Service 7605e7
Packit Service 7605e7
        m_painter->closeTableRow();
Packit Service 7605e7
      }
Packit Service 7605e7
Packit Service 7605e7
      m_painter->endTableObject();
Packit Service 7605e7
    }
Packit Service 7605e7
    else // a text object
Packit Service 7605e7
    {
Packit Service 7605e7
      Margins margins = info.m_margins.get_value_or(Margins());
Packit Service 7605e7
      props.insert("fo:padding-left", (double)margins.m_left / EMUS_IN_INCH);
Packit Service 7605e7
      props.insert("fo:padding-top", (double)margins.m_top / EMUS_IN_INCH);
Packit Service 7605e7
      props.insert("fo:padding-right", (double)margins.m_right / EMUS_IN_INCH);
Packit Service 7605e7
      props.insert("fo:padding-bottom", (double)margins.m_bottom / EMUS_IN_INCH);
Packit Service 7605e7
      if (bool(info.m_verticalAlign))
Packit Service 7605e7
      {
Packit Service 7605e7
        switch (info.m_verticalAlign.get())
Packit Service 7605e7
        {
Packit Service 7605e7
        default:
Packit Service 7605e7
        case TOP:
Packit Service 7605e7
          props.insert("draw:textarea-vertical-align", "top");
Packit Service 7605e7
          break;
Packit Service 7605e7
        case MIDDLE:
Packit Service 7605e7
          props.insert("draw:textarea-vertical-align", "middle");
Packit Service 7605e7
          break;
Packit Service 7605e7
        case BOTTOM:
Packit Service 7605e7
          props.insert("draw:textarea-vertical-align", "bottom");
Packit Service 7605e7
          break;
Packit Service 7605e7
        }
Packit Service 7605e7
      }
Packit Service 7605e7
      if (info.m_numColumns)
Packit Service 7605e7
      {
Packit Service 7605e7
        unsigned ncols = info.m_numColumns.get_value_or(0);
Packit Service 7605e7
        if (ncols > 0)
Packit Service 7605e7
          props.insert("fo:column-count", (int)ncols);
Packit Service 7605e7
      }
Packit Service 7605e7
      if (info.m_columnSpacing)
Packit Service 7605e7
      {
Packit Service 7605e7
        unsigned ngap = info.m_columnSpacing;
Packit Service 7605e7
        if (ngap > 0)
Packit Service 7605e7
          props.insert("fo:column-gap", (double)ngap / EMUS_IN_INCH);
Packit Service 7605e7
      }
Packit Service 7605e7
      m_painter->startTextObject(props);
Packit Service 7605e7
      for (const auto &line : text)
Packit Service 7605e7
      {
Packit Service 7605e7
        librevenge::RVNGPropertyList paraProps = getParaStyleProps(line.style, line.style.m_defaultCharStyleIndex);
Packit Service 7605e7
        m_painter->openParagraph(paraProps);
Packit Service 7605e7
        for (unsigned i_spans = 0; i_spans < line.spans.size(); ++i_spans)
Packit Service 7605e7
        {
Packit Service 7605e7
          librevenge::RVNGString textString;
Packit Service 7605e7
          appendCharacters(textString, line.spans[i_spans].chars,
Packit Service 7605e7
                           getCalculatedEncoding());
Packit Service 7605e7
          librevenge::RVNGPropertyList charProps = getCharStyleProps(line.spans[i_spans].style, line.style.m_defaultCharStyleIndex);
Packit Service 7605e7
          m_painter->openSpan(charProps);
Packit Service 7605e7
          separateSpacesAndInsertText(m_painter, textString);
Packit Service 7605e7
          m_painter->closeSpan();
Packit Service 7605e7
        }
Packit Service 7605e7
        m_painter->closeParagraph();
Packit Service 7605e7
      }
Packit Service 7605e7
      m_painter->endTextObject();
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
  if (makeLayer)
Packit Service 7605e7
  {
Packit Service 7605e7
    m_painter->endLayer();
Packit Service 7605e7
  }
Packit Service 7605e7
  return &no_op;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
const char *MSPUBCollector::getCalculatedEncoding() const
Packit Service 7605e7
{
Packit Service 7605e7
  if (bool(m_calculatedEncoding))
Packit Service 7605e7
  {
Packit Service 7605e7
    return m_calculatedEncoding.get();
Packit Service 7605e7
  }
Packit Service 7605e7
  // modern versions are somewhat sane and use Unicode
Packit Service 7605e7
  if (! m_encodingHeuristic)
Packit Service 7605e7
  {
Packit Service 7605e7
    m_calculatedEncoding = "UTF-16LE";
Packit Service 7605e7
    return m_calculatedEncoding.get();
Packit Service 7605e7
  }
Packit Service 7605e7
  // for older versions of PUB, see if we can get ICU to tell us the encoding.
Packit Service 7605e7
  UErrorCode status = U_ZERO_ERROR;
Packit Service 7605e7
  UCharsetDetector *ucd = nullptr;
Packit Service 7605e7
  const UCharsetMatch **matches = nullptr;
Packit Service 7605e7
  const UCharsetMatch *ucm = nullptr;
Packit Service 7605e7
  ucd = ucsdet_open(&status);
Packit Service 7605e7
  int matchesFound = -1;
Packit Service 7605e7
  const char *name = nullptr;
Packit Service 7605e7
  const char *windowsName = nullptr;
Packit Service 7605e7
  if (m_allText.empty())
Packit Service 7605e7
  {
Packit Service 7605e7
    goto csd_fail;
Packit Service 7605e7
  }
Packit Service 7605e7
  if (U_FAILURE(status))
Packit Service 7605e7
  {
Packit Service 7605e7
    goto csd_fail;
Packit Service 7605e7
  }
Packit Service 7605e7
  // don't worry, the below call doesn't require a null-terminated string.
Packit Service 7605e7
  ucsdet_setText(ucd, (const char *)m_allText.data(), m_allText.size(), &status);
Packit Service 7605e7
  if (U_FAILURE(status))
Packit Service 7605e7
  {
Packit Service 7605e7
    goto csd_fail;
Packit Service 7605e7
  }
Packit Service 7605e7
  matches = ucsdet_detectAll(ucd, &matchesFound, &status);
Packit Service 7605e7
  if (U_FAILURE(status))
Packit Service 7605e7
  {
Packit Service 7605e7
    goto csd_fail;
Packit Service 7605e7
  }
Packit Service 7605e7
  //find best fit that is an actual Windows encoding
Packit Service 7605e7
  for (int i = 0; i < matchesFound; ++i)
Packit Service 7605e7
  {
Packit Service 7605e7
    ucm = matches[i];
Packit Service 7605e7
    name = ucsdet_getName(ucm, &status);
Packit Service 7605e7
    if (U_FAILURE(status))
Packit Service 7605e7
    {
Packit Service 7605e7
      goto csd_fail;
Packit Service 7605e7
    }
Packit Service 7605e7
    windowsName = windowsCharsetNameByOriginalCharset(name);
Packit Service 7605e7
    if (windowsName)
Packit Service 7605e7
    {
Packit Service 7605e7
      m_calculatedEncoding = windowsName;
Packit Service 7605e7
      ucsdet_close(ucd);
Packit Service 7605e7
      return windowsName;
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
csd_fail:
Packit Service 7605e7
  ucsdet_close(ucd);
Packit Service 7605e7
  return "windows-1252"; // Pretty likely to give garbage text, but it's the best we can do.
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeLineBackColor(unsigned shapeSeqNum,
Packit Service 7605e7
                                           ColorReference backColor)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[shapeSeqNum].m_lineBackColor = backColor;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::writeImage(double x, double y,
Packit Service 7605e7
                                double height, double width, ImgType type, const librevenge::RVNGBinaryData &blob,
Packit Service 7605e7
                                boost::optional<Color> oneBitColor) const
Packit Service 7605e7
{
Packit Service 7605e7
  librevenge::RVNGPropertyList props;
Packit Service 7605e7
  if (bool(oneBitColor))
Packit Service 7605e7
  {
Packit Service 7605e7
    Color obc = oneBitColor.get();
Packit Service 7605e7
    props.insert("draw:color-mode", "greyscale");
Packit Service 7605e7
    props.insert("draw:red", static_cast<double>(obc.r) / 255.0, librevenge::RVNG_PERCENT);
Packit Service 7605e7
    props.insert("draw:blue", static_cast<double>(obc.b) / 255.0, librevenge::RVNG_PERCENT);
Packit Service 7605e7
    props.insert("draw:green", static_cast<double>(obc.g) / 255.0, librevenge::RVNG_PERCENT);
Packit Service 7605e7
  }
Packit Service 7605e7
  props.insert("svg:x", x);
Packit Service 7605e7
  props.insert("svg:y", y);
Packit Service 7605e7
  props.insert("svg:width", width);
Packit Service 7605e7
  props.insert("svg:height", height);
Packit Service 7605e7
  props.insert("librevenge:mime-type", mimeByImgType(type));
Packit Service 7605e7
  props.insert("office:binary-data", blob);
Packit Service 7605e7
  m_painter->drawGraphicObject(props);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
double MSPUBCollector::getSpecialValue(const ShapeInfo &info, const CustomShape &shape, int arg, const std::vector<int> &adjustValues) const
Packit Service 7605e7
{
Packit Service 7605e7
  if (PROP_ADJUST_VAL_FIRST <= arg && PROP_ADJUST_VAL_LAST >= arg)
Packit Service 7605e7
  {
Packit Service 7605e7
    unsigned adjustIndex = arg - PROP_ADJUST_VAL_FIRST;
Packit Service 7605e7
    if (adjustIndex < adjustValues.size())
Packit Service 7605e7
    {
Packit Service 7605e7
      if ((shape.m_adjustShiftMask >> adjustIndex) & 0x1)
Packit Service 7605e7
      {
Packit Service 7605e7
        return adjustValues[adjustIndex] >> 16;
Packit Service 7605e7
      }
Packit Service 7605e7
      return adjustValues[adjustIndex];
Packit Service 7605e7
    }
Packit Service 7605e7
    return 0;
Packit Service 7605e7
  }
Packit Service 7605e7
  if (arg == ASPECT_RATIO)
Packit Service 7605e7
  {
Packit Service 7605e7
    const Coordinate coord = info.m_coordinates.get_value_or(Coordinate());
Packit Service 7605e7
    return (double)coord.getWidthIn() / coord.getHeightIn();
Packit Service 7605e7
  }
Packit Service 7605e7
  if (arg & OTHER_CALC_VAL)
Packit Service 7605e7
  {
Packit Service 7605e7
    return getCalculationValue(info, arg & 0xff, true, adjustValues);
Packit Service 7605e7
  }
Packit Service 7605e7
  switch (arg)
Packit Service 7605e7
  {
Packit Service 7605e7
  case PROP_GEO_LEFT:
Packit Service 7605e7
    return 0;
Packit Service 7605e7
  case PROP_GEO_TOP:
Packit Service 7605e7
    return 0;
Packit Service 7605e7
  case PROP_GEO_RIGHT:
Packit Service 7605e7
    return shape.m_coordWidth;
Packit Service 7605e7
  case PROP_GEO_BOTTOM:
Packit Service 7605e7
    return shape.m_coordHeight;
Packit Service 7605e7
  default:
Packit Service 7605e7
    break;
Packit Service 7605e7
  }
Packit Service 7605e7
  return 0;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
double MSPUBCollector::getCalculationValue(const ShapeInfo &info, unsigned index, bool recursiveEntry, const std::vector<int> &adjustValues) const
Packit Service 7605e7
{
Packit Service 7605e7
  std::shared_ptr<const CustomShape> p_shape = info.getCustomShape();
Packit Service 7605e7
  if (! p_shape)
Packit Service 7605e7
  {
Packit Service 7605e7
    return 0;
Packit Service 7605e7
  }
Packit Service 7605e7
  const CustomShape &shape = *p_shape;
Packit Service 7605e7
  if (index >= shape.m_numCalculations)
Packit Service 7605e7
  {
Packit Service 7605e7
    return 0;
Packit Service 7605e7
  }
Packit Service 7605e7
  if (! recursiveEntry)
Packit Service 7605e7
  {
Packit Service 7605e7
    m_calculationValuesSeen.clear();
Packit Service 7605e7
    m_calculationValuesSeen.resize(shape.m_numCalculations);
Packit Service 7605e7
  }
Packit Service 7605e7
  if (m_calculationValuesSeen[index])
Packit Service 7605e7
  {
Packit Service 7605e7
    //recursion detected. The simplest way to avoid infinite recursion, at the "cost"
Packit Service 7605e7
    // of making custom shape parsing not Turing-complete ;), is to ban recursion entirely.
Packit Service 7605e7
    return 0;
Packit Service 7605e7
  }
Packit Service 7605e7
  m_calculationValuesSeen[index] = true;
Packit Service 7605e7
Packit Service 7605e7
  const Calculation &c = shape.mp_calculations[index];
Packit Service 7605e7
  bool oneSpecial = (c.m_flags & 0x2000) != 0;
Packit Service 7605e7
  bool twoSpecial = (c.m_flags & 0x4000) != 0;
Packit Service 7605e7
  bool threeSpecial = (c.m_flags & 0x8000) != 0;
Packit Service 7605e7
Packit Service 7605e7
  double valOne = oneSpecial ? getSpecialValue(info, shape, c.m_argOne, adjustValues) : c.m_argOne;
Packit Service 7605e7
  double valTwo = twoSpecial ? getSpecialValue(info, shape, c.m_argTwo, adjustValues) : c.m_argTwo;
Packit Service 7605e7
  double valThree = threeSpecial ? getSpecialValue(info, shape, c.m_argThree, adjustValues) : c.m_argThree;
Packit Service 7605e7
  m_calculationValuesSeen[index] = false;
Packit Service 7605e7
  switch (c.m_flags & 0xFF)
Packit Service 7605e7
  {
Packit Service 7605e7
  case 0:
Packit Service 7605e7
  case 14:
Packit Service 7605e7
    return valOne + valTwo - valThree;
Packit Service 7605e7
  case 1:
Packit Service 7605e7
    return valOne * valTwo / (valThree == 0 ? 1 : valThree);
Packit Service 7605e7
  case 2:
Packit Service 7605e7
    return (valOne + valTwo) / 2;
Packit Service 7605e7
  case 3:
Packit Service 7605e7
    return fabs(valOne);
Packit Service 7605e7
  case 4:
Packit Service 7605e7
    return std::min(valOne, valTwo);
Packit Service 7605e7
  case 5:
Packit Service 7605e7
    return std::max(valOne, valTwo);
Packit Service 7605e7
  case 6:
Packit Service 7605e7
    return valOne ? valTwo : valThree;
Packit Service 7605e7
  case 7:
Packit Service 7605e7
    return sqrt(valOne * valTwo * valThree);
Packit Service 7605e7
  case 8:
Packit Service 7605e7
    return atan2(valTwo, valOne) / (M_PI / 180);
Packit Service 7605e7
  case 9:
Packit Service 7605e7
    return valOne * sin(valTwo * (M_PI / 180));
Packit Service 7605e7
  case 10:
Packit Service 7605e7
    return valOne * cos(valTwo * (M_PI / 180));
Packit Service 7605e7
  case 11:
Packit Service 7605e7
    return valOne * cos(atan2(valThree, valTwo));
Packit Service 7605e7
  case 12:
Packit Service 7605e7
    return valOne * sin(atan2(valThree, valTwo));
Packit Service 7605e7
  case 13:
Packit Service 7605e7
    return sqrt(valOne);
Packit Service 7605e7
  case 15:
Packit Service 7605e7
    return valThree * sqrt(1 - (valOne / valTwo) * (valOne / valTwo));
Packit Service 7605e7
  case 16:
Packit Service 7605e7
    return valOne * tan(valTwo);
Packit Service 7605e7
  case 0x80:
Packit Service 7605e7
    return sqrt(valThree * valThree - valOne * valOne);
Packit Service 7605e7
  case 0x81:
Packit Service 7605e7
    return (cos(valThree * (M_PI / 180)) * (valOne - 10800) + sin(valThree * (M_PI / 180)) * (valTwo - 10800)) + 10800;
Packit Service 7605e7
  case 0x82:
Packit Service 7605e7
    return -(sin(valThree * (M_PI / 180)) * (valOne - 10800) - cos(valThree * (M_PI / 180)) * (valTwo - 10800)) + 10800;
Packit Service 7605e7
  default:
Packit Service 7605e7
    return 0;
Packit Service 7605e7
  }
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
MSPUBCollector::~MSPUBCollector()
Packit Service 7605e7
{
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeRotation(unsigned seqNum, double rotation)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_rotation = rotation;
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_innerRotation = (int)rotation;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeFlip(unsigned seqNum, bool flipVertical, bool flipHorizontal)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_flips = std::pair<bool, bool>(flipVertical, flipHorizontal);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeType(unsigned seqNum, ShapeType type)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_type = type;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setAdjustValue(unsigned seqNum, unsigned index, int adjust)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_adjustValuesByIndex[index] = adjust;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::addDefaultCharacterStyle(const CharacterStyle &st)
Packit Service 7605e7
{
Packit Service 7605e7
  m_defaultCharStyles.push_back(st);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::addDefaultParagraphStyle(const ParagraphStyle &st)
Packit Service 7605e7
{
Packit Service 7605e7
  m_defaultParaStyles.push_back(st);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
bool MSPUBCollector::addPage(unsigned seqNum)
Packit Service 7605e7
{
Packit Service 7605e7
  if (!(m_widthSet && m_heightSet))
Packit Service 7605e7
  {
Packit Service 7605e7
    return false;
Packit Service 7605e7
  }
Packit Service 7605e7
  MSPUB_DEBUG_MSG(("Adding page of seqnum 0x%x\n", seqNum));
Packit Service 7605e7
  m_pagesBySeqNum[seqNum] = PageInfo();
Packit Service 7605e7
  return true;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::addTextShape(unsigned stringId, unsigned seqNum)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_textId = stringId;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeImgIndex(unsigned seqNum, unsigned index)
Packit Service 7605e7
{
Packit Service 7605e7
  MSPUB_DEBUG_MSG(("Setting image index of shape with seqnum 0x%x to 0x%x\n", seqNum, index));
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_imgIndex = index;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeDash(unsigned seqNum, const Dash &dash)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_dash = dash;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeFill(unsigned seqNum, std::shared_ptr<Fill> fill, bool skipIfNotBg)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_fill = fill;
Packit Service 7605e7
  if (skipIfNotBg)
Packit Service 7605e7
  {
Packit Service 7605e7
    m_skipIfNotBgSeqNums.insert(seqNum);
Packit Service 7605e7
  }
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeCoordinatesInEmu(unsigned seqNum, int xs, int ys, int xe, int ye)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_coordinates = Coordinate(xs, ys, xe, ye);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::addFont(std::vector<unsigned char> name)
Packit Service 7605e7
{
Packit Service 7605e7
  m_fonts.push_back(name);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
librevenge::RVNGPropertyList MSPUBCollector::getParaStyleProps(const ParagraphStyle &style, boost::optional<unsigned> defaultParaStyleIndex) const
Packit Service 7605e7
{
Packit Service 7605e7
  ParagraphStyle _nothing;
Packit Service 7605e7
  const ParagraphStyle &defaultStyle = bool(defaultParaStyleIndex) && defaultParaStyleIndex.get() < m_defaultParaStyles.size() ? m_defaultParaStyles[defaultParaStyleIndex.get()] : _nothing;
Packit Service 7605e7
  librevenge::RVNGPropertyList ret;
Packit Service 7605e7
  Alignment align = style.m_align.get_value_or(
Packit Service 7605e7
                      defaultStyle.m_align.get_value_or(LEFT));
Packit Service 7605e7
  switch (align)
Packit Service 7605e7
  {
Packit Service 7605e7
  case RIGHT:
Packit Service 7605e7
    ret.insert("fo:text-align", "right");
Packit Service 7605e7
    break;
Packit Service 7605e7
  case CENTER:
Packit Service 7605e7
    ret.insert("fo:text-align", "center");
Packit Service 7605e7
    break;
Packit Service 7605e7
  case JUSTIFY:
Packit Service 7605e7
    ret.insert("fo:text-align", "justify");
Packit Service 7605e7
    break;
Packit Service 7605e7
  case LEFT:
Packit Service 7605e7
  default:
Packit Service 7605e7
    ret.insert("fo:text-align", "left");
Packit Service 7605e7
    break;
Packit Service 7605e7
  }
Packit Service 7605e7
  LineSpacingInfo info = style.m_lineSpacing.get_value_or(
Packit Service 7605e7
                           defaultStyle.m_lineSpacing.get_value_or(LineSpacingInfo()));
Packit Service 7605e7
  LineSpacingType lineSpacingType = info.m_type;
Packit Service 7605e7
  double lineSpacing = info.m_amount;
Packit Service 7605e7
  if (!(lineSpacingType == LINE_SPACING_SP && lineSpacing == 1))
Packit Service 7605e7
  {
Packit Service 7605e7
    if (lineSpacingType == LINE_SPACING_SP)
Packit Service 7605e7
    {
Packit Service 7605e7
      ret.insert("fo:line-height", lineSpacing, librevenge::RVNG_PERCENT);
Packit Service 7605e7
    }
Packit Service 7605e7
    else if (lineSpacingType == LINE_SPACING_PT)
Packit Service 7605e7
    {
Packit Service 7605e7
      ret.insert("fo:line-height", lineSpacing, librevenge::RVNG_POINT);
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
  unsigned spaceAfterEmu = style.m_spaceAfterEmu.get_value_or(
Packit Service 7605e7
                             defaultStyle.m_spaceAfterEmu.get_value_or(0));
Packit Service 7605e7
  unsigned spaceBeforeEmu = style.m_spaceBeforeEmu.get_value_or(
Packit Service 7605e7
                              defaultStyle.m_spaceBeforeEmu.get_value_or(0));
Packit Service 7605e7
  int firstLineIndentEmu = style.m_firstLineIndentEmu.get_value_or(
Packit Service 7605e7
                             defaultStyle.m_firstLineIndentEmu.get_value_or(0));
Packit Service 7605e7
  unsigned leftIndentEmu = style.m_leftIndentEmu.get_value_or(
Packit Service 7605e7
                             defaultStyle.m_leftIndentEmu.get_value_or(0));
Packit Service 7605e7
  unsigned rightIndentEmu = style.m_rightIndentEmu.get_value_or(
Packit Service 7605e7
                              defaultStyle.m_rightIndentEmu.get_value_or(0));
Packit Service 7605e7
  if (spaceAfterEmu != 0)
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("fo:margin-bottom", (double)spaceAfterEmu / EMUS_IN_INCH);
Packit Service 7605e7
  }
Packit Service 7605e7
  if (spaceBeforeEmu != 0)
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("fo:margin-top", (double)spaceBeforeEmu / EMUS_IN_INCH);
Packit Service 7605e7
  }
Packit Service 7605e7
  if (firstLineIndentEmu != 0)
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("fo:text-indent", (double)firstLineIndentEmu / EMUS_IN_INCH);
Packit Service 7605e7
  }
Packit Service 7605e7
  if (leftIndentEmu != 0)
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("fo:margin-left", (double)leftIndentEmu / EMUS_IN_INCH);
Packit Service 7605e7
  }
Packit Service 7605e7
  if (rightIndentEmu != 0)
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("fo:margin-right", (double)rightIndentEmu / EMUS_IN_INCH);
Packit Service 7605e7
  }
Packit Service 7605e7
  unsigned dropCapLines = style.m_dropCapLines.get_value_or(
Packit Service 7605e7
                            defaultStyle.m_dropCapLines.get_value_or(0));
Packit Service 7605e7
  if (dropCapLines != 0)
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("style:drop-cap", (int)dropCapLines);
Packit Service 7605e7
  }
Packit Service 7605e7
  unsigned dropCapLetters = style.m_dropCapLetters.get_value_or(
Packit Service 7605e7
                              defaultStyle.m_dropCapLetters.get_value_or(0));
Packit Service 7605e7
  if (dropCapLetters != 0)
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("style:length", (int)dropCapLetters);
Packit Service 7605e7
  }
Packit Service 7605e7
  return ret;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
librevenge::RVNGPropertyList MSPUBCollector::getCharStyleProps(const CharacterStyle &style, boost::optional<unsigned> defaultCharStyleIndex) const
Packit Service 7605e7
{
Packit Service 7605e7
  CharacterStyle _nothing;
Packit Service 7605e7
  if (!defaultCharStyleIndex)
Packit Service 7605e7
  {
Packit Service 7605e7
    defaultCharStyleIndex = 0;
Packit Service 7605e7
  }
Packit Service 7605e7
  const CharacterStyle &defaultCharStyle = defaultCharStyleIndex.get() < m_defaultCharStyles.size() ? m_defaultCharStyles[defaultCharStyleIndex.get()] : _nothing;
Packit Service 7605e7
  librevenge::RVNGPropertyList ret;
Packit Service 7605e7
  if (style.italic ^ defaultCharStyle.italic)
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("fo:font-style", "italic");
Packit Service 7605e7
  }
Packit Service 7605e7
  if (style.bold ^ defaultCharStyle.bold)
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("fo:font-weight", "bold");
Packit Service 7605e7
  }
Packit Service 7605e7
  if (style.outline ^ defaultCharStyle.outline)
Packit Service 7605e7
    ret.insert("style:text-outline", "true");
Packit Service 7605e7
  if (style.shadow ^ defaultCharStyle.shadow)
Packit Service 7605e7
    ret.insert("fo:text-shadow", "1pt 1pt");
Packit Service 7605e7
  if (style.smallCaps ^ defaultCharStyle.smallCaps)
Packit Service 7605e7
    ret.insert("fo:font-variant", "small-caps");
Packit Service 7605e7
  else if (style.allCaps ^ defaultCharStyle.allCaps)
Packit Service 7605e7
    ret.insert("fo:text-transform", "uppercase");
Packit Service 7605e7
  if (style.emboss ^ defaultCharStyle.emboss)
Packit Service 7605e7
    ret.insert("style:font-relief", "embossed");
Packit Service 7605e7
  else if (style.engrave ^ defaultCharStyle.engrave)
Packit Service 7605e7
    ret.insert("style:font-relief", "engraved");
Packit Service 7605e7
  if (style.underline)
Packit Service 7605e7
    fillUnderline(ret, get(style.underline));
Packit Service 7605e7
  else if (defaultCharStyle.underline)
Packit Service 7605e7
    fillUnderline(ret, get(defaultCharStyle.underline));
Packit Service 7605e7
  if (style.textScale)
Packit Service 7605e7
    ret.insert("fo:text-scale", get(style.textScale), librevenge::RVNG_PERCENT);
Packit Service 7605e7
  else if (defaultCharStyle.textScale)
Packit Service 7605e7
    ret.insert("fo:text-scale", get(defaultCharStyle.textScale), librevenge::RVNG_PERCENT);
Packit Service 7605e7
  if (bool(style.textSizeInPt))
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("fo:font-size", style.textSizeInPt.get() / POINTS_IN_INCH);
Packit Service 7605e7
  }
Packit Service 7605e7
  else if (bool(defaultCharStyle.textSizeInPt))
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("fo:font-size", defaultCharStyle.textSizeInPt.get()
Packit Service 7605e7
               / POINTS_IN_INCH);
Packit Service 7605e7
  }
Packit Service 7605e7
  if (style.colorIndex >= 0 && (size_t)style.colorIndex < m_textColors.size())
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("fo:color", getColorString(m_textColors[style.colorIndex].getFinalColor(m_paletteColors)));
Packit Service 7605e7
  }
Packit Service 7605e7
  else if (defaultCharStyle.colorIndex >= 0 && (size_t)defaultCharStyle.colorIndex < m_textColors.size())
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("fo:color", getColorString(m_textColors[defaultCharStyle.colorIndex].getFinalColor(m_paletteColors)));
Packit Service 7605e7
  }
Packit Service 7605e7
  else
Packit Service 7605e7
  {
Packit Service 7605e7
    ret.insert("fo:color", getColorString(Color(0, 0, 0)));  // default color is black
Packit Service 7605e7
  }
Packit Service 7605e7
  if (bool(style.fontIndex) &&
Packit Service 7605e7
      style.fontIndex.get() < m_fonts.size())
Packit Service 7605e7
  {
Packit Service 7605e7
    librevenge::RVNGString str;
Packit Service 7605e7
    appendCharacters(str, m_fonts[style.fontIndex.get()],
Packit Service 7605e7
                     getCalculatedEncoding());
Packit Service 7605e7
    ret.insert("style:font-name", str);
Packit Service 7605e7
  }
Packit Service 7605e7
  else if (bool(defaultCharStyle.fontIndex) &&
Packit Service 7605e7
           defaultCharStyle.fontIndex.get() < m_fonts.size())
Packit Service 7605e7
  {
Packit Service 7605e7
    librevenge::RVNGString str;
Packit Service 7605e7
    appendCharacters(str, m_fonts[defaultCharStyle.fontIndex.get()],
Packit Service 7605e7
                     getCalculatedEncoding());
Packit Service 7605e7
    ret.insert("style:font-name", str);
Packit Service 7605e7
  }
Packit Service 7605e7
  else if (!m_fonts.empty())
Packit Service 7605e7
  {
Packit Service 7605e7
    librevenge::RVNGString str;
Packit Service 7605e7
    appendCharacters(str, m_fonts[0],
Packit Service 7605e7
                     getCalculatedEncoding());
Packit Service 7605e7
    ret.insert("style:font-name", str);
Packit Service 7605e7
  }
Packit Service 7605e7
  switch (style.superSubType)
Packit Service 7605e7
  {
Packit Service 7605e7
  case SUPERSCRIPT:
Packit Service 7605e7
    ret.insert("style:text-position", "50% 67%");
Packit Service 7605e7
    break;
Packit Service 7605e7
  case SUBSCRIPT:
Packit Service 7605e7
    ret.insert("style:text-position", "-50% 67%");
Packit Service 7605e7
    break;
Packit Service 7605e7
  default:
Packit Service 7605e7
    break;
Packit Service 7605e7
  }
Packit Service 7605e7
  if (style.lcid)
Packit Service 7605e7
    fillLocale(ret, get(style.lcid));
Packit Service 7605e7
  else if (defaultCharStyle.lcid)
Packit Service 7605e7
    fillLocale(ret, get(defaultCharStyle.lcid));
Packit Service 7605e7
  return ret;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
librevenge::RVNGString MSPUBCollector::getColorString(const Color &color)
Packit Service 7605e7
{
Packit Service 7605e7
  librevenge::RVNGString ret;
Packit Service 7605e7
  ret.sprintf("#%.2x%.2x%.2x",(unsigned char)color.r, (unsigned char)color.g, (unsigned char)color.b);
Packit Service 7605e7
  MSPUB_DEBUG_MSG(("String for r: 0x%x, g: 0x%x, b: 0x%x is %s\n", color.r, color.g, color.b, ret.cstr()));
Packit Service 7605e7
  return ret;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::addBlackToPaletteIfNecessary()
Packit Service 7605e7
{
Packit Service 7605e7
  if (m_paletteColors.size() < 8)
Packit Service 7605e7
  {
Packit Service 7605e7
    m_paletteColors.insert(m_paletteColors.begin(), Color());
Packit Service 7605e7
  }
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::assignShapesToPages()
Packit Service 7605e7
{
Packit Service 7605e7
  for (auto &topLevelShape : m_topLevelShapes)
Packit Service 7605e7
  {
Packit Service 7605e7
    unsigned *ptr_pageSeqNum = getIfExists(m_pageSeqNumsByShapeSeqNum, topLevelShape->getSeqNum());
Packit Service 7605e7
    topLevelShape->setup(std::bind(&MSPUBCollector::setupShapeStructures, this, _1));
Packit Service 7605e7
    if (ptr_pageSeqNum)
Packit Service 7605e7
    {
Packit Service 7605e7
      PageInfo *ptr_page = getIfExists(m_pagesBySeqNum, *ptr_pageSeqNum);
Packit Service 7605e7
      if (ptr_page)
Packit Service 7605e7
      {
Packit Service 7605e7
        ptr_page->m_shapeGroupsOrdered.push_back(topLevelShape);
Packit Service 7605e7
      }
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
boost::optional<unsigned> MSPUBCollector::getMasterPageSeqNum(unsigned pageSeqNum) const
Packit Service 7605e7
{
Packit Service 7605e7
  boost::optional<unsigned> toReturn;
Packit Service 7605e7
  const unsigned *ptr_masterSeqNum = getIfExists_const(m_masterPagesByPageSeqNum, pageSeqNum);
Packit Service 7605e7
  if (ptr_masterSeqNum && m_masterPages.find(*ptr_masterSeqNum) != m_masterPages.end())
Packit Service 7605e7
  {
Packit Service 7605e7
    return *ptr_masterSeqNum;
Packit Service 7605e7
  }
Packit Service 7605e7
  return toReturn;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::writePage(unsigned pageSeqNum) const
Packit Service 7605e7
{
Packit Service 7605e7
  const PageInfo &pageInfo = m_pagesBySeqNum.find(pageSeqNum)->second;
Packit Service 7605e7
  librevenge::RVNGPropertyList pageProps;
Packit Service 7605e7
  if (m_widthSet)
Packit Service 7605e7
  {
Packit Service 7605e7
    pageProps.insert("svg:width", m_width);
Packit Service 7605e7
  }
Packit Service 7605e7
  if (m_heightSet)
Packit Service 7605e7
  {
Packit Service 7605e7
    pageProps.insert("svg:height", m_height);
Packit Service 7605e7
  }
Packit Service 7605e7
  const auto &shapeGroupsOrdered = pageInfo.m_shapeGroupsOrdered;
Packit Service 7605e7
  if (!shapeGroupsOrdered.empty())
Packit Service 7605e7
  {
Packit Service 7605e7
    m_painter->startPage(pageProps);
Packit Service 7605e7
    boost::optional<unsigned> masterSeqNum = getMasterPageSeqNum(pageSeqNum);
Packit Service 7605e7
    auto hasMaster = bool(masterSeqNum);
Packit Service 7605e7
    if (hasMaster)
Packit Service 7605e7
    {
Packit Service 7605e7
      writePageBackground(masterSeqNum.get());
Packit Service 7605e7
    }
Packit Service 7605e7
    writePageBackground(pageSeqNum);
Packit Service 7605e7
    if (hasMaster)
Packit Service 7605e7
    {
Packit Service 7605e7
      writePageShapes(masterSeqNum.get());
Packit Service 7605e7
    }
Packit Service 7605e7
    writePageShapes(pageSeqNum);
Packit Service 7605e7
    m_painter->endPage();
Packit Service 7605e7
  }
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::writePageShapes(unsigned pageSeqNum) const
Packit Service 7605e7
{
Packit Service 7605e7
  const PageInfo &pageInfo = m_pagesBySeqNum.find(pageSeqNum)->second;
Packit Service 7605e7
  for (const auto &shapeGroup : pageInfo.m_shapeGroupsOrdered)
Packit Service 7605e7
    shapeGroup->visit(std::bind(&MSPUBCollector::paintShape, this, _1, _2, _3, _4, _5));
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::writePageBackground(unsigned pageSeqNum) const
Packit Service 7605e7
{
Packit Service 7605e7
  const unsigned *ptr_fillSeqNum = getIfExists_const(m_bgShapeSeqNumsByPageSeqNum, pageSeqNum);
Packit Service 7605e7
  if (ptr_fillSeqNum)
Packit Service 7605e7
  {
Packit Service 7605e7
    std::shared_ptr<const Fill> ptr_fill;
Packit Service 7605e7
    const ShapeInfo *ptr_info = getIfExists_const(m_shapeInfosBySeqNum, *ptr_fillSeqNum);
Packit Service 7605e7
    if (ptr_info)
Packit Service 7605e7
    {
Packit Service 7605e7
      ptr_fill = ptr_info->m_fill;
Packit Service 7605e7
    }
Packit Service 7605e7
    if (ptr_fill)
Packit Service 7605e7
    {
Packit Service 7605e7
      ShapeInfo bg;
Packit Service 7605e7
      bg.m_type = RECTANGLE;
Packit Service 7605e7
      Coordinate wholePage(-m_width/2 * EMUS_IN_INCH, -m_height/2 * EMUS_IN_INCH, m_width/2 * EMUS_IN_INCH, m_height/2 * EMUS_IN_INCH);
Packit Service 7605e7
      bg.m_coordinates = wholePage;
Packit Service 7605e7
      bg.m_pageSeqNum = pageSeqNum;
Packit Service 7605e7
      bg.m_fill = ptr_fill;
Packit Service 7605e7
      paintShape(bg, Coordinate(), VectorTransformation2D(), false, VectorTransformation2D());
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
bool MSPUBCollector::pageIsMaster(unsigned pageSeqNum) const
Packit Service 7605e7
{
Packit Service 7605e7
  return m_masterPages.find(pageSeqNum) != m_masterPages.end();
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
bool MSPUBCollector::go()
Packit Service 7605e7
{
Packit Service 7605e7
  addBlackToPaletteIfNecessary();
Packit Service 7605e7
  assignShapesToPages();
Packit Service 7605e7
  m_painter->startDocument(librevenge::RVNGPropertyList());
Packit Service 7605e7
  m_painter->setDocumentMetaData(m_metaData);
Packit Service 7605e7
Packit Service 7605e7
  for (std::list<EmbeddedFontInfo>::const_iterator i = m_embeddedFonts.begin(); i != m_embeddedFonts.end(); ++i)
Packit Service 7605e7
  {
Packit Service 7605e7
    librevenge::RVNGPropertyList props;
Packit Service 7605e7
    props.insert("librevenge:name", i->m_name);
Packit Service 7605e7
    props.insert("librevenge:mime-type", "application/vnd.ms-fontobject");
Packit Service 7605e7
    props.insert("office:binary-data",i->m_blob);
Packit Service 7605e7
    m_painter->defineEmbeddedFont(props);
Packit Service 7605e7
  }
Packit Service 7605e7
Packit Service 7605e7
  if (m_pageSeqNumsOrdered.empty())
Packit Service 7605e7
  {
Packit Service 7605e7
    for (std::map<unsigned, PageInfo>::const_iterator i = m_pagesBySeqNum.begin();
Packit Service 7605e7
         i != m_pagesBySeqNum.end(); ++i)
Packit Service 7605e7
    {
Packit Service 7605e7
      if (!pageIsMaster(i->first))
Packit Service 7605e7
      {
Packit Service 7605e7
        writePage(i->first);
Packit Service 7605e7
      }
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
  else
Packit Service 7605e7
  {
Packit Service 7605e7
    for (unsigned int i : m_pageSeqNumsOrdered)
Packit Service 7605e7
    {
Packit Service 7605e7
      std::map<unsigned, PageInfo>::const_iterator iter =
Packit Service 7605e7
        m_pagesBySeqNum.find(i);
Packit Service 7605e7
      if (iter != m_pagesBySeqNum.end() && !pageIsMaster(iter->first))
Packit Service 7605e7
      {
Packit Service 7605e7
        writePage(iter->first);
Packit Service 7605e7
      }
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
  m_painter->endDocument();
Packit Service 7605e7
  return true;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
Packit Service 7605e7
bool MSPUBCollector::addTextString(const std::vector<TextParagraph> &str, unsigned id)
Packit Service 7605e7
{
Packit Service 7605e7
  MSPUB_DEBUG_MSG(("addTextString, id: 0x%x\n", id));
Packit Service 7605e7
  m_textStringsById[id] = str;
Packit Service 7605e7
  if (m_encodingHeuristic)
Packit Service 7605e7
  {
Packit Service 7605e7
    ponderStringEncoding(str);
Packit Service 7605e7
  }
Packit Service 7605e7
  return true; //FIXME: Warn if the string already existed in the map.
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::ponderStringEncoding(
Packit Service 7605e7
  const std::vector<TextParagraph> &str)
Packit Service 7605e7
{
Packit Service 7605e7
  for (const auto &i : str)
Packit Service 7605e7
  {
Packit Service 7605e7
    for (unsigned j = 0; j < i.spans.size(); ++j)
Packit Service 7605e7
    {
Packit Service 7605e7
      const std::vector<unsigned char> &chars = i.spans[j].chars;
Packit Service 7605e7
      m_allText.insert(m_allText.end(), chars.begin(), chars.end());
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setWidthInEmu(unsigned long widthInEmu)
Packit Service 7605e7
{
Packit Service 7605e7
  //FIXME: Warn if this is called twice
Packit Service 7605e7
  m_width = ((double)widthInEmu) / EMUS_IN_INCH;
Packit Service 7605e7
  m_widthSet = true;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setHeightInEmu(unsigned long heightInEmu)
Packit Service 7605e7
{
Packit Service 7605e7
  //FIXME: Warn if this is called twice
Packit Service 7605e7
  m_height = ((double)heightInEmu) / EMUS_IN_INCH;
Packit Service 7605e7
  m_heightSet = true;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
bool MSPUBCollector::addImage(unsigned index, ImgType type, librevenge::RVNGBinaryData img)
Packit Service 7605e7
{
Packit Service 7605e7
  while (m_images.size() < index)
Packit Service 7605e7
  {
Packit Service 7605e7
    m_images.push_back(std::pair<ImgType, librevenge::RVNGBinaryData>(UNKNOWN, librevenge::RVNGBinaryData()));
Packit Service 7605e7
  }
Packit Service 7605e7
  if (index > 0)
Packit Service 7605e7
  {
Packit Service 7605e7
    MSPUB_DEBUG_MSG(("Image at index %u and of type 0x%x added.\n", index, type));
Packit Service 7605e7
    m_images[index - 1] = std::pair<ImgType, librevenge::RVNGBinaryData>(type, img);
Packit Service 7605e7
  }
Packit Service 7605e7
  else
Packit Service 7605e7
  {
Packit Service 7605e7
    MSPUB_DEBUG_MSG(("0 is not a valid index for image, ignoring.\n"));
Packit Service 7605e7
  }
Packit Service 7605e7
  return index > 0;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
librevenge::RVNGBinaryData *MSPUBCollector::addBorderImage(ImgType type,
Packit Service 7605e7
                                                           unsigned borderArtIndex)
Packit Service 7605e7
{
Packit Service 7605e7
  while (borderArtIndex >= m_borderImages.size())
Packit Service 7605e7
  {
Packit Service 7605e7
    m_borderImages.push_back(BorderArtInfo());
Packit Service 7605e7
  }
Packit Service 7605e7
  m_borderImages[borderArtIndex].m_images.push_back(BorderImgInfo(type));
Packit Service 7605e7
  return &(m_borderImages[borderArtIndex].m_images.back().m_imgBlob);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setBorderImageOffset(unsigned index, unsigned offset)
Packit Service 7605e7
{
Packit Service 7605e7
  while (index >= m_borderImages.size())
Packit Service 7605e7
  {
Packit Service 7605e7
    m_borderImages.push_back(BorderArtInfo());
Packit Service 7605e7
  }
Packit Service 7605e7
  BorderArtInfo &bai = m_borderImages[index];
Packit Service 7605e7
  bai.m_offsets.push_back(offset);
Packit Service 7605e7
  bool added = false;
Packit Service 7605e7
  for (auto i = bai.m_offsetsOrdered.begin();
Packit Service 7605e7
       i != bai.m_offsetsOrdered.end(); ++i)
Packit Service 7605e7
  {
Packit Service 7605e7
    if (*i >= offset)
Packit Service 7605e7
    {
Packit Service 7605e7
      bai.m_offsetsOrdered.insert(i, offset);
Packit Service 7605e7
      added = true;
Packit Service 7605e7
      break;
Packit Service 7605e7
    }
Packit Service 7605e7
  }
Packit Service 7605e7
  if (!added)
Packit Service 7605e7
  {
Packit Service 7605e7
    bai.m_offsetsOrdered.push_back(offset);
Packit Service 7605e7
  }
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapePage(unsigned seqNum, unsigned pageSeqNum)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_pageSeqNum = pageSeqNum;
Packit Service 7605e7
  m_pageSeqNumsByShapeSeqNum[seqNum] = pageSeqNum;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::addTextColor(ColorReference c)
Packit Service 7605e7
{
Packit Service 7605e7
  m_textColors.push_back(c);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::designateMasterPage(unsigned seqNum)
Packit Service 7605e7
{
Packit Service 7605e7
  m_masterPages.insert(seqNum);
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setMasterPage(unsigned seqNum, unsigned masterPageSeqNum)
Packit Service 7605e7
{
Packit Service 7605e7
  m_masterPagesByPageSeqNum[seqNum] = masterPageSeqNum;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
void MSPUBCollector::setShapeCropType(unsigned seqNum, ShapeType cropType)
Packit Service 7605e7
{
Packit Service 7605e7
  m_shapeInfosBySeqNum[seqNum].m_cropType = cropType;
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
}
Packit Service 7605e7
Packit Service 7605e7
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */