uint8_t readU8(const RVNGInputStreamPtr &input, bool /* bigEndian */)
{
  checkStream(input);

  unsigned long numBytesRead;
  uint8_t const *p = input->read(sizeof(uint8_t), numBytesRead);

  if (p && numBytesRead == sizeof(uint8_t))
    return *(uint8_t const *)(p);
  throw EndOfStreamException();
}
uint64_t readU64(const RVNGInputStreamPtr &input, bool bigEndian)
{
  checkStream(input);

  unsigned long numBytesRead;
  uint8_t const *p = input->read(sizeof(uint64_t), numBytesRead);

  if (p && numBytesRead == sizeof(uint64_t))
  {
    if (bigEndian)
      return (uint64_t)p[7]|((uint64_t)p[6]<<8)|((uint64_t)p[5]<<16)|((uint64_t)p[4]<<24)|((uint64_t)p[3]<<32)|((uint64_t)p[2]<<40)|((uint64_t)p[1]<<48)|((uint64_t)p[0]<<56);
    return (uint64_t)p[0]|((uint64_t)p[1]<<8)|((uint64_t)p[2]<<16)|((uint64_t)p[3]<<24)|((uint64_t)p[4]<<32)|((uint64_t)p[5]<<40)|((uint64_t)p[6]<<48)|((uint64_t)p[7]<<56);
  }
  throw EndOfStreamException();
}
uint16_t readU16(const RVNGInputStreamPtr &input, bool bigEndian)
{
  checkStream(input);

  unsigned long numBytesRead;
  uint8_t const *p = input->read(sizeof(uint16_t), numBytesRead);

  if (p && numBytesRead == sizeof(uint16_t))
  {
    if (bigEndian)
      return static_cast<uint16_t>((uint16_t)p[1]|((uint16_t)p[0]<<8));
    return static_cast<uint16_t>((uint16_t)p[0]|((uint16_t)p[1]<<8));
  }
  throw EndOfStreamException();
}
Esempio n. 4
0
void DosWordParser::readPAP(uint32_t fcFirst, uint32_t fcLim, unsigned cch)
{
	RVNGInputStreamPtr input = getInput();

	DosWordParserInternal::PAP pap;

	WPS_LE_PUT_GUINT16(&pap.m_dyaLine, 240);

	if (cch)
	{
		if (cch > sizeof(pap))
			cch = sizeof(pap);

		unsigned long read_bytes;
		const unsigned char *p = input->read(cch, read_bytes);
		if (read_bytes != cch)
		{
			WPS_DEBUG_MSG(("DosWordParser::readPAP failed to read PAP\n"));
			throw (libwps::ParseException());
		}

		memcpy(&pap, p, cch);
	}

	int16_t dxaLeft = (int16_t) WPS_LE_GET_GUINT16(&pap.m_dxaLeft);
	int16_t dxaLeft1 = (int16_t) WPS_LE_GET_GUINT16(&pap.m_dxaLeft1);
	int16_t dxaRight = (int16_t) WPS_LE_GET_GUINT16(&pap.m_dxaRight);

	MSWriteParserInternal::Paragraph para;
	int i;

	for (i=0; i<20; i++)
	{
		uint16_t pos = WPS_LE_GET_GUINT16(&pap.m_TBD[i].m_dxa);

		if (!pos)
			break;

		WPSTabStop::Alignment align;

		switch (pap.m_TBD[i].m_jcTab & 3)
		{
		default:
		case 0:
			align = WPSTabStop::LEFT;
			break;
		case 1:
			align = WPSTabStop::CENTER;
			break;
		case 2:
			align = WPSTabStop::RIGHT;
			break;
		case 3:
			align = WPSTabStop::DECIMAL;
			break;
		}

		unsigned leader = (pap.m_TBD[i].m_jcTab >> 3) & 3;
		WPSTabStop tab(pos / 1440., align, uint16_t("\0.-_"[leader]));

		para.m_tabs.push_back(tab);

		if (dxaLeft + dxaLeft1 == pos)
			para.m_skiptab = true;
	}

	switch (pap.m_justification & 3)
	{
	default:
	case 0:
		para.m_justify = libwps::JustificationLeft;
		break;
	case 1:
		para.m_justify = libwps::JustificationCenter;
		break;
	case 2:
		para.m_justify = libwps::JustificationRight;
		break;
	case 3:
		para.m_justify = libwps::JustificationFull;
		break;
	}

	para.m_margins[0] = dxaLeft1 / 1440.0;
	para.m_margins[1] = dxaLeft / 1440.0;
	para.m_margins[2] = dxaRight / 1440.0;

	// spacings
	int16_t dyaLine = (int16_t) WPS_LE_GET_GUINT16(&pap.m_dyaLine);
	uint16_t dyaBefore = WPS_LE_GET_GUINT16(&pap.m_dyaBefore);
	uint16_t dyaAfter = WPS_LE_GET_GUINT16(&pap.m_dyaAfter);
	// dyaLine = -40 means "auto"
	if (dyaLine > 0)
		para.m_spacings[0] = dyaLine / 240.0;
	para.m_spacings[1] = dyaBefore / 240.0;
	para.m_spacings[2] = dyaAfter / 240.0;

	para.m_fcFirst = fcFirst;
	para.m_fcLim = fcLim;

	if (pap.m_rhc & 0xe)
	{
		if (pap.m_rhc & 1)
			para.m_Location = MSWriteParserInternal::Paragraph::FOOTER;
		else
			para.m_Location = MSWriteParserInternal::Paragraph::HEADER;

		switch ((pap.m_rhc >> 1) & 3)
		{
		default:
		case 3: // all
			para.m_HeaderFooterOccurrence = WPSPageSpan::ALL;
			break;
		case 2: // even
			para.m_HeaderFooterOccurrence = WPSPageSpan::EVEN;
			break;
		case 1: // odd
			para.m_HeaderFooterOccurrence = WPSPageSpan::ODD;
			break;
		case 0: // never; however might be on first page
			para.m_HeaderFooterOccurrence = WPSPageSpan::NEVER;
			break;
		}

		para.m_firstpage = (pap.m_rhc & 0x08) != 0;
	}

	if (pap.m_justification & 0x20)
		para.m_headerUseMargin = true;

	if (pap.m_style & 1)
	{
		switch (pap.m_style / 2)
		{
		case 39: // footnote
		case 87: // annotation
			para.m_Location = MSWriteParserInternal::Paragraph::FOOTNOTE;
			break;
		default:
			WPS_DEBUG_MSG(("DosWordParser::readPAP pap unknown style stc=%u %x-%x\n", pap.m_style / 2, fcFirst, fcLim));
			break;
		}
	}

	// Borders
	if (pap.m_rhc & 0x30)
	{
		if ((pap.m_rhc & 0x30) == 0x10)
			para.m_border = 15;
		else
			para.m_border = pap.m_border & 15;

		WPSBorder::Type type = WPSBorder::Single;
		int width = 1;

		switch (pap.m_rhc & 0xc0)
		{
		default:
		case 0:	// normal
			break;
		case 0x40: // bold
			width = 2;
			break;
		case 0x80: // Double
			type = WPSBorder::Double;
			break;
		case 0xc0: // thick
			width = 8;
			break;
		}

		para.m_borderStyle.m_type = type;
		para.m_borderStyle.m_width = width;
		para.m_borderStyle.m_color = color((pap.m_border / 16) & 7);
	}

	if (pap.m_justification & 4)
		para.m_breakStatus |= libwps::NoBreakBit;
	if (pap.m_justification & 8)
		para.m_breakStatus |= libwps::NoBreakWithNextBit;

	// paragraph shading
	if (pap.m_shade & 0x7f)
	{
		WPSColor c = color((pap.m_pos >> 4) & 7);

		unsigned percent = std::min(pap.m_shade & 0x7fu, 100u);

		// Use percent to increase brightness
		// 100% means color stays the same
		// 0% means white

		unsigned add = (255 * (100 - percent)) / 100;

		para.m_backgroundColor = WPSColor(
		                             (unsigned char)std::min(c.getRed() + add, 255u),
		                             (unsigned char)std::min(c.getGreen() + add, 255u),
		                             (unsigned char)std::min(c.getBlue() + add, 255u));
	}
Esempio n. 5
0
void DosWordParser::readCHP(uint32_t fcFirst, uint32_t fcLim, unsigned cch)
{
	RVNGInputStreamPtr input = getInput();

	DosWordParserInternal::CHP chp;

	chp.m_hps = 24;

	if (cch)
	{
		if (cch > sizeof(chp))
			cch = sizeof(chp);

		unsigned long read_bytes;
		const unsigned char *p = input->read(cch, read_bytes);
		if (read_bytes != cch)
		{
			WPS_DEBUG_MSG(("DosWordParser::readCHP failed to read CHP entry\n"));
			throw (libwps::ParseException());
		}

		memcpy(&chp, p, cch);
	}

	MSWriteParserInternal::Font font;

	if (chp.m_fStyled & 1)
	{
		switch (chp.m_fStyled / 2)
		{
		case 13: // footnote reference
			font.m_footnote = true;
			break;
		case 26: // annotation reference
			font.m_annotation = true;
			break;
		default:
			WPS_DEBUG_MSG(("Style sheet stc=%u %x-%x\n", chp.m_fStyled / 2, fcFirst, fcLim));
			break;
		}
	}

	unsigned ftc = (chp.m_fBold / 4);

	// Note the font depends on the printer driver
	if (ftc <= 15)
		font.m_name.sprintf("modern %c", 'a' + ftc);
	else if (ftc <= 31)
		font.m_name.sprintf("roman %c", 'a' + (ftc - 16));
	else if (ftc <= 39)
		font.m_name.sprintf("script %c", 'a' + (ftc - 32));
	else if (ftc <= 47)
		font.m_name.sprintf("foreign %c", 'a' + (ftc - 40));
	else if (ftc <= 55)
		font.m_name.sprintf("decor %c", 'a' + (ftc - 48));
	else
		font.m_name.sprintf("symbol %c", 'a' + (ftc - 56));

	font.m_size = chp.m_hps / 2.0;
	if (chp.m_fBold & 1)
		font.m_attributes |= WPS_BOLD_BIT;
	if (chp.m_fBold & 2)
		font.m_attributes |= WPS_ITALICS_BIT;
	if (chp.m_fUline & 1)
		font.m_attributes |= WPS_UNDERLINE_BIT;
	if (chp.m_fUline & 2)
		font.m_attributes |= WPS_STRIKEOUT_BIT;
	if (chp.m_fUline & 4)
		font.m_attributes |= WPS_DOUBLE_UNDERLINE_BIT;
	// FIXME: if (chp.m_fUline & 8) marks a text new (not accepted)
	if ((chp.m_fUline & 0x30) == 0x10)
		font.m_attributes |= WPS_ALL_CAPS_BIT;
	else if ((chp.m_fUline & 0x30) == 0x30)
		font.m_attributes |= WPS_SMALL_CAPS_BIT;
	if (chp.m_fUline & 0x40)
		font.m_special = true;
	if (chp.m_fUline & 0x80)
		font.m_attributes |= WPS_HIDDEN_BIT;
	if (chp.m_hpsPos)
	{
		if (chp.m_hpsPos & 0x80)
			font.m_attributes |= WPS_SUBSCRIPT_BIT;
		else
			font.m_attributes |= WPS_SUPERSCRIPT_BIT;
	}

	font.m_fcFirst = fcFirst;
	font.m_fcLim = fcLim;
	font.m_encoding = libwps_tools_win::Font::getFontType(font.m_name);
	if (font.m_encoding == libwps_tools_win::Font::UNKNOWN)
		font.m_encoding = m_fontType;

	font.m_color = color(chp.m_clr & 7);

	m_fontList.push_back(font);
}