Blame src/lib/MSPUBParser2k.cpp

rpm-build 9243a4
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
rpm-build 9243a4
/*
rpm-build 9243a4
 * This file is part of the libmspub project.
rpm-build 9243a4
 *
rpm-build 9243a4
 * This Source Code Form is subject to the terms of the Mozilla Public
rpm-build 9243a4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
rpm-build 9243a4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
rpm-build 9243a4
 */
rpm-build 9243a4
rpm-build 9243a4
#include "MSPUBParser2k.h"
rpm-build 9243a4
rpm-build 9243a4
#include <algorithm>
rpm-build 9243a4
#include <utility>
rpm-build 9243a4
#include <memory>
rpm-build 9243a4
rpm-build 9243a4
#include <librevenge-stream/librevenge-stream.h>
rpm-build 9243a4
rpm-build 9243a4
#include "ColorReference.h"
rpm-build 9243a4
#include "Fill.h"
rpm-build 9243a4
#include "Line.h"
rpm-build 9243a4
#include "MSPUBCollector.h"
rpm-build 9243a4
#include "ShapeType.h"
rpm-build 9243a4
#include "libmspub_utils.h"
rpm-build 9243a4
rpm-build 9243a4
namespace libmspub
rpm-build 9243a4
{
rpm-build 9243a4
rpm-build 9243a4
namespace
rpm-build 9243a4
{
rpm-build 9243a4
rpm-build 9243a4
class ChunkNestingGuard
rpm-build 9243a4
{
rpm-build 9243a4
public:
rpm-build 9243a4
  ChunkNestingGuard(std::deque<unsigned> &chunks, const unsigned seqNum)
rpm-build 9243a4
    : m_chunks(chunks)
rpm-build 9243a4
  {
rpm-build 9243a4
    m_chunks.push_front(seqNum);
rpm-build 9243a4
  }
rpm-build 9243a4
rpm-build 9243a4
  ~ChunkNestingGuard()
rpm-build 9243a4
  {
rpm-build 9243a4
    m_chunks.pop_front();
rpm-build 9243a4
  }
rpm-build 9243a4
rpm-build 9243a4
private:
rpm-build 9243a4
  std::deque<unsigned> &m_chunks;
rpm-build 9243a4
};
rpm-build 9243a4
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
MSPUBParser2k::MSPUBParser2k(librevenge::RVNGInputStream *input, MSPUBCollector *collector)
rpm-build 9243a4
  : MSPUBParser(input, collector),
rpm-build 9243a4
    m_imageDataChunkIndices(),
rpm-build 9243a4
    m_quillColorEntries(),
rpm-build 9243a4
    m_chunkChildIndicesById(),
rpm-build 9243a4
    m_chunksBeingRead()
rpm-build 9243a4
{
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
unsigned MSPUBParser2k::getColorIndexByQuillEntry(unsigned entry)
rpm-build 9243a4
{
rpm-build 9243a4
  unsigned translation = translate2kColorReference(entry);
rpm-build 9243a4
  std::vector<unsigned>::const_iterator i_entry = std::find(m_quillColorEntries.begin(), m_quillColorEntries.end(), translation);
rpm-build 9243a4
  if (i_entry == m_quillColorEntries.end())
rpm-build 9243a4
  {
rpm-build 9243a4
    m_quillColorEntries.push_back(translation);
rpm-build 9243a4
    m_collector->addTextColor(ColorReference(translation));
rpm-build 9243a4
    return m_quillColorEntries.size() - 1;
rpm-build 9243a4
  }
rpm-build 9243a4
  return i_entry - m_quillColorEntries.begin();
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
MSPUBParser2k::~MSPUBParser2k()
rpm-build 9243a4
{
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
// Takes a line width specifier in Pub2k format and translates it into quarter points
rpm-build 9243a4
unsigned short translateLineWidth(unsigned char lineWidth)
rpm-build 9243a4
{
rpm-build 9243a4
  if (lineWidth == 0x81)
rpm-build 9243a4
  {
rpm-build 9243a4
    return 0;
rpm-build 9243a4
  }
rpm-build 9243a4
  else if (lineWidth > 0x81)
rpm-build 9243a4
  {
rpm-build 9243a4
    return ((lineWidth - 0x81) / 3) * 4 + ((lineWidth - 0x81) % 3) + 1;
rpm-build 9243a4
  }
rpm-build 9243a4
  else
rpm-build 9243a4
  {
rpm-build 9243a4
    return lineWidth * 4;
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
Color MSPUBParser2k::getColorBy2kHex(unsigned hex)
rpm-build 9243a4
{
rpm-build 9243a4
  switch ((hex >> 24) & 0xFF)
rpm-build 9243a4
  {
rpm-build 9243a4
  case 0x80:
rpm-build 9243a4
  case 0x00:
rpm-build 9243a4
    return getColorBy2kIndex(hex & 0xFF);
rpm-build 9243a4
  case 0x90:
rpm-build 9243a4
  case 0x20:
rpm-build 9243a4
    return Color(hex & 0xFF, (hex >> 8) & 0xFF, (hex >> 16) & 0xFF);
rpm-build 9243a4
  default:
rpm-build 9243a4
    return Color();
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
Color MSPUBParser2k::getColorBy2kIndex(unsigned char index)
rpm-build 9243a4
{
rpm-build 9243a4
  switch (index)
rpm-build 9243a4
  {
rpm-build 9243a4
  case 0x00:
rpm-build 9243a4
    return Color(0, 0, 0);
rpm-build 9243a4
  case 0x01:
rpm-build 9243a4
    return Color(0xff, 0xff, 0xff);
rpm-build 9243a4
  case 0x02:
rpm-build 9243a4
    return Color(0xff, 0, 0);
rpm-build 9243a4
  case 0x03:
rpm-build 9243a4
    return Color(0, 0xff, 0);
rpm-build 9243a4
  case 0x04:
rpm-build 9243a4
    return Color(0, 0, 0xff);
rpm-build 9243a4
  case 0x05:
rpm-build 9243a4
    return Color(0xff, 0xff, 0);
rpm-build 9243a4
  case 0x06:
rpm-build 9243a4
    return Color(0, 0xff, 0xff);
rpm-build 9243a4
  case 0x07:
rpm-build 9243a4
    return Color(0xff, 0, 0xff);
rpm-build 9243a4
  case 0x08:
rpm-build 9243a4
    return Color(128, 128, 128);
rpm-build 9243a4
  case 0x09:
rpm-build 9243a4
    return Color(192, 192, 192);
rpm-build 9243a4
  case 0x0A:
rpm-build 9243a4
    return Color(128, 0, 0);
rpm-build 9243a4
  case 0x0B:
rpm-build 9243a4
    return Color(0, 128, 0);
rpm-build 9243a4
  case 0x0C:
rpm-build 9243a4
    return Color(0, 0, 128);
rpm-build 9243a4
  case 0x0D:
rpm-build 9243a4
    return Color(128, 128, 0);
rpm-build 9243a4
  case 0x0E:
rpm-build 9243a4
    return Color(0, 128, 128);
rpm-build 9243a4
  case 0x0F:
rpm-build 9243a4
    return Color(128, 0, 128);
rpm-build 9243a4
  case 0x10:
rpm-build 9243a4
    return Color(255, 153, 51);
rpm-build 9243a4
  case 0x11:
rpm-build 9243a4
    return Color(51, 0, 51);
rpm-build 9243a4
  case 0x12:
rpm-build 9243a4
    return Color(0, 0, 153);
rpm-build 9243a4
  case 0x13:
rpm-build 9243a4
    return Color(0, 153, 0);
rpm-build 9243a4
  case 0x14:
rpm-build 9243a4
    return Color(153, 153, 0);
rpm-build 9243a4
  case 0x15:
rpm-build 9243a4
    return Color(204, 102, 0);
rpm-build 9243a4
  case 0x16:
rpm-build 9243a4
    return Color(153, 0, 0);
rpm-build 9243a4
  case 0x17:
rpm-build 9243a4
    return Color(204, 153, 204);
rpm-build 9243a4
  case 0x18:
rpm-build 9243a4
    return Color(102, 102, 255);
rpm-build 9243a4
  case 0x19:
rpm-build 9243a4
    return Color(102, 255, 102);
rpm-build 9243a4
  case 0x1A:
rpm-build 9243a4
    return Color(255, 255, 153);
rpm-build 9243a4
  case 0x1B:
rpm-build 9243a4
    return Color(255, 204, 153);
rpm-build 9243a4
  case 0x1C:
rpm-build 9243a4
    return Color(255, 102, 102);
rpm-build 9243a4
  case 0x1D:
rpm-build 9243a4
    return Color(255, 153, 0);
rpm-build 9243a4
  case 0x1E:
rpm-build 9243a4
    return Color(0, 102, 255);
rpm-build 9243a4
  case 0x1F:
rpm-build 9243a4
    return Color(255, 204, 0);
rpm-build 9243a4
  case 0x20:
rpm-build 9243a4
    return Color(153, 0, 51);
rpm-build 9243a4
  case 0x21:
rpm-build 9243a4
    return Color(102, 51, 0);
rpm-build 9243a4
  case 0x22:
rpm-build 9243a4
    return Color(66, 66, 66);
rpm-build 9243a4
  case 0x23:
rpm-build 9243a4
    return Color(255, 153, 102);
rpm-build 9243a4
  case 0x24:
rpm-build 9243a4
    return Color(153, 51, 0);
rpm-build 9243a4
  case 0x25:
rpm-build 9243a4
    return Color(255, 102, 0);
rpm-build 9243a4
  case 0x26:
rpm-build 9243a4
    return Color(51, 51, 0);
rpm-build 9243a4
  case 0x27:
rpm-build 9243a4
    return Color(153, 204, 0);
rpm-build 9243a4
  case 0x28:
rpm-build 9243a4
    return Color(255, 255, 153);
rpm-build 9243a4
  case 0x29:
rpm-build 9243a4
    return Color(0, 51, 0);
rpm-build 9243a4
  case 0x2A:
rpm-build 9243a4
    return Color(51, 153, 102);
rpm-build 9243a4
  case 0x2B:
rpm-build 9243a4
    return Color(204, 255, 204);
rpm-build 9243a4
  case 0x2C:
rpm-build 9243a4
    return Color(0, 51, 102);
rpm-build 9243a4
  case 0x2D:
rpm-build 9243a4
    return Color(51, 204, 204);
rpm-build 9243a4
  case 0x2E:
rpm-build 9243a4
    return Color(204, 255, 255);
rpm-build 9243a4
  case 0x2F:
rpm-build 9243a4
    return Color(51, 102, 255);
rpm-build 9243a4
  case 0x30:
rpm-build 9243a4
    return Color(0, 204, 255);
rpm-build 9243a4
  case 0x31:
rpm-build 9243a4
    return Color(153, 204, 255);
rpm-build 9243a4
  case 0x32:
rpm-build 9243a4
    return Color(51, 51, 153);
rpm-build 9243a4
  case 0x33:
rpm-build 9243a4
    return Color(102, 102, 153);
rpm-build 9243a4
  case 0x34:
rpm-build 9243a4
    return Color(153, 51, 102);
rpm-build 9243a4
  case 0x35:
rpm-build 9243a4
    return Color(204, 153, 255);
rpm-build 9243a4
  case 0x36:
rpm-build 9243a4
    return Color(51, 51, 51);
rpm-build 9243a4
  case 0x37:
rpm-build 9243a4
    return Color(150, 150, 150);
rpm-build 9243a4
  default:
rpm-build 9243a4
    return Color();
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
// takes a color reference in 2k format and translates it into 2k2 format that collector understands.
rpm-build 9243a4
unsigned MSPUBParser2k::translate2kColorReference(unsigned ref2k)
rpm-build 9243a4
{
rpm-build 9243a4
  switch ((ref2k >> 24) & 0xFF)
rpm-build 9243a4
  {
rpm-build 9243a4
  case 0xC0: //index into user palette
rpm-build 9243a4
  case 0xE0:
rpm-build 9243a4
    return (ref2k & 0xFF) | (0x08 << 24);
rpm-build 9243a4
  default:
rpm-build 9243a4
  {
rpm-build 9243a4
    Color c = getColorBy2kHex(ref2k);
rpm-build 9243a4
    return (c.r) | (c.g << 8) | (c.b << 16);
rpm-build 9243a4
  }
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
//FIXME: Valek found different values; what does this depend on?
rpm-build 9243a4
ShapeType MSPUBParser2k::getShapeType(unsigned char shapeSpecifier)
rpm-build 9243a4
{
rpm-build 9243a4
  switch (shapeSpecifier)
rpm-build 9243a4
  {
rpm-build 9243a4
  case 0x1:
rpm-build 9243a4
    return RIGHT_TRIANGLE;
rpm-build 9243a4
  /*
rpm-build 9243a4
  case 0x2:
rpm-build 9243a4
    return GENERAL_TRIANGLE;
rpm-build 9243a4
  */
rpm-build 9243a4
  case 0x3:
rpm-build 9243a4
    return UP_ARROW;
rpm-build 9243a4
  case 0x4:
rpm-build 9243a4
    return STAR;
rpm-build 9243a4
  case 0x5:
rpm-build 9243a4
    return HEART;
rpm-build 9243a4
  case 0x6:
rpm-build 9243a4
    return ISOCELES_TRIANGLE;
rpm-build 9243a4
  case 0x7:
rpm-build 9243a4
    return PARALLELOGRAM;
rpm-build 9243a4
  /*
rpm-build 9243a4
  case 0x8:
rpm-build 9243a4
    return TILTED_TRAPEZOID;
rpm-build 9243a4
  */
rpm-build 9243a4
  case 0x9:
rpm-build 9243a4
    return UP_DOWN_ARROW;
rpm-build 9243a4
  case 0xA:
rpm-build 9243a4
    return SEAL_16;
rpm-build 9243a4
  case 0xB:
rpm-build 9243a4
    return WAVE;
rpm-build 9243a4
  case 0xC:
rpm-build 9243a4
    return DIAMOND;
rpm-build 9243a4
  case 0xD:
rpm-build 9243a4
    return TRAPEZOID;
rpm-build 9243a4
  case 0xE:
rpm-build 9243a4
    return CHEVRON;
rpm-build 9243a4
  case 0xF:
rpm-build 9243a4
    return BENT_ARROW;
rpm-build 9243a4
  case 0x10:
rpm-build 9243a4
    return SEAL_24;
rpm-build 9243a4
  /*
rpm-build 9243a4
  case 0x11:
rpm-build 9243a4
    return PIE;
rpm-build 9243a4
  */
rpm-build 9243a4
  case 0x12:
rpm-build 9243a4
    return PENTAGON;
rpm-build 9243a4
  case 0x13:
rpm-build 9243a4
    return HOME_PLATE;
rpm-build 9243a4
  /*
rpm-build 9243a4
  case 0x14:
rpm-build 9243a4
    return NOTCHED_TRIANGLE;
rpm-build 9243a4
  */
rpm-build 9243a4
  case 0x15:
rpm-build 9243a4
    return U_TURN_ARROW;
rpm-build 9243a4
  case 0x16:
rpm-build 9243a4
    return IRREGULAR_SEAL_1;
rpm-build 9243a4
  /*
rpm-build 9243a4
  case 0x17:
rpm-build 9243a4
    return CHORD;
rpm-build 9243a4
  */
rpm-build 9243a4
  case 0x18:
rpm-build 9243a4
    return HEXAGON;
rpm-build 9243a4
  /*
rpm-build 9243a4
  case 0x19:
rpm-build 9243a4
    return NOTCHED_RECTANGLE;
rpm-build 9243a4
  */
rpm-build 9243a4
  /*
rpm-build 9243a4
  case 0x1A:
rpm-build 9243a4
    return W_SHAPE; //This is a bizarre shape; the number of vertices depends on one of the adjust values.
rpm-build 9243a4
                    //We need to refactor our escher shape drawing routines before we can handle it.
rpm-build 9243a4
  */
rpm-build 9243a4
  /*
rpm-build 9243a4
  case 0x1B:
rpm-build 9243a4
    return ROUND_RECT_CALLOUT_2K; //This is not quite the same as the round rect. found in 2k2 and above.
rpm-build 9243a4
  */
rpm-build 9243a4
  case 0x1C:
rpm-build 9243a4
    return IRREGULAR_SEAL_2;
rpm-build 9243a4
  case 0x1D:
rpm-build 9243a4
    return BLOCK_ARC;
rpm-build 9243a4
  case 0x1E:
rpm-build 9243a4
    return OCTAGON;
rpm-build 9243a4
  case 0x1F:
rpm-build 9243a4
    return PLUS;
rpm-build 9243a4
  case 0x20:
rpm-build 9243a4
    return CUBE;
rpm-build 9243a4
  /*
rpm-build 9243a4
  case 0x21:
rpm-build 9243a4
    return OVAL_CALLOUT_2K; //Not sure yet if this is the same as the 2k2 one.
rpm-build 9243a4
  */
rpm-build 9243a4
  case 0x22:
rpm-build 9243a4
    return LIGHTNING_BOLT;
rpm-build 9243a4
  default:
rpm-build 9243a4
    return UNKNOWN_SHAPE;
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
void MSPUBParser2k::parseContentsTextIfNecessary(librevenge::RVNGInputStream *)
rpm-build 9243a4
{
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
bool MSPUBParser2k::parseContents(librevenge::RVNGInputStream *input)
rpm-build 9243a4
{
rpm-build 9243a4
  parseContentsTextIfNecessary(input);
rpm-build 9243a4
  input->seek(0x16, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
  unsigned trailerOffset = readU32(input);
rpm-build 9243a4
  input->seek(trailerOffset, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
  unsigned numBlocks = readU16(input);
rpm-build 9243a4
  unsigned chunkOffset = 0;
rpm-build 9243a4
  for (unsigned i = 0; i < numBlocks; ++i)
rpm-build 9243a4
  {
rpm-build 9243a4
    input->seek(input->tell() + 2, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
    unsigned short id = readU16(input);
rpm-build 9243a4
    unsigned short parent = readU16(input);
rpm-build 9243a4
    chunkOffset = readU32(input);
rpm-build 9243a4
    if (m_contentChunks.size() > 0)
rpm-build 9243a4
    {
rpm-build 9243a4
      m_contentChunks.back().end = chunkOffset;
rpm-build 9243a4
    }
rpm-build 9243a4
    unsigned offset = input->tell();
rpm-build 9243a4
    input->seek(chunkOffset, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
    unsigned short typeMarker = readU16(input);
rpm-build 9243a4
    input->seek(offset, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
    switch (typeMarker)
rpm-build 9243a4
    {
rpm-build 9243a4
    case 0x0014:
rpm-build 9243a4
      MSPUB_DEBUG_MSG(("Found page chunk of id 0x%x and parent 0x%x\n", id, parent));
rpm-build 9243a4
      m_contentChunks.push_back(ContentChunkReference(PAGE, chunkOffset, 0, id, parent));
rpm-build 9243a4
      m_pageChunkIndices.push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      m_chunkChildIndicesById[parent].push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      break;
rpm-build 9243a4
    case 0x0015:
rpm-build 9243a4
      MSPUB_DEBUG_MSG(("Found document chunk of id 0x%x and parent 0x%x\n", id, parent));
rpm-build 9243a4
      m_contentChunks.push_back(ContentChunkReference(DOCUMENT, chunkOffset, 0, id, parent));
rpm-build 9243a4
      m_documentChunkIndex = unsigned(m_contentChunks.size() - 1);
rpm-build 9243a4
      m_chunkChildIndicesById[parent].push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      break;
rpm-build 9243a4
    case 0x0002:
rpm-build 9243a4
      MSPUB_DEBUG_MSG(("Found image_2k chunk of id 0x%x and parent 0x%x\n", id, parent));
rpm-build 9243a4
      m_contentChunks.push_back(ContentChunkReference(IMAGE_2K, chunkOffset, 0, id, parent));
rpm-build 9243a4
      m_shapeChunkIndices.push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      m_chunkChildIndicesById[parent].push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      break;
rpm-build 9243a4
    case 0x0021:
rpm-build 9243a4
      MSPUB_DEBUG_MSG(("Found image_2k_data chunk of id 0x%x and parent 0x%x\n", id, parent));
rpm-build 9243a4
      m_contentChunks.push_back(ContentChunkReference(IMAGE_2K_DATA, chunkOffset, 0, id, parent));
rpm-build 9243a4
      m_imageDataChunkIndices.push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      m_chunkChildIndicesById[parent].push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      break;
rpm-build 9243a4
    case 0x0000:
rpm-build 9243a4
    case 0x0004:
rpm-build 9243a4
    case 0x0005:
rpm-build 9243a4
    case 0x0006:
rpm-build 9243a4
    case 0x0007:
rpm-build 9243a4
    case 0x0008:
rpm-build 9243a4
      MSPUB_DEBUG_MSG(("Found shape chunk of id 0x%x and parent 0x%x\n", id, parent));
rpm-build 9243a4
      m_contentChunks.push_back(ContentChunkReference(SHAPE, chunkOffset, 0, id, parent));
rpm-build 9243a4
      m_shapeChunkIndices.push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      m_chunkChildIndicesById[parent].push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      break;
rpm-build 9243a4
    case 0x0047:
rpm-build 9243a4
      MSPUB_DEBUG_MSG(("Found palette chunk of id 0x%x and parent 0x%x\n", id, parent));
rpm-build 9243a4
      m_contentChunks.push_back(ContentChunkReference(PALETTE, chunkOffset, 0, id, parent));
rpm-build 9243a4
      m_paletteChunkIndices.push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      m_chunkChildIndicesById[parent].push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      break;
rpm-build 9243a4
    case 0x000F:
rpm-build 9243a4
      MSPUB_DEBUG_MSG(("Found group chunk of id 0x%x and parent 0x%x\n", id, parent));
rpm-build 9243a4
      m_contentChunks.push_back(ContentChunkReference(GROUP, chunkOffset, 0, id, parent));
rpm-build 9243a4
      m_shapeChunkIndices.push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      m_chunkChildIndicesById[parent].push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      break;
rpm-build 9243a4
    default:
rpm-build 9243a4
      MSPUB_DEBUG_MSG(("Found unknown chunk of id 0x%x and parent 0x%x\n", id, parent));
rpm-build 9243a4
      m_contentChunks.push_back(ContentChunkReference(UNKNOWN_CHUNK, chunkOffset, 0, id, parent));
rpm-build 9243a4
      m_unknownChunkIndices.push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      m_chunkChildIndicesById[parent].push_back(unsigned(m_contentChunks.size() - 1));
rpm-build 9243a4
      break;
rpm-build 9243a4
    }
rpm-build 9243a4
  }
rpm-build 9243a4
  if (m_contentChunks.size() > 0)
rpm-build 9243a4
  {
rpm-build 9243a4
    m_contentChunks.back().end = chunkOffset;
rpm-build 9243a4
  }
rpm-build 9243a4
rpm-build 9243a4
  if (!parseDocument(input))
rpm-build 9243a4
  {
rpm-build 9243a4
    MSPUB_DEBUG_MSG(("No document chunk found.\n"));
rpm-build 9243a4
    return false;
rpm-build 9243a4
  }
rpm-build 9243a4
rpm-build 9243a4
rpm-build 9243a4
  for (unsigned int paletteChunkIndex : m_paletteChunkIndices)
rpm-build 9243a4
  {
rpm-build 9243a4
    const ContentChunkReference &chunk = m_contentChunks.at(paletteChunkIndex);
rpm-build 9243a4
    input->seek(chunk.offset, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
    input->seek(0xA0, librevenge::RVNG_SEEK_CUR);
rpm-build 9243a4
    for (unsigned j = 0; j < 8; ++j)
rpm-build 9243a4
    {
rpm-build 9243a4
      unsigned hex = readU32(input);
rpm-build 9243a4
      Color color = getColorBy2kHex(hex);
rpm-build 9243a4
      m_collector->addPaletteColor(color);
rpm-build 9243a4
    }
rpm-build 9243a4
  }
rpm-build 9243a4
rpm-build 9243a4
  for (unsigned int imageDataChunkIndex : m_imageDataChunkIndices)
rpm-build 9243a4
  {
rpm-build 9243a4
    const ContentChunkReference &chunk = m_contentChunks.at(imageDataChunkIndex);
rpm-build 9243a4
    input->seek(chunk.offset + 4, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
    unsigned toRead = readU32(input);
rpm-build 9243a4
    librevenge::RVNGBinaryData img;
rpm-build 9243a4
    while (toRead > 0 && stillReading(input, (unsigned long)-1))
rpm-build 9243a4
    {
rpm-build 9243a4
      unsigned long howManyRead = 0;
rpm-build 9243a4
      const unsigned char *buf = input->read(toRead, howManyRead);
rpm-build 9243a4
      img.append(buf, howManyRead);
rpm-build 9243a4
      toRead -= howManyRead;
rpm-build 9243a4
    }
rpm-build 9243a4
    m_collector->addImage(++m_lastAddedImage, WMF, img);
rpm-build 9243a4
  }
rpm-build 9243a4
rpm-build 9243a4
  for (unsigned int shapeChunkIndex : m_shapeChunkIndices)
rpm-build 9243a4
  {
rpm-build 9243a4
    parse2kShapeChunk(m_contentChunks.at(shapeChunkIndex), input);
rpm-build 9243a4
  }
rpm-build 9243a4
rpm-build 9243a4
  return true;
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
bool MSPUBParser2k::parseDocument(librevenge::RVNGInputStream *input)
rpm-build 9243a4
{
rpm-build 9243a4
  if (bool(m_documentChunkIndex))
rpm-build 9243a4
  {
rpm-build 9243a4
    input->seek(m_contentChunks[m_documentChunkIndex.get()].offset, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
    input->seek(0x14, librevenge::RVNG_SEEK_CUR);
rpm-build 9243a4
    unsigned width = readU32(input);
rpm-build 9243a4
    unsigned height = readU32(input);
rpm-build 9243a4
    m_collector->setWidthInEmu(width);
rpm-build 9243a4
    m_collector->setHeightInEmu(height);
rpm-build 9243a4
    return true;
rpm-build 9243a4
  }
rpm-build 9243a4
  return false;
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
void MSPUBParser2k::parseShapeRotation(librevenge::RVNGInputStream *input, bool isGroup, bool isLine,
rpm-build 9243a4
                                       unsigned seqNum, unsigned chunkOffset)
rpm-build 9243a4
{
rpm-build 9243a4
  input->seek(chunkOffset + 4, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
  // shape transforms are NOT compounded with group transforms. They are equal to what they would be
rpm-build 9243a4
  // if the shape were not part of a group at all. This is different from how MSPUBCollector handles rotations;
rpm-build 9243a4
  // we work around the issue by simply not setting the rotation of any group, thereby letting it default to zero.
rpm-build 9243a4
  //
rpm-build 9243a4
  // Furthermore, line rotations are redundant and need to be treated as zero.
rpm-build 9243a4
  unsigned short counterRotationInDegreeTenths = readU16(input);
rpm-build 9243a4
  if (!isGroup && !isLine)
rpm-build 9243a4
  {
rpm-build 9243a4
    m_collector->setShapeRotation(seqNum, 360. - double(counterRotationInDegreeTenths) / 10);
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
bool MSPUBParser2k::parse2kShapeChunk(const ContentChunkReference &chunk, librevenge::RVNGInputStream *input,
rpm-build 9243a4
                                      boost::optional<unsigned> pageSeqNum, bool topLevelCall)
rpm-build 9243a4
{
rpm-build 9243a4
  if (find(m_chunksBeingRead.begin(), m_chunksBeingRead.end(), chunk.seqNum) != m_chunksBeingRead.end())
rpm-build 9243a4
  {
rpm-build 9243a4
    MSPUB_DEBUG_MSG(("chunk %u is nested in itself", chunk.seqNum));
rpm-build 9243a4
    return false;
rpm-build 9243a4
  }
rpm-build 9243a4
  const ChunkNestingGuard guard(m_chunksBeingRead, chunk.seqNum);
rpm-build 9243a4
rpm-build 9243a4
  unsigned page = pageSeqNum.get_value_or(chunk.parentSeqNum);
rpm-build 9243a4
  input->seek(chunk.offset, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
  if (topLevelCall)
rpm-build 9243a4
  {
rpm-build 9243a4
    // ignore non top level shapes
rpm-build 9243a4
    int i_page = -1;
rpm-build 9243a4
    for (unsigned int pageIndex : m_pageChunkIndices)
rpm-build 9243a4
    {
rpm-build 9243a4
      if (m_contentChunks.at(pageIndex).seqNum == chunk.parentSeqNum)
rpm-build 9243a4
      {
rpm-build 9243a4
        i_page = pageIndex;
rpm-build 9243a4
        break;
rpm-build 9243a4
      }
rpm-build 9243a4
    }
rpm-build 9243a4
    if (i_page == -1)
rpm-build 9243a4
    {
rpm-build 9243a4
      return false;
rpm-build 9243a4
    }
rpm-build 9243a4
    if (getPageTypeBySeqNum(m_contentChunks[i_page].seqNum) != NORMAL)
rpm-build 9243a4
    {
rpm-build 9243a4
      return false;
rpm-build 9243a4
    }
rpm-build 9243a4
    // if the parent of this is a page and hasn't yet been added, then add it.
rpm-build 9243a4
    if (!m_collector->hasPage(chunk.parentSeqNum))
rpm-build 9243a4
    {
rpm-build 9243a4
      m_collector->addPage(chunk.parentSeqNum);
rpm-build 9243a4
    }
rpm-build 9243a4
  }
rpm-build 9243a4
  m_collector->setShapePage(chunk.seqNum, page);
rpm-build 9243a4
  m_collector->setShapeBorderPosition(chunk.seqNum, INSIDE_SHAPE); // This appears to be the only possibility for MSPUB2k
rpm-build 9243a4
  bool isImage = false;
rpm-build 9243a4
  bool isRectangle = false;
rpm-build 9243a4
  bool isGroup = false;
rpm-build 9243a4
  bool isLine = false;
rpm-build 9243a4
  unsigned flagsOffset(0); // ? why was this changed from boost::optional ?
rpm-build 9243a4
  parseShapeType(input, chunk.seqNum, chunk.offset, isGroup, isLine, isImage, isRectangle, flagsOffset);
rpm-build 9243a4
  parseShapeRotation(input, isGroup, isLine, chunk.seqNum, chunk.offset);
rpm-build 9243a4
  parseShapeCoordinates(input, chunk.seqNum, chunk.offset);
rpm-build 9243a4
  parseShapeFlips(input, flagsOffset, chunk.seqNum, chunk.offset);
rpm-build 9243a4
  if (isGroup)
rpm-build 9243a4
  {
rpm-build 9243a4
    return parseGroup(input, chunk.seqNum, page);
rpm-build 9243a4
  }
rpm-build 9243a4
  if (isImage)
rpm-build 9243a4
  {
rpm-build 9243a4
    assignShapeImgIndex(chunk.seqNum);
rpm-build 9243a4
  }
rpm-build 9243a4
  else
rpm-build 9243a4
  {
rpm-build 9243a4
    parseShapeFill(input, chunk.seqNum, chunk.offset);
rpm-build 9243a4
  }
rpm-build 9243a4
  parseShapeLine(input, isRectangle, chunk.offset, chunk.seqNum);
rpm-build 9243a4
  m_collector->setShapeOrder(chunk.seqNum);
rpm-build 9243a4
  return true;
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
unsigned MSPUBParser2k::getShapeFillTypeOffset() const
rpm-build 9243a4
{
rpm-build 9243a4
  return 0x2A;
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
unsigned MSPUBParser2k::getShapeFillColorOffset() const
rpm-build 9243a4
{
rpm-build 9243a4
  return 0x22;
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
void MSPUBParser2k::parseShapeFill(librevenge::RVNGInputStream *input, unsigned seqNum, unsigned chunkOffset)
rpm-build 9243a4
{
rpm-build 9243a4
  input->seek(chunkOffset + getShapeFillTypeOffset(), librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
  unsigned char fillType = readU8(input);
rpm-build 9243a4
  if (fillType == 2) // other types are gradients and patterns which are not implemented yet. 0 is no fill.
rpm-build 9243a4
  {
rpm-build 9243a4
    input->seek(chunkOffset + getShapeFillColorOffset(), librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
    unsigned fillColorReference = readU32(input);
rpm-build 9243a4
    unsigned translatedFillColorReference = translate2kColorReference(fillColorReference);
rpm-build 9243a4
    m_collector->setShapeFill(seqNum, std::shared_ptr<Fill>(new SolidFill(ColorReference(translatedFillColorReference), 1, m_collector)), false);
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
bool MSPUBParser2k::parseGroup(librevenge::RVNGInputStream *input, unsigned seqNum, unsigned page)
rpm-build 9243a4
{
rpm-build 9243a4
  bool retVal = true;
rpm-build 9243a4
  m_collector->beginGroup();
rpm-build 9243a4
  m_collector->setCurrentGroupSeqNum(seqNum);
rpm-build 9243a4
  const std::map<unsigned, std::vector<unsigned> >::const_iterator it = m_chunkChildIndicesById.find(seqNum);
rpm-build 9243a4
  if (it != m_chunkChildIndicesById.end())
rpm-build 9243a4
  {
rpm-build 9243a4
    const std::vector<unsigned> &chunkChildIndices = it->second;
rpm-build 9243a4
    for (unsigned int chunkChildIndex : chunkChildIndices)
rpm-build 9243a4
    {
rpm-build 9243a4
      const ContentChunkReference &childChunk = m_contentChunks.at(chunkChildIndex);
rpm-build 9243a4
      if (childChunk.type == SHAPE || childChunk.type == GROUP)
rpm-build 9243a4
      {
rpm-build 9243a4
        retVal = retVal && parse2kShapeChunk(childChunk, input, page, false);
rpm-build 9243a4
      }
rpm-build 9243a4
    }
rpm-build 9243a4
  }
rpm-build 9243a4
  m_collector->endGroup();
rpm-build 9243a4
  return retVal;
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
void MSPUBParser2k::assignShapeImgIndex(unsigned seqNum)
rpm-build 9243a4
{
rpm-build 9243a4
  int i_dataIndex = -1;
rpm-build 9243a4
  for (unsigned j = 0; j < m_imageDataChunkIndices.size(); ++j)
rpm-build 9243a4
  {
rpm-build 9243a4
    if (m_contentChunks.at(m_imageDataChunkIndices[j]).parentSeqNum == seqNum)
rpm-build 9243a4
    {
rpm-build 9243a4
      i_dataIndex = j;
rpm-build 9243a4
      break;
rpm-build 9243a4
    }
rpm-build 9243a4
  }
rpm-build 9243a4
  if (i_dataIndex >= 0)
rpm-build 9243a4
  {
rpm-build 9243a4
    m_collector->setShapeImgIndex(seqNum, i_dataIndex + 1);
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
void MSPUBParser2k::parseShapeCoordinates(librevenge::RVNGInputStream *input, unsigned seqNum,
rpm-build 9243a4
                                          unsigned chunkOffset)
rpm-build 9243a4
{
rpm-build 9243a4
  input->seek(chunkOffset + 6, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
  int xs = translateCoordinateIfNecessary(readS32(input));
rpm-build 9243a4
  int ys = translateCoordinateIfNecessary(readS32(input));
rpm-build 9243a4
  int xe = translateCoordinateIfNecessary(readS32(input));
rpm-build 9243a4
  int ye = translateCoordinateIfNecessary(readS32(input));
rpm-build 9243a4
  m_collector->setShapeCoordinatesInEmu(seqNum, xs, ys, xe, ye);
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
int MSPUBParser2k::translateCoordinateIfNecessary(int coordinate) const
rpm-build 9243a4
{
rpm-build 9243a4
  return coordinate;
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
void MSPUBParser2k::parseShapeFlips(librevenge::RVNGInputStream *input, unsigned flagsOffset, unsigned seqNum,
rpm-build 9243a4
                                    unsigned chunkOffset)
rpm-build 9243a4
{
rpm-build 9243a4
  if (flagsOffset)
rpm-build 9243a4
  {
rpm-build 9243a4
    input->seek(chunkOffset + flagsOffset, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
    unsigned char flags = readU8(input);
rpm-build 9243a4
    bool flipV = flags & 0x1;
rpm-build 9243a4
    bool flipH = flags & (0x2 | 0x10); // FIXME: this is a guess
rpm-build 9243a4
    m_collector->setShapeFlip(seqNum, flipV, flipH);
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
void MSPUBParser2k::parseShapeType(librevenge::RVNGInputStream *input,
rpm-build 9243a4
                                   unsigned seqNum, unsigned chunkOffset,
rpm-build 9243a4
                                   bool &isGroup, bool &isLine, bool &isImage, bool &isRectangle,
rpm-build 9243a4
                                   unsigned &flagsOffset)
rpm-build 9243a4
{
rpm-build 9243a4
  input->seek(chunkOffset, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
  unsigned short typeMarker = readU16(input);
rpm-build 9243a4
  if (typeMarker == 0x000f)
rpm-build 9243a4
  {
rpm-build 9243a4
    isGroup = true;
rpm-build 9243a4
  }
rpm-build 9243a4
  else if (typeMarker == 0x0004)
rpm-build 9243a4
  {
rpm-build 9243a4
    isLine = true;
rpm-build 9243a4
    flagsOffset = 0x41;
rpm-build 9243a4
    m_collector->setShapeType(seqNum, LINE);
rpm-build 9243a4
  }
rpm-build 9243a4
  else if (typeMarker == 0x0002)
rpm-build 9243a4
  {
rpm-build 9243a4
    isImage = true;
rpm-build 9243a4
    m_collector->setShapeType(seqNum, RECTANGLE);
rpm-build 9243a4
    isRectangle = true;
rpm-build 9243a4
  }
rpm-build 9243a4
  else if (typeMarker == 0x0005)
rpm-build 9243a4
  {
rpm-build 9243a4
    m_collector->setShapeType(seqNum, RECTANGLE);
rpm-build 9243a4
    isRectangle = true;
rpm-build 9243a4
  }
rpm-build 9243a4
  else if (typeMarker == 0x0006)
rpm-build 9243a4
  {
rpm-build 9243a4
    input->seek(chunkOffset + 0x31, librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
    ShapeType shapeType = getShapeType(readU8(input));
rpm-build 9243a4
    flagsOffset = 0x33;
rpm-build 9243a4
    if (shapeType != UNKNOWN_SHAPE)
rpm-build 9243a4
    {
rpm-build 9243a4
      m_collector->setShapeType(seqNum, shapeType);
rpm-build 9243a4
    }
rpm-build 9243a4
  }
rpm-build 9243a4
  else if (typeMarker == 0x0007)
rpm-build 9243a4
  {
rpm-build 9243a4
    m_collector->setShapeType(seqNum, ELLIPSE);
rpm-build 9243a4
  }
rpm-build 9243a4
  else if (typeMarker == getTextMarker())
rpm-build 9243a4
  {
rpm-build 9243a4
    m_collector->setShapeType(seqNum, RECTANGLE);
rpm-build 9243a4
    isRectangle = true;
rpm-build 9243a4
    input->seek(chunkOffset + getTextIdOffset(), librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
    unsigned txtId = readU16(input);
rpm-build 9243a4
    m_collector->addTextShape(txtId, seqNum);
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
unsigned MSPUBParser2k::getTextIdOffset() const
rpm-build 9243a4
{
rpm-build 9243a4
  return 0x58;
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
unsigned short MSPUBParser2k::getTextMarker() const
rpm-build 9243a4
{
rpm-build 9243a4
  return 0x0008;
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
unsigned MSPUBParser2k::getFirstLineOffset() const
rpm-build 9243a4
{
rpm-build 9243a4
  return 0x2C;
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
unsigned MSPUBParser2k::getSecondLineOffset() const
rpm-build 9243a4
{
rpm-build 9243a4
  return 0x35;
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
void MSPUBParser2k::parseShapeLine(librevenge::RVNGInputStream *input, bool isRectangle, unsigned offset,
rpm-build 9243a4
                                   unsigned seqNum)
rpm-build 9243a4
{
rpm-build 9243a4
  input->seek(offset + getFirstLineOffset(), librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
  unsigned short leftLineWidth = readU8(input);
rpm-build 9243a4
  bool leftLineExists = leftLineWidth != 0;
rpm-build 9243a4
  unsigned leftColorReference = readU32(input);
rpm-build 9243a4
  unsigned translatedLeftColorReference = translate2kColorReference(leftColorReference);
rpm-build 9243a4
  if (isRectangle)
rpm-build 9243a4
  {
rpm-build 9243a4
    input->seek(offset + getSecondLineOffset(), librevenge::RVNG_SEEK_SET);
rpm-build 9243a4
    unsigned char topLineWidth = readU8(input);
rpm-build 9243a4
    bool topLineExists = topLineWidth != 0;
rpm-build 9243a4
    unsigned topColorReference = readU32(input);
rpm-build 9243a4
    unsigned translatedTopColorReference = translate2kColorReference(topColorReference);
rpm-build 9243a4
    m_collector->addShapeLine(seqNum, Line(ColorReference(translatedTopColorReference),
rpm-build 9243a4
                                           translateLineWidth(topLineWidth) * EMUS_IN_INCH / (4 * POINTS_IN_INCH), topLineExists));
rpm-build 9243a4
rpm-build 9243a4
    input->seek(1, librevenge::RVNG_SEEK_CUR);
rpm-build 9243a4
    unsigned char rightLineWidth = readU8(input);
rpm-build 9243a4
    bool rightLineExists = rightLineWidth != 0;
rpm-build 9243a4
    unsigned rightColorReference = readU32(input);
rpm-build 9243a4
    unsigned translatedRightColorReference = translate2kColorReference(rightColorReference);
rpm-build 9243a4
    m_collector->addShapeLine(seqNum, Line(ColorReference(translatedRightColorReference),
rpm-build 9243a4
                                           translateLineWidth(rightLineWidth) * EMUS_IN_INCH / (4 * POINTS_IN_INCH), rightLineExists));
rpm-build 9243a4
rpm-build 9243a4
    input->seek(1, librevenge::RVNG_SEEK_CUR);
rpm-build 9243a4
    unsigned char bottomLineWidth = readU8(input);
rpm-build 9243a4
    bool bottomLineExists = bottomLineWidth != 0;
rpm-build 9243a4
    unsigned bottomColorReference = readU32(input);
rpm-build 9243a4
    unsigned translatedBottomColorReference = translate2kColorReference(bottomColorReference);
rpm-build 9243a4
    m_collector->addShapeLine(seqNum, Line(ColorReference(translatedBottomColorReference),
rpm-build 9243a4
                                           translateLineWidth(bottomLineWidth) * EMUS_IN_INCH / (4 * POINTS_IN_INCH), bottomLineExists));
rpm-build 9243a4
  }
rpm-build 9243a4
  m_collector->addShapeLine(seqNum, Line(ColorReference(translatedLeftColorReference),
rpm-build 9243a4
                                         translateLineWidth(leftLineWidth) * EMUS_IN_INCH / (4 * POINTS_IN_INCH), leftLineExists));
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
bool MSPUBParser2k::parse()
rpm-build 9243a4
{
rpm-build 9243a4
  std::unique_ptr<librevenge::RVNGInputStream> contents(m_input->getSubStreamByName("Contents"));
rpm-build 9243a4
  if (!contents)
rpm-build 9243a4
  {
rpm-build 9243a4
    MSPUB_DEBUG_MSG(("Couldn't get contents stream.\n"));
rpm-build 9243a4
    return false;
rpm-build 9243a4
  }
rpm-build 9243a4
  if (!parseContents(contents.get()))
rpm-build 9243a4
  {
rpm-build 9243a4
    MSPUB_DEBUG_MSG(("Couldn't parse contents stream.\n"));
rpm-build 9243a4
    return false;
rpm-build 9243a4
  }
rpm-build 9243a4
  std::unique_ptr<librevenge::RVNGInputStream> quill(m_input->getSubStreamByName("Quill/QuillSub/CONTENTS"));
rpm-build 9243a4
  if (!quill)
rpm-build 9243a4
  {
rpm-build 9243a4
    MSPUB_DEBUG_MSG(("Couldn't get quill stream.\n"));
rpm-build 9243a4
    return false;
rpm-build 9243a4
  }
rpm-build 9243a4
  if (!parseQuill(quill.get()))
rpm-build 9243a4
  {
rpm-build 9243a4
    MSPUB_DEBUG_MSG(("Couldn't parse quill stream.\n"));
rpm-build 9243a4
    return false;
rpm-build 9243a4
  }
rpm-build 9243a4
  return m_collector->go();
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
PageType MSPUBParser2k::getPageTypeBySeqNum(unsigned seqNum)
rpm-build 9243a4
{
rpm-build 9243a4
  switch (seqNum)
rpm-build 9243a4
  {
rpm-build 9243a4
  case 0x116:
rpm-build 9243a4
  case 0x108:
rpm-build 9243a4
  case 0x10B:
rpm-build 9243a4
  case 0x10D:
rpm-build 9243a4
  case 0x119:
rpm-build 9243a4
    return DUMMY_PAGE;
rpm-build 9243a4
  case 0x109:
rpm-build 9243a4
    return MASTER;
rpm-build 9243a4
  default:
rpm-build 9243a4
    return NORMAL;
rpm-build 9243a4
  }
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
}
rpm-build 9243a4
rpm-build 9243a4
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */