Example #1
0
void libcdr::CDRPolygon::create(libcdr::CDRPath &path) const
{
  if (m_numAngles == 0)
    return;

  libcdr::CDRPath tmpPath(path);
  double step = 2*M_PI / (double)m_numAngles;
  if (m_nextPoint && m_numAngles % m_nextPoint)
  {
    libcdr::CDRTransform tmpTrafo(cos(m_nextPoint*step), sin(m_nextPoint*step), 0.0, -sin(m_nextPoint*step), cos(m_nextPoint*step), 0.0);
    for (unsigned i = 1; i < m_numAngles; ++i)
    {
      tmpPath.transform(tmpTrafo);
      path.appendPath(tmpPath);
    }
  }
  else
  {
    libcdr::CDRTransform tmpTrafo(cos(m_nextPoint*step), sin(m_nextPoint*step), 0.0, -sin(m_nextPoint*step), cos(m_nextPoint*step), 0.0);
    libcdr::CDRTransform tmpShift(cos(step), sin(step), 0.0, -sin(step), cos(step), 0.0);
    for (unsigned i = 0; i < m_nextPoint; ++i)
    {
      if (i)
      {
        tmpPath.transform(tmpShift);
        path.appendPath(tmpPath);
      }
      for (unsigned j=1; j < m_numAngles / m_nextPoint; ++j)
      {
        tmpPath.transform(tmpTrafo);
        path.appendPath(tmpPath);
      }
      path.appendClosePath();
    }
  }
  path.appendClosePath();
  libcdr::CDRTransform trafo(m_rx, 0.0, m_cx, 0.0, m_ry, m_cy);
  path.transform(trafo);
}
Example #2
0
void libcdr::CDRContentCollector::_flushCurrentPath()
{
  CDR_DEBUG_MSG(("CDRContentCollector::_flushCurrentPath\n"));
  CDROutputElementList outputElement;
  if (!m_currentPath.empty() || (!m_splineData.empty() && m_isInSpline))
  {
    if (m_polygon && m_isInPolygon)
      m_polygon->create(m_currentPath);
    if (m_polygon)
    {
      delete m_polygon;
      m_polygon = 0;
    }
    m_isInPolygon = false;
    if (!m_splineData.empty() && m_isInSpline)
      m_splineData.create(m_currentPath);
    m_splineData.clear();
    m_isInSpline = false;
    bool firstPoint = true;
    bool wasMove = false;
    double initialX = 0.0;
    double initialY = 0.0;
    double previousX = 0.0;
    double previousY = 0.0;
    double x = 0.0;
    double y = 0.0;
    librevenge::RVNGPropertyList style;
    _fillProperties(style);
    _lineProperties(style);
    outputElement.addStyle(style);
    m_currentPath.transform(m_currentTransforms);
    if (!m_groupTransforms.empty())
      m_currentPath.transform(m_groupTransforms.top());
    CDRTransform tmpTrafo(1.0, 0.0, -m_page.offsetX, 0.0, 1.0, -m_page.offsetY);
    m_currentPath.transform(tmpTrafo);
    tmpTrafo = CDRTransform(1.0, 0.0, 0.0, 0.0, -1.0, m_page.height);
    m_currentPath.transform(tmpTrafo);

    std::vector<librevenge::RVNGPropertyList> tmpPath;

    librevenge::RVNGPropertyListVector path;
    m_currentPath.writeOut(path);

    bool isPathClosed = m_currentPath.isClosed();

    librevenge::RVNGPropertyListVector::Iter i(path);
    for (i.rewind(); i.next();)
    {
      if (!i()["librevenge:path-action"])
        continue;
      if (i()["svg:x"] && i()["svg:y"])
      {
        bool ignoreM = false;
        x = i()["svg:x"]->getDouble();
        y = i()["svg:y"]->getDouble();
        if (firstPoint)
        {
          initialX = x;
          initialY = y;
          firstPoint = false;
          wasMove = true;
        }
        else if (i()["librevenge:path-action"]->getStr() == "M")
        {
          // This is needed for a good generation of path from polygon
          if (CDR_ALMOST_ZERO(previousX - x) && CDR_ALMOST_ZERO(previousY - y))
            ignoreM = true;
          else
          {
            if (!tmpPath.empty())
            {
              if (!wasMove)
              {
                if ((CDR_ALMOST_ZERO(initialX - previousX) && CDR_ALMOST_ZERO(initialY - previousY)) || isPathClosed)
                {
                  librevenge::RVNGPropertyList node;
                  node.insert("librevenge:path-action", "Z");
                  tmpPath.push_back(node);
                }
              }
              else
                tmpPath.pop_back();
            }
          }

          if (!ignoreM)
          {
            initialX = x;
            initialY = y;
            wasMove = true;
          }

        }
        else
          wasMove = false;

        if (!ignoreM)
        {
          tmpPath.push_back(i());
          previousX = x;
          previousY = y;
        }

      }
      else if (i()["librevenge:path-action"]->getStr() == "Z")
      {
        if (tmpPath.back()["librevenge:path-action"] && tmpPath.back()["librevenge:path-action"]->getStr() != "Z")
          tmpPath.push_back(i());
      }
    }
    if (!tmpPath.empty())
    {
      if (!wasMove)
      {
        if ((CDR_ALMOST_ZERO(initialX - previousX) && CDR_ALMOST_ZERO(initialY - previousY)) || isPathClosed)
        {
          if (tmpPath.back()["librevenge:path-action"] && tmpPath.back()["librevenge:path-action"]->getStr() != "Z")
          {
            librevenge::RVNGPropertyList closedPath;
            closedPath.insert("librevenge:path-action", "Z");
            tmpPath.push_back(closedPath);
          }
        }
      }
      else
        tmpPath.pop_back();
    }
    if (!tmpPath.empty())
    {
      librevenge::RVNGPropertyListVector outputPath;
      for (std::vector<librevenge::RVNGPropertyList>::const_iterator iter = tmpPath.begin(); iter != tmpPath.end(); ++iter)
        outputPath.append(*iter);
      librevenge::RVNGPropertyList propList;
      propList.insert("svg:d", outputPath);
      outputElement.addPath(propList);

    }
    m_currentPath.clear();
  }

  if (m_currentImage.getImage().size())
  {
    double cx = m_currentImage.getMiddleX();
    double cy = m_currentImage.getMiddleY();
    double corner1x = m_currentImage.m_x1;
    double corner1y = m_currentImage.m_y1;
    double corner2x = m_currentImage.m_x1;
    double corner2y = m_currentImage.m_y2;
    double corner3x = m_currentImage.m_x2;
    double corner3y = m_currentImage.m_y2;
    m_currentTransforms.applyToPoint(cx, cy);
    m_currentTransforms.applyToPoint(corner1x, corner1y);
    m_currentTransforms.applyToPoint(corner2x, corner2y);
    m_currentTransforms.applyToPoint(corner3x, corner3y);
    if (!m_groupTransforms.empty())
    {
      m_groupTransforms.top().applyToPoint(cx, cy);
      m_groupTransforms.top().applyToPoint(corner1x, corner1y);
      m_groupTransforms.top().applyToPoint(corner2x, corner2y);
      m_groupTransforms.top().applyToPoint(corner3x, corner3y);
    }
    CDRTransform tmpTrafo(1.0, 0.0, -m_page.offsetX, 0.0, 1.0, -m_page.offsetY);
    tmpTrafo.applyToPoint(cx, cy);
    tmpTrafo.applyToPoint(corner1x, corner1y);
    tmpTrafo.applyToPoint(corner2x, corner2y);
    tmpTrafo.applyToPoint(corner3x, corner3y);
    tmpTrafo = CDRTransform(1.0, 0.0, 0.0, 0.0, -1.0, m_page.height);
    tmpTrafo.applyToPoint(cx, cy);
    tmpTrafo.applyToPoint(corner1x, corner1y);
    tmpTrafo.applyToPoint(corner2x, corner2y);
    tmpTrafo.applyToPoint(corner3x, corner3y);
    bool flipX(m_currentTransforms.getFlipX());
    bool flipY(m_currentTransforms.getFlipY());
    double width = sqrt((corner2x - corner3x)*(corner2x - corner3x) + (corner2y - corner3y)*(corner2y - corner3y));
    double height = sqrt((corner2x - corner1x)*(corner2x - corner1x) + (corner2y - corner1y)*(corner2y - corner1y));
    double rotate = atan2(corner3y-corner2y, corner3x-corner2x);

    librevenge::RVNGPropertyList propList;

    propList.insert("svg:x", cx - width / 2.0);
    propList.insert("svg:width", width);
    propList.insert("svg:y", cy - height / 2.0);
    propList.insert("svg:height", height);

    if (flipX)
    {
      propList.insert("draw:mirror-horizontal", true);
      rotate = M_PI - rotate;
    }
    if (flipY)
    {
      propList.insert("draw:mirror-vertical", true);
      rotate *= -1.0;
    }

    while (rotate < 0.0)
      rotate += 2.0*M_PI;
    while (rotate > 2.0*M_PI)
      rotate -= 2.0*M_PI;

    if (rotate != 0.0)
      propList.insert("librevenge:rotate", rotate * 180 / M_PI, librevenge::RVNG_GENERIC);

    propList.insert("librevenge:mime-type", "image/bmp");
    propList.insert("office:binary-data", m_currentImage.getImage());
    outputElement.addGraphicObject(propList);
  }
  if (m_currentText && !m_currentText->empty())
  {
    double x1 = m_currentTextBox.m_x;
    double y1 = m_currentTextBox.m_y;
    double x2 = m_currentTextBox.m_x + m_currentTextBox.m_w;
    double y2 = m_currentTextBox.m_y - m_currentTextBox.m_h;
    if (!CDR_ALMOST_ZERO(m_currentTextBox.m_h) && !CDR_ALMOST_ZERO(m_currentTextBox.m_w))
    {
      m_currentTransforms.applyToPoint(x1, y1);
      m_currentTransforms.applyToPoint(x2, y2);
      if (!m_groupTransforms.empty())
      {
        m_groupTransforms.top().applyToPoint(x1, y1);
        m_groupTransforms.top().applyToPoint(x2, y2);
      }
    }
    else if (!CDR_ALMOST_ZERO(m_currentBBox.getWidth()) && !CDR_ALMOST_ZERO(m_currentBBox.getHeight()))
    {
      y1 = m_currentBBox.getMinY();
      y2 = m_currentBBox.getMinY() + m_currentBBox.getHeight();
      if ((*m_currentText)[0].m_line[0].m_charStyle.m_align == 2) // Center
      {
        x1 = m_currentBBox.getMinX() - m_currentBBox.getWidth() / 4.0;
        x2 = m_currentBBox.getMinX() + (3.0 * m_currentBBox.getWidth() / 4.0);
      }
      else if ((*m_currentText)[0].m_line[0].m_charStyle.m_align == 3) // Right
      {
        x1 = m_currentBBox.getMinX() - m_currentBBox.getWidth() / 2.0;
        x2 = m_currentBBox.getMinX() + m_currentBBox.getWidth() / 2.0;
      }
      else
      {
        x1 = m_currentBBox.getMinX();
        x2 = m_currentBBox.getMinX() + m_currentBBox.getWidth();
      }
    }

    CDRTransform tmpTrafo(1.0, 0.0, -m_page.offsetX, 0.0, 1.0, -m_page.offsetY);
    tmpTrafo.applyToPoint(x1, y1);
    tmpTrafo.applyToPoint(x2, y2);
    tmpTrafo = CDRTransform(1.0, 0.0, 0.0, 0.0, -1.0, m_page.height);
    tmpTrafo.applyToPoint(x1, y1);
    tmpTrafo.applyToPoint(x2, y2);
    if (x1 > x2)
      std::swap(x1, x2);
    if (y1 > y2)
      std::swap(y1, y2);

    librevenge::RVNGPropertyList textFrameProps;
    textFrameProps.insert("svg:width", fabs(x2-x1));
    textFrameProps.insert("svg:height", fabs(y2-y1));
    textFrameProps.insert("svg:x", x1);
    textFrameProps.insert("svg:y", y1);
    textFrameProps.insert("fo:padding-top", 0.0);
    textFrameProps.insert("fo:padding-bottom", 0.0);
    textFrameProps.insert("fo:padding-left", 0.0);
    textFrameProps.insert("fo:padding-right", 0.0);
    outputElement.addStartTextObject(textFrameProps);
    for (unsigned i = 0; i < m_currentText->size(); ++i)
    {
      const std::vector<CDRText> &currentLine = (*m_currentText)[i].m_line;
      if (currentLine.empty())
        continue;
      librevenge::RVNGPropertyList paraProps;
      bool rtl = false;
      switch (currentLine[0].m_charStyle.m_align)
      {
      case 1:  // Left
        if (!rtl)
          paraProps.insert("fo:text-align", "left");
        else
          paraProps.insert("fo:text-align", "end");
        break;
      case 2:  // Center
        paraProps.insert("fo:text-align", "center");
        break;
      case 3:  // Right
        if (!rtl)
          paraProps.insert("fo:text-align", "end");
        else
          paraProps.insert("fo:text-align", "left");
        break;
      case 4:  // Full justify
        paraProps.insert("fo:text-align", "justify");
        break;
      case 5:  // Force justify
        paraProps.insert("fo:text-align", "full");
        break;
      case 0:  // None
      default:
        break;
      }
      outputElement.addOpenParagraph(paraProps);
      for (unsigned j = 0; j < currentLine.size(); ++j)
      {
        if (!currentLine[j].m_text.empty())
        {
          librevenge::RVNGPropertyList spanProps;
          double fontSize = (double)cdr_round(144.0*currentLine[j].m_charStyle.m_fontSize) / 2.0;
          spanProps.insert("fo:font-size", fontSize, librevenge::RVNG_POINT);
          if (currentLine[j].m_charStyle.m_fontName.len())
            spanProps.insert("style:font-name", currentLine[j].m_charStyle.m_fontName);
          if (currentLine[j].m_charStyle.m_fillStyle.fillType != (unsigned short)-1)
            spanProps.insert("fo:color", m_ps.getRGBColorString(currentLine[j].m_charStyle.m_fillStyle.color1));
          outputElement.addOpenSpan(spanProps);
          outputElement.addInsertText(currentLine[j].m_text);
          outputElement.addCloseSpan();
        }
      }
      outputElement.addCloseParagraph();
    }
    outputElement.addEndTextObject();
  }
  m_currentImage = libcdr::CDRImage();
  if (!outputElement.empty())
    m_outputElements->push(outputElement);
  m_currentTransforms.clear();
  m_fillTransforms = libcdr::CDRTransforms();
  m_fillOpacity = 1.0;
  m_currentText = 0;
}