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(); }
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)); }
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); }