24#include <tqdatastream.h>
27#include <tqpointarray.h>
33const int Msod::s_area = 30505;
40 m_images.setAutoDelete( true);
41 m_opt = new Options(* this);
48 delete [] m_shape.data;
55 TQDataStream &operands)
57 static const char *funcTab[] =
109 "ACCENTBORDERCALLOUT1",
110 "ACCENTBORDERCALLOUT2",
111 "ACCENTBORDERCALLOUT3",
122 "WEDGEELLIPSECALLOUT",
140 "LEFTRIGHTARROWCALLOUT",
141 "UPDOWNARROWCALLOUT",
159 "NOTCHEDCIRCULARARROW",
170 "FLOWCHARTINPUTOUTPUT",
171 "FLOWCHARTPREDEFINEDPROCESS",
172 "FLOWCHARTINTERNALSTORAGE",
174 "FLOWCHARTMULTIDOCUMENT",
175 "FLOWCHARTTERMINATOR",
176 "FLOWCHARTPREPARATION",
177 "FLOWCHARTMANUALINPUT",
178 "FLOWCHARTMANUALOPERATION",
179 "FLOWCHARTCONNECTOR",
180 "FLOWCHARTPUNCHEDCARD",
181 "FLOWCHARTPUNCHEDTAPE",
182 "FLOWCHARTSUMMINGJUNCTION",
188 "FLOWCHARTOFFLINESTORAGE",
189 "FLOWCHARTONLINESTORAGE",
190 "FLOWCHARTMAGNETICTAPE",
191 "FLOWCHARTMAGNETICDISK",
192 "FLOWCHARTMAGNETICDRUM",
198 "TEXTTRIANGLEINVERTED",
200 "TEXTCHEVRONINVERTED",
225 "TEXTDEFLATEINFLATE",
226 "TEXTDEFLATEINFLATEDEFLATE",
235 "FLOWCHARTALTERNATEPROCESS",
236 "FLOWCHARTOFFPAGECONNECTOR",
240 "ACCENTBORDERCALLOUT90",
251 "ACTIONBUTTONINFORMATION",
252 "ACTIONBUTTONFORWARDNEXT",
253 "ACTIONBUTTONBACKPREVIOUS",
255 "ACTIONBUTTONBEGINNING",
256 "ACTIONBUTTONRETURN",
257 "ACTIONBUTTONDOCUMENT",
271 TQ_UINT32 fGroup : 1;
272 TQ_UINT32 fChild : 1;
273 TQ_UINT32 fPatriarch : 1;
275 TQ_UINT32 fDeleted : 1;
276 TQ_UINT32 fOleShape : 1;
277 TQ_UINT32 fHaveMaster : 1;
278 TQ_UINT32 fFlipH : 1;
279 TQ_UINT32 fFlipV : 1;
280 TQ_UINT32 fConnector : 1;
281 TQ_UINT32 fHaveAnchor : 1;
282 TQ_UINT32 fBackground : 1;
283 TQ_UINT32 fHaveSpt : 1;
284 TQ_UINT32 reserved : 20;
291 operands >> data.spid;
292 operands >> data.grfPersistent.info;
294 kdDebug(s_area) << "shape-id: " << data.spid << " type: " << funcTab[shapeType] << " (" << shapeType << ")" <<
295 (data.grfPersistent.fields.fGroup ? " group" : "") <<
296 (data.grfPersistent.fields.fChild ? " child" : "") <<
297 (data.grfPersistent.fields.fPatriarch ? " patriarch" : "") <<
298 (data.grfPersistent.fields.fDeleted ? " deleted" : "") <<
299 (data.grfPersistent.fields.fOleShape ? " oleshape" : "") <<
300 (data.grfPersistent.fields.fHaveMaster ? " master" : "") <<
301 (data.grfPersistent.fields.fFlipH ? " flipv" : "") <<
302 (data.grfPersistent.fields.fConnector ? " connector" : "") <<
303 (data.grfPersistent.fields.fHaveAnchor ? " anchor" : "") <<
304 (data.grfPersistent.fields.fBackground ? " background" : "") <<
305 (data.grfPersistent.fields.fHaveSpt ? " spt" : "") <<
306 " operands: " << bytes << endl;
307 if (data.grfPersistent.fields.fDeleted)
309 if ((!m_isRequiredDrawing) && (m_requestedShapeId != data.spid))
317 if (m_opt->m_pVertices)
319 gotPolyline(m_dc, *m_opt->m_pVertices);
328 topLeft = normalisePoint(operands);
329 size = normaliseSize(operands);
331 TQRect rect(topLeft, size);
332 TQPointArray points(4);
334 points.setPoint(0, topLeft);
335 points.setPoint(1, rect.topRight());
336 points.setPoint(2, rect.bottomRight());
337 points.setPoint(3, rect.bottomLeft());
338 gotRectangle(m_dc, points);
346 lineTo = normalisePoint(operands);
348 TQPointArray points(2);
350 points.setPoint(0, lineFrom);
351 points.setPoint(1, lineTo);
352 gotPolyline(m_dc, points);
360void Msod::invokeHandler(
363 TQDataStream &operands)
365 typedef void (Msod::*method)(Header &op, TQ_UINT32 bytes, TQDataStream &operands);
374 static const opcodeEntry funcTab[] =
376 { "ALIGNRULE", 0xF013, &Msod::opAlignrule },
377 { "ANCHOR", 0xF00E, &Msod::opAnchor },
378 { "ARCRULE", 0xF014, &Msod::opArcrule },
379 { "BSE", 0xF007, &Msod::opBse },
380 { "BSTORECONTAINER", 0xF001, &Msod::opBstorecontainer },
381 { "CALLOUTRULE", 0xF017, &Msod::opCalloutrule },
382 { "CHILDANCHOR", 0xF00F, &Msod::opChildanchor },
383 { "CLIENTANCHOR", 0xF010, &Msod::opClientanchor },
384 { "CLIENTDATA", 0xF011, &Msod::opClientdata },
385 { "CLIENTRULE", 0xF015, &Msod::opClientrule },
386 { "CLIENTTEXTBOX", 0xF00D, &Msod::opClienttextbox },
387 { "CLSID", 0xF016, &Msod::opClsid },
388 { "COLORMRU", 0xF11A, &Msod::opColormru },
389 { "CONNECTORRULE", 0xF012, &Msod::opConnectorrule },
390 { "DELETEDPSPL", 0xF11D, &Msod::opDeletedpspl },
391 { "DG", 0xF008, &Msod::opDg },
392 { "DGCONTAINER", 0xF002, &Msod::opDgcontainer },
393 { "DGG", 0xF006, &Msod::opDgg },
394 { "DGGCONTAINER", 0xF000, &Msod::opDggcontainer },
395 { "OLEOBJECT", 0xF11F, &Msod::opOleobject },
396 { "OPT", 0xF00B, &Msod::opOpt },
397 { "REGROUPITEMS", 0xF118, &Msod::opRegroupitems },
398 { "SELECTION", 0xF119, &Msod::opSelection },
399 { "SOLVERCONTAINER", 0xF005, &Msod::opSolvercontainer },
400 { "SP", 0xF00A, &Msod::opSp },
401 { "SPCONTAINER", 0xF004, &Msod::opSpcontainer },
402 { "SPGR", 0xF009, &Msod::opSpgr },
403 { "SPGRCONTAINER", 0xF003, &Msod::opSpgrcontainer },
404 { "SPLITMENUCOLORS", 0xF11E, &Msod::opSplitmenucolors },
405 { "TEXTBOX", 0xF00C, &Msod::opTextbox },
407 { "BLIP", 0, &Msod::opBlip }
414 for (i = 0; funcTab[i].name; i++)
416 if (funcTab[i].opcode == op.opcode.fields.fbt)
424 result = funcTab[i].handler;
425 if (!result && (op.opcode.fields.fbt >= 0xF018) && (0xF117 >= op.opcode.fields.fbt))
426 result = funcTab[++i].handler;
430 kdWarning(s_area) << "invokeHandler: unsupported opcode: " <<
432 " operands: " << bytes << endl;
434 kdWarning(s_area) << "invokeHandler: unsupported opcode: 0x" <<
435 TQString::number(op.opcode.fields.fbt, 16) <<
436 " operands: " << bytes << endl;
440 skip(bytes, operands);
444 kdDebug(s_area) << "invokeHandler: opcode: " << funcTab[i].name <<
445 " operands: " << bytes << endl;
455 TQByteArray *record = new TQByteArray(bytes);
458 operands.readRawBytes(record->data(), bytes);
459 body = new TQDataStream(*record, IO_ReadOnly);
460 body->setByteOrder(TQDataStream::LittleEndian);
461 (this->*result)(op, bytes, *body);
467 TQDataStream *body = new TQDataStream();
469 (this->*result)(op, bytes, *body);
475TQPoint Msod::normalisePoint(
476 TQDataStream &operands)
482 return TQPoint(x / m_dpi, y / m_dpi);
485TQSize Msod::normaliseSize(
486 TQDataStream &operands)
491 operands >> width >> height;
492 return TQSize(width / m_dpi, height / m_dpi);
497 const TQString &file,
498 const char *delayStream)
501 if (!in.open(IO_ReadOnly))
503 kdError(s_area) << "Unable to open input file!" << endl;
507 TQDataStream stream(&in);
508 bool result = parse(shapeId, stream, in.size(), delayStream);
515 TQDataStream &stream,
517 const char *delayStream)
519 stream.setByteOrder(TQDataStream::LittleEndian);
520 m_requestedShapeId = shapeId;
521 m_isRequiredDrawing = false;
522 m_delayStream = delayStream;
530void Msod::opAlignrule(
551void Msod::opBlip(Header &, TQ_UINT32 bytes, TQDataStream &operands)
565 msocompressionDeflate,
566 msocompressionNone = 254,
568 } MSOBLIPCOMPRESSION;
571 TQ_UINT32 length = 0;
588 TQ_UINT8 compression;
597 hasPrimaryId = (m_blipType ^ msobiEMF) != 0;
600 hasPrimaryId = (m_blipType ^ msobiWMF) != 0;
603 hasPrimaryId = (m_blipType ^ msobiPICT) != 0;
606 hasPrimaryId = (m_blipType ^ msobiJPEG) != 0;
609 hasPrimaryId = (m_blipType ^ msobiPNG) != 0;
612 hasPrimaryId = (m_blipType ^ msobiDIB) != 0;
615 hasPrimaryId = (m_blipType ^ msobiClient) != 0;
626 data.compression = msocompressionNone;
634 operands >> data.bounds.x >> data.bounds.y >> data.bounds.w >> data.bounds.h;
635 operands >> data.ptSize.w >> data.ptSize.h;
636 operands >> data.cbSave;
637 operands >> data.compression >> data.filter;
652 Image *image = new Image();
656 image->extension = "emf";
659 image->extension = "wmf";
662 image->extension = "pic";
665 image->extension = "jpg";
668 image->extension = "png";
671 image->extension = "dib";
674 image->extension = "img";
677 image->length = bytes - length;
678 image->data = new char[image->length];
679 operands.readRawBytes(( char *)image->data, image->length);
680 if (data.compression == msocompressionDeflate)
683 uLongf destLen = data.cb;
686 tmp = new char[data.cb];
687 result = uncompress((TQ_UINT8 *)tmp, &destLen, (TQ_UINT8 *)image->data, image->length);
690 kdError(s_area) << "opBlip: uncompress failed: " << result << endl;
692 if (destLen != data.cb)
694 kdError(s_area) << "opBlip: uncompressed " << destLen << " instead of " << data.cb << endl;
696 delete [] image->data;
698 image->length = destLen;
700 m_images.resize(m_images.size() + 1);
701 m_images.insert(m_images.size() - 1, image);
706void Msod::opBse(Header &op, TQ_UINT32, TQDataStream &operands)
726 m_blipType = static_cast<MSOBLIPTYPE >(op.opcode.fields.inst);
727 operands >> data.btWin32;
728 operands >> data.btMacOS;
729 for (i = 0; i < 16; i++)
730 operands >> data.rgbUid[i];
731 operands >> data.tag >> data.size;
732 operands >> data.cRef >> data.foDelay;
733 operands >> data.usage >> data.cbName;
734 operands >> data.unused2 >> data.unused2;
744 if (data.size && data.cRef)
747 bytes.setRawData(m_delayStream + data.foDelay, data.size);
748 TQDataStream stream(bytes, IO_ReadOnly);
749 stream.setByteOrder(TQDataStream::LittleEndian);
750 walk(data.size, stream);
751 bytes.resetRawData(m_delayStream + data.foDelay, data.size);
755 m_images.resize(m_images.size() + 1);
756 m_images.insert(m_images.size() - 1, 0L);
761void Msod::opBstorecontainer(Header &, TQ_UINT32 bytes, TQDataStream &operands)
763 walk(bytes, operands);
766void Msod::opCalloutrule(
773void Msod::opChildanchor(
780void Msod::opClientanchor(Header &, TQ_UINT32, TQDataStream &operands)
787 operands >> data.unknown;
788 kdDebug(s_area) << "client anchor: " << data.unknown << endl;
791void Msod::opClientdata(Header &, TQ_UINT32, TQDataStream &operands)
798 operands >> data.unknown;
799 kdDebug(s_area) << "client data: " << data.unknown << endl;
802void Msod::opClientrule(
809void Msod::opClienttextbox(
812 TQDataStream &operands)
819 operands >> data.unknown;
820 kdDebug(s_area) << "client textbox: 0x" << TQString::number(data.unknown,16) << endl;
830void Msod::opColormru(
837void Msod::opConnectorrule(
844void Msod::opDeletedpspl(
853void Msod::opDg(Header &, TQ_UINT32, TQDataStream &operands)
861 operands >> data.csp >> data.spidCur;
862 kdDebug(s_area) << "drawing id: " << data.spidCur << endl;
863 m_isRequiredDrawing = (m_requestedShapeId == data.spidCur);
864 if (m_isRequiredDrawing)
866 kdDebug(s_area) << "found requested drawing" << endl;
870void Msod::opDgcontainer(Header &, TQ_UINT32 bytes, TQDataStream &operands)
872 walk(bytes, operands);
877void Msod::opDgg(Header &, TQ_UINT32, TQDataStream &operands)
898 operands >> data.spidMax >> data.cidcl >> data.cspSaved >> data.cdgSaved;
899 kdDebug(s_area) << data.cspSaved << " shapes in " <<
900 data.cidcl - 1 << " clusters in " <<
901 data.cdgSaved << " drawings" << endl;
902 for (i = 0; i < data.cidcl - 1; i++)
904 operands >> data1.dgid >> data1.cspidCur;
908void Msod::opDggcontainer(Header &, TQ_UINT32 bytes, TQDataStream &operands)
910 walk(bytes, operands);
913void Msod::opOleobject(
920void Msod::opOpt(Header &, TQ_UINT32 bytes, TQDataStream &operands)
922 m_opt->walk(bytes, operands);
925void Msod::opRegroupitems(
932void Msod::opSelection(
939void Msod::opSolvercontainer(Header &, TQ_UINT32 bytes, TQDataStream &operands)
941 walk(bytes, operands);
944void Msod::opSp(Header &op, TQ_UINT32 bytes, TQDataStream &operands)
950 m_shape.type = op.opcode.fields.inst;
951 m_shape.length = bytes;
952 m_shape.data = new char [bytes];
953 operands.readRawBytes(m_shape.data, bytes);
956void Msod::opSpcontainer(Header &, TQ_UINT32 bytes, TQDataStream &operands)
958 walk(bytes, operands);
964 a.setRawData(m_shape.data, m_shape.length);
965 TQDataStream s(a, IO_ReadOnly);
966 s.setByteOrder(TQDataStream::LittleEndian);
967 drawShape(m_shape.type, m_shape.length, s);
968 a.resetRawData(m_shape.data, m_shape.length);
969 delete [] m_shape.data;
973void Msod::opSpgr(Header &, TQ_UINT32, TQDataStream &operands)
983 operands >> data.x >> data.y >> data.w >> data.h;
986void Msod::opSpgrcontainer(Header &, TQ_UINT32 bytes, TQDataStream &operands)
988 walk(bytes, operands);
991void Msod::opSplitmenucolors(Header &, TQ_UINT32, TQDataStream &operands)
1001 operands >> data.fill >> data.line >> data.shadow >> data.threeDee;
1004void Msod::opTextbox(
1011void Msod::skip(TQ_UINT32 bytes, TQDataStream &operands)
1015 kdError(s_area) << "skip: " << (int)bytes << endl;
1023 kdDebug(s_area) << "skip: " << bytes << endl;
1024 for (i = 0; i < bytes; i++)
1026 operands >> discard;
1031void Msod::walk(TQ_UINT32 bytes, TQDataStream &operands)
1034 TQ_UINT32 length = 0;
1038 while (length + 8 <= bytes)
1040 operands >> op.opcode.info >> op.cbLength;
1043 if (length + op.cbLength + 8 > bytes)
1045 op.cbLength = bytes - length - 8;
1047 length += op.cbLength + 8;
1048 if (op.opcode.fields.fbt == 0x200)
1056 invokeHandler(op, op.cbLength, operands);
1060 skip(bytes - length, operands);
1063Msod::Options::Options(
1071Msod::Options::~Options()
1076double Msod::Options::from1616ToDouble(TQ_UINT32 value)
1078 return (value >> 16) + 65535.0 / (double)(value & 0xffff);
1081void Msod::Options::initialise()
1088 m_pibName = TQString();
1091 m_fNoHitTestPicture = false;
1092 m_pictureGray = false;
1093 m_pictureBiLevel = false;
1094 m_pictureActive = false;
1099 m_geoBottom = 21600;
1107 m_fFillShadeShapeOK = false;
1111 m_fHitTestFill = true;
1113 m_fillUseRect = false;
1114 m_fNoFillHitTest = false;
1117 m_lineBackColor = 0xffffff;
1121 m_fArrowheadsOK = false;
1123 m_fHitTestLine = true;
1124 m_lineFillShape = true;
1125 m_fNoLineDrawDash = false;
1130 m_fPreferRelativeResize = false;
1131 m_fLockShapeType = false;
1132 m_fDeleteAttachedObject = false;
1133 m_fBackground = false;
1136void Msod::Options::walk(TQ_UINT32 bytes, TQDataStream &operands)
1139 TQ_UINT16 length = 0;
1140 TQ_UINT16 complexLength = 0;
1148 TQPtrList<Header> complexOpts;
1149 complexOpts.setAutoDelete( true);
1151 while (length + complexLength < ( int)bytes)
1153 operands >> op.opcode.info >> op.value;
1158 if (op.opcode.fields.fComplex)
1160 complexLength += op.value;
1161 complexOpts.append( new Header(op));
1167 unsupported = false;
1168 switch (op.opcode.fields.pid)
1171 m_rotation = from1616ToDouble(op.value);
1175 kdDebug(s_area) << "textbox: 0x" << TQString::number(op.value,16) << endl;
1178 if (op.opcode.fields.fBid)
1181 if (m_parent.m_isRequiredDrawing)
1183 Image *image = m_parent.m_images[m_pib - 1];
1188 if (image->extension == "wmf")
1191 a.setRawData(image->data, image->length);
1192 TQDataStream s(a, IO_ReadOnly);
1193 m_parent.KWmf::parse(s, image->length);
1194 a.resetRawData(image->data, image->length);
1198 m_parent.gotPicture(
1208 kdError(s_area) << "Cannot handle IMsoBlip" << endl;
1212 m_pibFlags = op.value;
1215 m_pictureId = op.value;
1218 m_fNoHitTestPicture = (op.value & 0x0008) != 0;
1219 m_pictureGray = (op.value & 0x0004) != 0;
1220 m_pictureBiLevel = (op.value & 0x0002) != 0;
1221 m_pictureActive = (op.value & 0x0001) != 0;
1224 m_geoLeft = op.value;
1227 m_geoTop = op.value;
1230 m_geoRight = op.value;
1233 m_geoBottom = op.value;
1236 m_shapePath = op.value;
1239 m_fShadowOK = (op.value & 0x0020) != 0;
1240 m_f3DOK = (op.value & 0x0010) != 0;
1241 m_fLineOK = (op.value & 0x0008) != 0;
1242 m_fGTextOK = (op.value & 0x0004) != 0;
1243 m_fFillShadeShapeOK = (op.value & 0x0002) != 0;
1244 m_fFillOK = (op.value & 0x0001) != 0;
1247 m_fFilled = (op.value & 0x0010) != 0;
1248 m_fHitTestFill = (op.value & 0x0008) != 0;
1249 m_fillShape = (op.value & 0x0004) != 0;
1250 m_fillUseRect = (op.value & 0x0002) != 0;
1251 m_fNoFillHitTest = (op.value & 0x0001) != 0;
1254 m_lineColor = op.value;
1257 m_lineBackColor = op.value;
1260 m_lineType = op.value;
1263 m_lineWidth = op.value;
1266 m_fArrowheadsOK = (op.value & 0x0010) != 0;
1267 m_fLine = (op.value & 0x0008) != 0;
1268 m_fHitTestLine = (op.value & 0x0004) != 0;
1269 m_lineFillShape = (op.value & 0x0002) != 0;
1270 m_fNoLineDrawDash = (op.value & 0x0001) != 0;
1273 m_bWMode = op.value;
1276 m_fOleIcon = (op.value & 0x0010) != 0;
1277 m_fPreferRelativeResize = (op.value & 0x0008) != 0;
1278 m_fLockShapeType = (op.value & 0x0004) != 0;
1279 m_fDeleteAttachedObject = (op.value & 0x0002) != 0;
1280 m_fBackground = (op.value & 0x0001) != 0;
1284 kdWarning(s_area) << "unsupported simple option: " <<
1285 op.opcode.fields.pid << endl;
1289 kdDebug(s_area) << "simple option: " <<
1290 op.opcode.fields.pid << endl;
1295 while (complexOpts.count())
1300 op = *complexOpts.getFirst();
1301 complexOpts.removeFirst();
1302 unsupported = false;
1303 switch (op.opcode.fields.pid)
1311 m_pibName += TQChar(t16);
1315 m_pVertices = new TQPointArray(op.value / 4);
1316 for (i = 0; i < m_pVertices->count(); i++)
1318 m_pVertices->setPoint(i, m_parent.normalisePoint(operands));
1326 m_parent.skip(i * t16, operands);
1330 kdWarning(s_area) << "unsupported complex option: " <<
1331 op.opcode.fields.pid << " operands: " << op.value << endl;
1332 m_parent.skip(op.value, operands);
1336 kdDebug(s_area) << "complex option: " <<
1337 op.opcode.fields.pid << " operands: " << op.value << endl;
1338 complexLength -= op.value;
|