int wri_ole_read (unsigned char */*data*/, int /*size*/, GsfOutput */*fout*/) { #if 0 FILE *f; read_wri_struct_mem (write_ole, data); dump_wri_struct (write_ole); f = fopen ("ole.dump", "wb"); fwrite (data + 40, 1, wri_struct_value (write_ole, "dwDataSize"), f); fclose (f); #endif return 0; }
bool IE_Imp_MSWrite::read_txt (int from, int to) { static const char *currcp; int fcMac, pnChar, fcFirst, cfod, fc, fcLim; unsigned char page[0x80]; UT_String properties, tmp; int dataLen = static_cast<UT_sint32>(mData.getLength()); UT_DEBUGMSG((" TXT:\n")); UT_DEBUGMSG((" from = %d\n", from)); UT_DEBUGMSG((" to = %d\n", to)); fcMac = wri_struct_value(wri_file_header, "fcMac"); pnChar = (fcMac + 127) / 128; fcFirst = 0x80; while (true) { gsf_input_seek(mFile, pnChar++ * 0x80, G_SEEK_SET); gsf_input_read(mFile, 0x80, page); fc = READ_DWORD(page); cfod = page[0x7f]; UT_DEBUGMSG((" fcFirst = %d\n", fc)); UT_DEBUGMSG((" cfod = %d\n", cfod)); if (fc != fcFirst) UT_WARNINGMSG(("read_txt: fcFirst wrong.\n")); // read all FODs (format descriptors) for (int fod = 0; fod < cfod; fod++) { int bfprop, cch, ftc, hps, fBold, fItalic, fUline, hpsPos; UT_DEBUGMSG((" CHP-FOD #%02d:\n", fod + 1)); // read a FOD (format descriptor) fcLim = READ_DWORD(page + 4 + fod * 6); bfprop = READ_WORD(page + 8 + fod * 6); UT_DEBUGMSG((" fcLim = %d\n", fcLim)); UT_DEBUGMSG((bfprop == 0xffff ? " bfprop = 0x%04X\n" : " bfprop = %d\n", bfprop)); // default CHP values ftc = 0; hps = 24; fBold = fItalic = fUline = hpsPos = 0; // if the CHP FPROPs (formatting properties) differ from the defaults, get them if (bfprop != 0xffff && bfprop + (cch = page[bfprop + 4]) < 0x80) { UT_DEBUGMSG((" cch = %d\n", cch)); if (cch >= 2) ftc = page[bfprop + 6] >> 2; if (cch >= 5) ftc |= (page[bfprop + 9] & 3) << 6; if (cch >= 3) hps = page[bfprop + 7]; if (cch >= 2) fBold = page[bfprop + 6] & 1; if (cch >= 2) fItalic = page[bfprop + 6] & 2; if (cch >= 4) fUline = page[bfprop + 8] & 1; if (cch >= 6) hpsPos = page[bfprop + 10]; } UT_DEBUGMSG((" ftc = %d\n", ftc)); UT_DEBUGMSG((" hps = %d\n", hps)); UT_DEBUGMSG((" fBold = %d\n", fBold)); UT_DEBUGMSG((" fItalic = %d\n", fItalic)); UT_DEBUGMSG((" fUline = %d\n", fUline)); UT_DEBUGMSG((" hpsPos = %d\n", hpsPos)); if (ftc >= wri_fonts_count) { UT_WARNINGMSG(("read_txt: Wrong font code.\n")); ftc = wri_fonts_count - 1; } if (from < fcLim && to >= fcFirst) { UT_LocaleTransactor lt(LC_NUMERIC, "C"); UT_String_sprintf(properties, "font-weight:%s", fBold ? "bold" : "normal"); if (hps != 24) { UT_String_sprintf(tmp, "; font-size:%dpt", hps / 2); properties += tmp; } if (fItalic) properties += "; font-style:italic"; if (fUline) properties += "; text-decoration:underline"; if (hpsPos) { UT_String_sprintf(tmp, "; text-position:%s", hpsPos < 128 ? "superscript" : "subscript"); properties += tmp; } if (wri_fonts_count) { UT_String_sprintf(tmp, "; font-family:%s", wri_fonts[ftc].name); properties += tmp; } if (wri_fonts[ftc].codepage != currcp /*sic!*/) { set_codepage(wri_fonts[ftc].codepage); currcp = wri_fonts[ftc].codepage; } mText.clear(); UT_DEBUGMSG((" Text: ")); while (fcFirst <= from && from < fcLim && from <= to && from - 0x80 < dataLen) translate_char(*mData.getPointer(from++ - 0x80), mText); UT_DEBUGMSG(("\n")); // new attributes, only if there was text if (mText.size() > 0) { const gchar *attributes[5]; const UT_UCS4Char *text = mText.ucs4_str(), *p = text; size_t txtLen; UT_DEBUGMSG((" Conv: %s\n", mText.utf8_str())); attributes[0] = PT_PROPS_ATTRIBUTE_NAME; attributes[1] = properties.c_str(); attributes[2] = NULL; appendFmt(attributes); // check for page number (should only be in header or footer) while (*p && *p != (UT_UCS4Char) 0x01) p++; if (*p) { if (p - text) appendSpan(text, p - text); attributes[2] = PT_TYPE_ATTRIBUTE_NAME; attributes[3] = "page_number"; attributes[4] = NULL; appendObject(PTO_Field, attributes); txtLen = mText.size() - (p - text) - 1; p++; } else { txtLen = mText.size(); p = text; } if (txtLen) appendSpan(p, txtLen); } } fcFirst = fcLim; if (fcLim >= fcMac || fcFirst > to) { UT_DEBUGMSG((" CHP-FODs end, fcLim (%d) >= fcMac (%d) or fcFirst (%d) > to (%d)\n", fcLim, fcMac, fcFirst, to)); return true; } } }
bool IE_Imp_MSWrite::read_pap (pap_t process) { static const char *text_align[] = {"left", "center", "right", "justify"}; int fcMac, pnPara, fcFirst, cfod, fc, fcLim; unsigned char page[0x80]; UT_String properties, tmp, lastprops; if (process == All) { UT_DEBUGMSG(("PAP:\n")); } fcMac = wri_struct_value(wri_file_header, "fcMac"); pnPara = wri_struct_value(wri_file_header, "pnPara"); fcFirst = 0x80; while (true) { gsf_input_seek(mFile, pnPara++ * 0x80, G_SEEK_SET); gsf_input_read(mFile, 0x80, page); fc = READ_DWORD(page); cfod = page[0x7f]; if (process == All) { UT_DEBUGMSG((" fcFirst = %d\n", fc)); UT_DEBUGMSG((" cfod = %d\n", cfod)); } if (fc != fcFirst) UT_WARNINGMSG(("read_pap: fcFirst wrong.\n")); // read all FODs (format descriptors) for (int fod = 0; fod < cfod; fod++) { int bfprop, cch; int jc, dxaRight, dxaLeft, dxaLeft1, dyaLine, fGraphics; int rhcPage, rHeaderFooter, rhcFirst; int tabs, dxaTab[14], jcTab[14]; if (process == All) { UT_DEBUGMSG((" PAP-FOD #%02d:\n", fod + 1)); } // read a FOD (format descriptor) fcLim = READ_DWORD(page + 4 + fod * 6); bfprop = READ_WORD(page + 8 + fod * 6); if (process == All) { UT_DEBUGMSG((" fcLim = %d\n", fcLim)); UT_DEBUGMSG((bfprop == 0xffff ? " bfprop = 0x%04X\n" : " bfprop = %d\n", bfprop)); } // default PAP values jc = 0; dxaRight = dxaLeft = dxaLeft1 = 0; dyaLine = 240; rhcPage = rHeaderFooter = rhcFirst = 0; fGraphics = 0; tabs = 0; // if the PAP FPROPs (formatting properties) differ from the defaults, get them if (bfprop != 0xffff && bfprop + (cch = page[bfprop + 4]) < 0x80) { if (process == All) { UT_DEBUGMSG((" cch = %d\n", cch)); } if (cch >= 2) jc = page[bfprop + 6] & 3; if (cch >= 6) dxaRight = READ_WORD(page + bfprop + 9); if (cch >= 8) dxaLeft = READ_WORD(page + bfprop + 11); if (cch >= 10) dxaLeft1 = READ_WORD(page + bfprop + 13); if (cch >= 12) dyaLine = READ_WORD(page + bfprop + 15); if (cch >= 17) { rhcPage = page[bfprop + 21] & 1; rHeaderFooter = page[bfprop + 21] & 6; rhcFirst = page[bfprop + 21] & 8; fGraphics = page[bfprop + 21] & 0x10; } for (int n = 0; n < 14; n++) { if (cch >= 4 * (n + 1) + 26) { dxaTab[tabs] = READ_WORD(page + bfprop + n * 4 + 27); jcTab[tabs] = page[bfprop + n * 4 + 29] & 3; tabs++; } } if (dxaRight & 0x8000) dxaRight = -0x10000 + dxaRight; if (dxaLeft & 0x8000) dxaLeft = -0x10000 + dxaLeft; if (dxaLeft1 & 0x8000) dxaLeft1 = -0x10000 + dxaLeft1; if (dyaLine < 240) dyaLine = 240; if (process == All && rHeaderFooter) { if (rhcPage) { if (!hasFooter) { hasFooter = true; page1Footer = rhcFirst; } } else { if (!hasHeader) { hasHeader = true; page1Header = rhcFirst; } } } } if ((process == All && !rHeaderFooter) || (rHeaderFooter && ((process == Header && !rhcPage) || (process == Footer && rhcPage)))) { UT_DEBUGMSG((" jc = %d\n", jc)); UT_DEBUGMSG((" dxaRight = %d\n", dxaRight)); UT_DEBUGMSG((" dxaLeft = %d\n", dxaLeft)); UT_DEBUGMSG((" dxaLeft1 = %d\n", dxaLeft1)); UT_DEBUGMSG((" dyaLine = %d\n", dyaLine)); UT_DEBUGMSG((" rhcPage = %d\n", rhcPage)); UT_DEBUGMSG((" rHeaderFooter = %d\n", rHeaderFooter)); UT_DEBUGMSG((" rhcFirst = %d\n", rhcFirst)); UT_DEBUGMSG((" fGraphics = %d\n", fGraphics)); UT_LocaleTransactor lt(LC_NUMERIC, "C"); UT_String_sprintf(properties, "text-align:%s; line-height:%.1f", text_align[jc], static_cast<float>(dyaLine) / 240.0); if (tabs) { properties += "; tabstops:"; UT_DEBUGMSG((" Tabs:\n")); for (int n = 0; n < tabs; n++) { UT_String_sprintf(tmp, "%.4fin/%c0", static_cast<float>(dxaTab[n]) / 1440.0, jcTab[n] ? 'D' : 'L'); properties += tmp; UT_DEBUGMSG((" #%02d dxa = %d, jcTab = %d\n", n + 1, dxaTab[n], jcTab[n])); if (n != tabs - 1) properties += ","; } } if (process == Header || process == Footer) { // For reasons unknown, the left and right margins from the paper // are included in the indents of the headers and footers. dxaLeft -= xaLeft; dxaRight -= xaRight; } if (dxaLeft1) { UT_String_sprintf(tmp, "; text-indent:%.4fin", static_cast<float>(dxaLeft1) / 1440.0); properties += tmp; } if (dxaLeft) { UT_String_sprintf(tmp, "; margin-left:%.4fin", static_cast<float>(dxaLeft) / 1440.0); properties += tmp; } if (dxaRight) { UT_String_sprintf(tmp, "; margin-right:%.4fin", static_cast<float>(dxaRight) / 1440.0); properties += tmp; } // new attributes, only if there was a line feed or FPROPs have changed if (lf || strcmp(properties.c_str(), lastprops.c_str()) != 0) { const gchar *attributes[3]; attributes[0] = PT_PROPS_ATTRIBUTE_NAME; attributes[1] = properties.c_str(); attributes[2] = NULL; appendStrux(PTX_Block, attributes); lastprops = properties; } if (fGraphics) read_pic(fcFirst, fcLim - fcFirst); else read_txt(fcFirst, fcLim - 1); } fcFirst = fcLim; if (fcLim >= fcMac) { UT_DEBUGMSG((" PAP-FODs end, fcLim (%d) >= fcMac (%d)\n", fcLim, fcMac)); return true; } } } }
bool IE_Imp_MSWrite::read_sep () { int pnSep, pnSetb; int yaMac, xaMac, yaTop, dyaText, dxaText, rStartPage, yaHeader, yaFooter; int cch, yaBot; unsigned char sep[0x80]; UT_DEBUGMSG(("SEP:\n")); pnSep = wri_struct_value(wri_file_header, "pnSep"); pnSetb = wri_struct_value(wri_file_header, "pnSetb"); // default SEP values yaMac = 15840; xaMac = 12240; yaTop = 1440; dyaText = 12960; dxaText = 8640; xaLeft = 1800; rStartPage = 0xFFFF; yaHeader = 1080; yaFooter = 15760; // if the section properties differ from the defaults, get them if (pnSep != pnSetb) { gsf_input_seek(mFile, pnSep * 0x80, G_SEEK_SET); gsf_input_read(mFile, 0x80, sep); cch = *sep; UT_DEBUGMSG((" cch = %d\n", cch)); if (cch >= 4) yaMac = READ_WORD(sep + 3); if (cch >= 6) xaMac = READ_WORD(sep + 5); if (cch >= 8) rStartPage = READ_WORD(sep + 7); if (cch >= 10) yaTop = READ_WORD(sep + 9); if (cch >= 12) dyaText = READ_WORD(sep + 11); if (cch >= 14) xaLeft = READ_WORD(sep + 13); if (cch >= 16) dxaText = READ_WORD(sep + 15); if (cch >= 20) yaHeader = READ_WORD(sep + 19); if (cch >= 22) yaFooter = READ_WORD(sep + 21); } if (rStartPage & 0x8000) rStartPage = -0x10000 + rStartPage; UT_DEBUGMSG((" yaMac = %d\n", yaMac)); UT_DEBUGMSG((" xaMac = %d\n", xaMac)); UT_DEBUGMSG((" rStartPage = %d\n", rStartPage)); UT_DEBUGMSG((" yaTop = %d\n", yaTop)); UT_DEBUGMSG((" dyaText = %d\n", dyaText)); UT_DEBUGMSG((" xaLeft = %d\n", xaLeft)); UT_DEBUGMSG((" dxaText = %d\n", dxaText)); UT_DEBUGMSG((" yaHeader = %d\n", yaHeader)); UT_DEBUGMSG((" yaFooter = %d\n", yaFooter)); yaBot = yaMac - yaTop - dyaText; xaRight = xaMac - xaLeft - dxaText; UT_String properties; UT_LocaleTransactor lt(LC_NUMERIC, "C"); UT_String_sprintf(properties, "page-margin-header:%.4fin; " "page-margin-right:%.4fin; " "page-margin-left:%.4fin; " "page-margin-top:%.4fin; " "page-margin-bottom:%.4fin; " "page-margin-footer:%.4fin", static_cast<float>(yaHeader) / 1440.0, static_cast<float>(xaRight) / 1440.0, static_cast<float>(xaLeft) / 1440.0, static_cast<float>(yaTop) / 1440.0, static_cast<float>(yaBot) / 1440.0, static_cast<float>(yaMac - yaFooter) / 1440.0); if (rStartPage >= 0) { UT_String tmp; UT_String_sprintf(tmp, "; section-restart:1" "; section-restart-value:%d", rStartPage); properties += tmp; } const gchar *attributes[11]; attributes[0] = PT_PROPS_ATTRIBUTE_NAME; attributes[1] = properties.c_str(); attributes[2] = PT_HEADERFIRST_ATTRIBUTE_NAME; attributes[3] = "0"; attributes[4] = PT_HEADER_ATTRIBUTE_NAME; attributes[5] = "1"; attributes[6] = PT_FOOTERFIRST_ATTRIBUTE_NAME; attributes[7] = "2"; attributes[8] = PT_FOOTER_ATTRIBUTE_NAME; attributes[9] = "3"; attributes[10] = NULL; appendStrux(PTX_Section, attributes); return true; }
bool IE_Imp_MSWrite::read_ffntb () { int pnFfntb, pnMac, fonts_count = 0, cbFfn, fflen; unsigned char buf[2], ffid; wri_font *fonts; char *ffn; UT_DEBUGMSG(("Fonts:\n")); pnFfntb = wri_struct_value(wri_file_header, "pnFfntb"); pnMac = wri_struct_value(wri_file_header, "pnMac"); // if pnFfntb is the same as pnMac, there are no fonts if (pnFfntb == pnMac) { UT_DEBUGMSG((" (none)\n")); return true; } if (gsf_input_seek(mFile, pnFfntb++ * 0x80, G_SEEK_SET)) { UT_WARNINGMSG(("read_ffntb: Can't seek FFNTB!\n")); return false; } // the first two bytes are the number of fonts if (!gsf_input_read(mFile, 2, buf)) { UT_WARNINGMSG(("read_ffntb: Can't read FFNTB!\n")); return false; } wri_fonts_count = READ_WORD(buf); UT_DEBUGMSG((" reported: %d\n", wri_fonts_count)); while (true) { if (!gsf_input_read(mFile, 2, buf)) { UT_WARNINGMSG(("read_ffntb: Can't read cbFfn!\n")); wri_fonts_count = fonts_count; free_ffntb(); return false; } cbFfn = READ_WORD(buf); if (cbFfn == 0) break; if (cbFfn == 0xffff) { if (gsf_input_seek(mFile, pnFfntb++ * 0x80, G_SEEK_SET)) { UT_WARNINGMSG(("read_ffntb: Can't seek next FFNTB!\n")); wri_fonts_count = fonts_count; free_ffntb(); return false; } continue; } // add one more font fonts = (wri_font *) realloc(wri_fonts, (fonts_count + 1) * sizeof(wri_font)); if (!fonts) { UT_WARNINGMSG(("read_ffntb: Out of memory!\n")); wri_fonts_count = fonts_count; free_ffntb(); return false; } wri_fonts = fonts; // This is the font family identifier. It can either be FF_DONTCARE, // FF_ROMAN, FF_SWISS, FF_MODERN, FF_SCRIPT or FF_DECORATIVE. These // are defined in <windows.h>, but I don't know what to do with them. if (!gsf_input_read(mFile, 1, &ffid)) { UT_WARNINGMSG(("read_ffntb: Can't read ffid!\n")); wri_fonts_count = fonts_count; free_ffntb(); return false; } wri_fonts[fonts_count].ffid = ffid; cbFfn--; // we've already read ffid ffn = static_cast<char *>(malloc(cbFfn)); if (!ffn) { UT_WARNINGMSG(("read_ffntb: Out of memory!\n")); wri_fonts_count = fonts_count; free_ffntb(); return false; } if (!gsf_input_read(mFile, cbFfn, (guint8 *) ffn)) { UT_WARNINGMSG(("read_ffntb: Can't read szFfn!\n")); wri_fonts_count = fonts_count + 1; free_ffntb(); return false; } wri_fonts[fonts_count].codepage = get_codepage(ffn, &fflen); ffn[fflen] = 0; wri_fonts[fonts_count].name = ffn; UT_DEBUGMSG((" %2d: %s (%s)\n", fonts_count, wri_fonts[fonts_count].name, wri_fonts[fonts_count].codepage)); fonts_count++; } if (fonts_count != wri_fonts_count) { wri_fonts_count = fonts_count; UT_WARNINGMSG(("read_ffntb: Wrong number of fonts.\n")); } return true; }
UT_Error IE_Imp_MSWrite::parse_file () { int id, size; UT_Byte *thetext; if (!read_wri_struct(wri_file_header, mFile)) return UT_ERROR; UT_DEBUGMSG(("File Header:\n")); DEBUG_WRI_STRUCT(wri_file_header); id = wri_struct_value(wri_file_header, "wIdent"); if (id == 0137062) { // okay, but expect OLE objects } else if (id != 0137061) { UT_WARNINGMSG(("parse_file: Not a write file!\n")); return UT_ERROR; } if (wri_struct_value(wri_file_header, "wTool") != 0125400) { UT_WARNINGMSG(("parse_file: Not a write file!\n")); return UT_ERROR; } size = wri_struct_value(wri_file_header, "fcMac") - 0x80; thetext = static_cast<UT_Byte *>(malloc(size)); if (!thetext) { UT_WARNINGMSG(("parse_file: Out of memory!\n")); return UT_ERROR; } if (gsf_input_seek(mFile, 0x80, G_SEEK_SET)) { UT_WARNINGMSG(("parse_file: Can't seek data!\n")); return UT_ERROR; } gsf_input_read(mFile, size, thetext); if (!read_ffntb()) { free(thetext); return UT_ERROR; } mData.truncate(0); mData.append(thetext, size); free(thetext); read_sep(); read_pap(All); UT_DEBUGMSG(("Header: %d, on first page: %d\n", hasHeader, page1Header)); if (hasHeader) { _append_hdrftr(header); read_pap(Header); if (!page1Header) _append_hdrftr(headerfirst); // an empty one } UT_DEBUGMSG(("Footer: %d, on first page: %d\n", hasFooter, page1Footer)); if (hasFooter) { _append_hdrftr(footer); read_pap(Footer); if (!page1Footer) _append_hdrftr(footerfirst); // an empty one } free_ffntb(); return UT_OK; }