00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <kdebug.h>
00028 #include <math.h>
00029 #include <QFile>
00030 #include <q3pointarray.h>
00031 #include "kwmf.h"
00032 #include <QRect>
00033
00034 #define PI (3.14159265358979323846)
00035
00036 const int KWmf::s_area = 30504;
00037
00038 KWmf::KWmf(
00039 unsigned dpi)
00040 {
00041 m_dpi = dpi;
00042 }
00043
00044 KWmf::~KWmf()
00045 {
00046 qDeleteAll(m_objectHandles);
00047 }
00048
00049
00050
00051
00052
00053 void KWmf::brushSet(
00054 unsigned color,
00055 unsigned style)
00056 {
00057 m_dc.m_brushColor = color;
00058 m_dc.m_brushStyle = style;
00059 }
00060
00061
00062 unsigned KWmf::getColor(
00063 S32 color)
00064 {
00065 unsigned red, green, blue;
00066
00067 red = color & 255;
00068 green = (color >> 8) & 255;
00069 blue = (color >> 16) & 255;
00070 return (red << 16) + (green << 8) + blue;
00071 }
00072
00073 void KWmf::genericArc(
00074 const QString & type,
00075 QDataStream &operands)
00076 {
00077 QPoint topLeft;
00078 QPoint bottomRight;
00079 QPoint start;
00080 QPoint end;
00081
00082 topLeft = normalisePoint(operands);
00083 bottomRight = normalisePoint(operands);
00084 start = normalisePoint(operands);
00085 end = normalisePoint(operands);
00086
00087
00088
00089
00090
00091 QRect ellipse(topLeft, bottomRight);
00092 QPoint center = ellipse.center();
00093 double startAngle = atan2((double)(center.y() - start.y()), (double)(center.x() - start.x()));
00094 double stopAngle = atan2((double)(center.y() - end.y()), (double)(center.x() - end.x()));
00095
00096 startAngle = 180 * startAngle / PI;
00097 stopAngle = 180 * stopAngle / PI;
00098
00099 gotEllipse(m_dc, type, center, ellipse.size() / 2,
00100 static_cast<unsigned int>(startAngle),
00101 static_cast<unsigned int>(stopAngle));
00102 }
00103
00104
00105 KWmf::WinObjPenHandle *KWmf::handleCreatePen(void)
00106 {
00107 WinObjPenHandle *handle = new WinObjPenHandle;
00108 m_objectHandles.append(handle);
00109 return handle;
00110 }
00111
00112
00113 KWmf::WinObjBrushHandle *KWmf::handleCreateBrush(void)
00114 {
00115 WinObjBrushHandle *handle = new WinObjBrushHandle;
00116 m_objectHandles.append(handle);
00117 return handle;
00118 }
00119
00120
00121
00122
00123
00124 void KWmf::invokeHandler(
00125 S16 opcode,
00126 U32 words,
00127 QDataStream &operands)
00128 {
00129 typedef void (KWmf::*method)(U32 words, QDataStream &operands);
00130
00131 typedef struct
00132 {
00133 const char *name;
00134 unsigned short opcode;
00135 method handler;
00136 } opcodeEntry;
00137
00138 static const opcodeEntry funcTab[] =
00139 {
00140 { "ANIMATEPALETTE", 0x0436, 0 },
00141 { "ARC", 0x0817, &KWmf::opArc },
00142 { "BITBLT", 0x0922, 0 },
00143 { "CHORD", 0x0830, 0 },
00144 { "CREATEBRUSHINDIRECT", 0x02FC, &KWmf::opBrushCreateIndirect },
00145 { "CREATEFONTINDIRECT", 0x02FB, 0 },
00146 { "CREATEPALETTE", 0x00F7, 0 },
00147 { "CREATEPATTERNBRUSH", 0x01F9, 0 },
00148 { "CREATEPENINDIRECT", 0x02FA, &KWmf::opPenCreateIndirect },
00149 { "CREATEREGION", 0x06FF, 0 },
00150 { "DELETEOBJECT", 0x01F0, &KWmf::opObjectDelete },
00151 { "DIBBITBLT", 0x0940, 0 },
00152 { "DIBCREATEPATTERNBRUSH",0x0142, 0 },
00153 { "DIBSTRETCHBLT", 0x0b41, 0 },
00154 { "ELLIPSE", 0x0418, &KWmf::opEllipse },
00155 { "ESCAPE", 0x0626, &KWmf::opNoop },
00156 { "EXCLUDECLIPRECT", 0x0415, 0 },
00157 { "EXTFLOODFILL", 0x0548, 0 },
00158 { "EXTTEXTOUT", 0x0a32, 0 },
00159 { "FILLREGION", 0x0228, 0 },
00160 { "FLOODFILL", 0x0419, 0 },
00161 { "FRAMEREGION", 0x0429, 0 },
00162 { "INTERSECTCLIPRECT", 0x0416, 0 },
00163 { "INVERTREGION", 0x012A, 0 },
00164 { "LINETO", 0x0213, &KWmf::opLineTo },
00165 { "MOVETO", 0x0214, &KWmf::opMoveTo },
00166 { "OFFSETCLIPRGN", 0x0220, 0 },
00167 { "OFFSETVIEWPORTORG", 0x0211, 0 },
00168 { "OFFSETWINDOWORG", 0x020F, 0 },
00169 { "PAINTREGION", 0x012B, 0 },
00170 { "PATBLT", 0x061D, 0 },
00171 { "PIE", 0x081A, &KWmf::opPie },
00172 { "POLYGON", 0x0324, &KWmf::opPolygon },
00173 { "POLYLINE", 0x0325, &KWmf::opPolyline },
00174 { "POLYPOLYGON", 0x0538, 0 },
00175 { "REALIZEPALETTE", 0x0035, 0 },
00176 { "RECTANGLE", 0x041B, &KWmf::opRectangle },
00177 { "RESIZEPALETTE", 0x0139, 0 },
00178 { "RESTOREDC", 0x0127, &KWmf::opRestoreDc },
00179 { "ROUNDRECT", 0x061C, 0 },
00180 { "SAVEDC", 0x001E, &KWmf::opSaveDc },
00181 { "SCALEVIEWPORTEXT", 0x0412, 0 },
00182 { "SCALEWINDOWEXT", 0x0410, 0 },
00183 { "SELECTCLIPREGION", 0x012C, 0 },
00184 { "SELECTOBJECT", 0x012D, &KWmf::opObjectSelect },
00185 { "SELECTPALETTE", 0x0234, 0 },
00186 { "SETBKCOLOR", 0x0201, 0 },
00187 { "SETBKMODE", 0x0102, 0 },
00188 { "SETDIBTODEV", 0x0d33, 0 },
00189 { "SETMAPMODE", 0x0103, 0 },
00190 { "SETMAPPERFLAGS", 0x0231, 0 },
00191 { "SETPALENTRIES", 0x0037, 0 },
00192 { "SETPIXEL", 0x041F, 0 },
00193 { "SETPOLYFILLMODE", 0x0106, &KWmf::opPolygonSetFillMode },
00194 { "SETRELABS", 0x0105, 0 },
00195 { "SETROP2", 0x0104, 0 },
00196 { "SETSTRETCHBLTMODE", 0x0107, 0 },
00197 { "SETTEXTALIGN", 0x012E, 0 },
00198 { "SETTEXTCHAREXTRA", 0x0108, 0 },
00199 { "SETTEXTCOLOR", 0x0209, 0 },
00200 { "SETTEXTJUSTIFICATION", 0x020A, 0 },
00201 { "SETVIEWPORTEXT", 0x020E, 0 },
00202 { "SETVIEWPORTORG", 0x020D, 0 },
00203 { "SETWINDOWEXT", 0x020C, &KWmf::opWindowSetExt },
00204 { "SETWINDOWORG", 0x020B, &KWmf::opWindowSetOrg },
00205 { "STRETCHBLT", 0x0B23, 0 },
00206 { "STRETCHDIB", 0x0f43, 0 },
00207 { "TEXTOUT", 0x0521, 0 },
00208 { NULL, 0, 0 }
00209 };
00210 unsigned i;
00211 method result;
00212
00213
00214
00215 for (i = 0; funcTab[i].name; i++)
00216 {
00217 if (funcTab[i].opcode == opcode)
00218 {
00219 break;
00220 }
00221 }
00222
00223
00224
00225 result = funcTab[i].handler;
00226 if (!result)
00227 {
00228 if (funcTab[i].name)
00229 kError(s_area) << "invokeHandler: unsupported opcode: " <<
00230 funcTab[i].name <<
00231 " operands: " << words << endl;
00232 else
00233 kError(s_area) << "invokeHandler: unsupported opcode: 0x" <<
00234 QString::number(opcode, 16) <<
00235 " operands: " << words << endl;
00236
00237
00238
00239 for (i = 0; i < words; i++)
00240 {
00241 S16 discard;
00242
00243 operands >> discard;
00244 }
00245 }
00246 else
00247 {
00248 kDebug(s_area) << "invokeHandler: opcode: " << funcTab[i].name <<
00249 " operands: " << words << endl;
00250
00251
00252
00253
00254
00255
00256
00257 if (words)
00258 {
00259 QByteArray *record = new QByteArray();
00260 record->resize( words*2 );
00261 QDataStream *body;
00262
00263 operands.readRawData(record->data(), words * 2);
00264 body = new QDataStream(record, QIODevice::ReadOnly);
00265 body->setByteOrder(QDataStream::LittleEndian);
00266 (this->*result)(words, *body);
00267 delete body;
00268 delete record;
00269 }
00270 else
00271 {
00272 QDataStream *body = new QDataStream();
00273
00274 (this->*result)(words, *body);
00275 delete body;
00276 }
00277 }
00278 }
00279
00280 QPoint KWmf::normalisePoint(
00281 QDataStream &operands)
00282 {
00283 S16 x;
00284 S16 y;
00285
00286 operands >> x >> y;
00287 return QPoint((x - m_windowOrgX) * m_windowFlipX / m_dpi, (y - m_windowOrgY) * m_windowFlipY / m_dpi);
00288 }
00289
00290 QSize KWmf::normaliseSize(
00291 QDataStream &operands)
00292 {
00293 S16 width;
00294 S16 height;
00295
00296 operands >> width >> height;
00297 return QSize(width / m_dpi, height / m_dpi);
00298 }
00299
00300 bool KWmf::parse(
00301 const QString &file)
00302 {
00303 QFile in(file);
00304 if (!in.open(QIODevice::ReadOnly))
00305 {
00306 kError(s_area) << "Unable to open input file!" << endl;
00307 in.close();
00308 return false;
00309 }
00310 QDataStream stream(&in);
00311 bool result = parse(stream, in.size());
00312 in.close();
00313 return result;
00314 }
00315
00316 bool KWmf::parse(
00317 QDataStream &stream,
00318 unsigned size)
00319 {
00320 int startedAt;
00321 bool isPlaceable;
00322 bool isEnhanced;
00323
00324 startedAt = stream.device()->pos();
00325 stream.setByteOrder(QDataStream::LittleEndian);
00326
00327 typedef struct _RECT
00328 {
00329 S16 left;
00330 S16 top;
00331 S16 right;
00332 S16 bottom;
00333 } RECT;
00334
00335 typedef struct _RECTL
00336 {
00337 S32 left;
00338 S32 top;
00339 S32 right;
00340 S32 bottom;
00341 } RECTL;
00342
00343 typedef struct _SIZE
00344 {
00345 S16 width;
00346 S16 height;
00347 } SIZE;
00348
00349 typedef struct _SIZEL
00350 {
00351 S32 width;
00352 S32 height;
00353 } SIZEL;
00354
00355 struct WmfEnhMetaHeader
00356 {
00357 S32 iType;
00358 S32 nSize;
00359
00360 RECTL rclBounds;
00361 RECTL rclFrame;
00362
00363 S32 dSignature;
00364 S32 nVersion;
00365 S32 nBytes;
00366 S32 nRecords;
00367 S16 nHandles;
00368
00369 S16 sReserved;
00370 S32 nDescription;
00371
00372 S32 offDescription;
00373
00374 S32 nPalEntries;
00375 SIZEL szlDevice;
00376 SIZEL szlMillimeters;
00377 };
00378 #define ENHMETA_SIGNATURE 0x464D4520
00379
00380 struct WmfMetaHeader
00381 {
00382 S16 mtType;
00383 S16 mtHeaderSize;
00384 S16 mtVersion;
00385 S32 mtSize;
00386 S16 mtNoObjects;
00387 S32 mtMaxRecord;
00388 S16 mtNoParameters;
00389 };
00390
00391 struct WmfPlaceableHeader
00392 {
00393 S32 key;
00394 S16 hmf;
00395 RECT bbox;
00396 S16 inch;
00397 S32 reserved;
00398 S16 checksum;
00399 };
00400 #define APMHEADER_KEY 0x9AC6CDD7L
00401
00402 WmfPlaceableHeader pheader;
00403 WmfEnhMetaHeader eheader;
00404 WmfMetaHeader header;
00405 S16 checksum;
00406 int fileAt;
00407
00408
00409
00410 stream >> pheader.key;
00411 isPlaceable = (pheader.key == (S32)APMHEADER_KEY);
00412 if (isPlaceable)
00413 {
00414 stream >> pheader.hmf;
00415 stream >> pheader.bbox.left;
00416 stream >> pheader.bbox.top;
00417 stream >> pheader.bbox.right;
00418 stream >> pheader.bbox.bottom;
00419 stream >> pheader.inch;
00420 stream >> pheader.reserved;
00421 stream >> pheader.checksum;
00422 checksum = 0;
00423 S16 *ptr = (S16 *)&pheader;
00424
00425
00426
00427 for (unsigned i = 0; i < sizeof(WmfPlaceableHeader)/sizeof(S16); i++)
00428 {
00429 checksum ^= ptr[i];
00430 }
00431 if (pheader.checksum != checksum)
00432 isPlaceable = false;
00433 m_dpi = (unsigned)((double)pheader.inch / m_dpi);
00434 m_windowOrgX = pheader.bbox.left;
00435 m_windowOrgY = pheader.bbox.top;
00436 if (pheader.bbox.right > pheader.bbox.left)
00437 m_windowFlipX = 1;
00438 else
00439 m_windowFlipX = -1;
00440 if (pheader.bbox.bottom > pheader.bbox.top)
00441 m_windowFlipY = 1;
00442 else
00443 m_windowFlipY = -1;
00444 }
00445 else
00446 {
00447 stream.device()->seek(startedAt);
00448 m_dpi = (unsigned)((double)576 / m_dpi);
00449 m_windowOrgX = 0;
00450 m_windowOrgY = 0;
00451 m_windowFlipX = 1;
00452 m_windowFlipY = 1;
00453 }
00454
00455
00456
00457 fileAt = stream.device()->pos();
00458 stream >> eheader.iType;
00459 stream >> eheader.nSize;
00460 stream >> eheader.rclBounds.left;
00461 stream >> eheader.rclBounds.top;
00462 stream >> eheader.rclBounds.right;
00463 stream >> eheader.rclBounds.bottom;
00464 stream >> eheader.rclFrame.left;
00465 stream >> eheader.rclFrame.top;
00466 stream >> eheader.rclFrame.right;
00467 stream >> eheader.rclFrame.bottom;
00468 stream >> eheader.dSignature;
00469 isEnhanced = (eheader.dSignature == ENHMETA_SIGNATURE);
00470 if (isEnhanced)
00471 {
00472 stream >> eheader.nVersion;
00473 stream >> eheader.nBytes;
00474 stream >> eheader.nRecords;
00475 stream >> eheader.nHandles;
00476 stream >> eheader.sReserved;
00477 stream >> eheader.nDescription;
00478 stream >> eheader.offDescription;
00479 stream >> eheader.nPalEntries;
00480 stream >> eheader.szlDevice.width;
00481 stream >> eheader.szlDevice.height;
00482 stream >> eheader.szlMillimeters.width;
00483 stream >> eheader.szlMillimeters.height;
00484
00485 kError(s_area) << "WMF Extended Header NOT YET IMPLEMENTED, SORRY." << endl;
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 return false;
00504 }
00505 else
00506 {
00507
00508
00509 stream.device()->seek(fileAt);
00510 stream >> header.mtType;
00511 stream >> header.mtHeaderSize;
00512 stream >> header.mtVersion;
00513 stream >> header.mtSize;
00514 stream >> header.mtNoObjects;
00515 stream >> header.mtMaxRecord;
00516 stream >> header.mtNoParameters;
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526 }
00527
00528 walk((size - (stream.device()->pos() - startedAt)) / 2, stream);
00529 return true;
00530 }
00531
00532 void KWmf::opArc(
00533 U32 ,
00534 QDataStream &operands)
00535 {
00536 genericArc("arc", operands);
00537 }
00538
00539 void KWmf::opBrushCreateIndirect(
00540 U32 ,
00541 QDataStream &operands)
00542 {
00543 static Qt::BrushStyle hatchedStyleTab[] =
00544 {
00545 Qt::HorPattern,
00546 Qt::FDiagPattern,
00547 Qt::BDiagPattern,
00548 Qt::CrossPattern,
00549 Qt::DiagCrossPattern
00550 };
00551 static Qt::BrushStyle styleTab[] =
00552 {
00553 Qt::SolidPattern,
00554 Qt::NoBrush,
00555 Qt::FDiagPattern,
00556 Qt::Dense4Pattern,
00557 Qt::HorPattern,
00558 Qt::VerPattern,
00559 Qt::Dense6Pattern,
00560 Qt::Dense2Pattern,
00561 Qt::Dense3Pattern
00562 };
00563 Qt::BrushStyle style;
00564 WinObjBrushHandle *handle = handleCreateBrush();
00565 S16 arg;
00566 S32 color;
00567 S16 discard;
00568
00569 operands >> arg >> color;
00570 handle->m_color = getColor(color);
00571 if (arg == 2)
00572 {
00573 operands >> arg;
00574 if (arg >= 0 && arg < 6)
00575 {
00576 style = hatchedStyleTab[arg];
00577 }
00578 else
00579 {
00580 kError(s_area) << "createBrushIndirect: invalid hatched brush " << arg << endl;
00581 style = Qt::SolidPattern;
00582 }
00583 }
00584 else
00585 if (arg >= 0 && arg < 9)
00586 {
00587 style = styleTab[arg];
00588 operands >> discard;
00589 }
00590 else
00591 {
00592 kError(s_area) << "createBrushIndirect: invalid brush " << arg << endl;
00593 style = Qt::SolidPattern;
00594 operands >> discard;
00595 }
00596 handle->m_style = style;
00597 }
00598
00599 void KWmf::opEllipse(
00600 U32 ,
00601 QDataStream &operands)
00602 {
00603 QPoint topLeft;
00604 QPoint bottomRight;
00605
00606 topLeft = normalisePoint(operands);
00607 bottomRight = normalisePoint(operands);
00608
00609 QRect ellipse(topLeft, bottomRight);
00610
00611 gotEllipse(m_dc, "full", ellipse.center(), ellipse.size() / 2, 0, 0);
00612 }
00613
00614 void KWmf::opLineTo(
00615 U32 ,
00616 QDataStream &operands)
00617 {
00618 QPoint lineTo;
00619
00620 lineTo = normalisePoint(operands);
00621 QPolygon points(2);
00622 points.setPoint(0, m_lineFrom);
00623 points.setPoint(1, lineTo);
00624 gotPolyline(m_dc, points);
00625
00626
00627
00628 m_lineFrom = lineTo;
00629 }
00630
00631 void KWmf::opMoveTo(
00632 U32 ,
00633 QDataStream &operands)
00634 {
00635 m_lineFrom = normalisePoint(operands);
00636 }
00637
00638 void KWmf::opNoop(
00639 U32 words,
00640 QDataStream &operands)
00641 {
00642 skip(words, operands);
00643 }
00644
00645
00646 void KWmf::opObjectDelete(
00647 U32 ,
00648 QDataStream &operands)
00649 {
00650 S16 idx;
00651
00652 operands >> idx;
00653 }
00654
00655
00656 void KWmf::opObjectSelect(
00657 U32 ,
00658 QDataStream &operands)
00659 {
00660 S16 idx;
00661
00662 operands >> idx;
00663 if (idx >= 0 && idx < m_objectHandles.count())
00664 m_objectHandles[idx]->apply(*this);
00665 }
00666
00667
00668
00669
00670
00671 void KWmf::opPenCreateIndirect(
00672 U32 ,
00673 QDataStream &operands)
00674 {
00675 static Qt::PenStyle styleTab[] =
00676 {
00677 Qt::SolidLine,
00678 Qt::DashLine,
00679 Qt::DotLine,
00680 Qt::DashDotLine,
00681 Qt::DashDotDotLine,
00682 Qt::NoPen,
00683 Qt::SolidLine,
00684 Qt::SolidLine,
00685 Qt::SolidLine
00686 };
00687 WinObjPenHandle *handle = handleCreatePen();
00688 S16 arg;
00689 S32 color;
00690
00691 operands >> arg;
00692 if (arg >= 0 && arg < 8)
00693 {
00694 handle->m_style = styleTab[arg];
00695 }
00696 else
00697 {
00698 kError(s_area) << "createPenIndirect: invalid pen " << arg << endl;
00699 handle->m_style = Qt::SolidLine;
00700 }
00701 operands >> arg;
00702 handle->m_width = arg;
00703 operands >> arg >> color;
00704 handle->m_color = getColor(color);
00705 }
00706
00707 void KWmf::opPie(
00708 U32 ,
00709 QDataStream &operands)
00710 {
00711 genericArc("pie", operands);
00712 }
00713
00714 void KWmf::opPolygonSetFillMode(
00715 U32 ,
00716 QDataStream &operands)
00717 {
00718 S16 tmp;
00719
00720 operands >> tmp;
00721 m_dc.m_winding = tmp != 0;
00722 }
00723
00724 void KWmf::opPolygon(
00725 U32 ,
00726 QDataStream &operands)
00727 {
00728 S16 tmp;
00729
00730 operands >> tmp;
00731 QPolygon points(tmp);
00732
00733 for (int i = 0; i < tmp; i++)
00734 {
00735 points.setPoint(i, normalisePoint(operands));
00736 }
00737 gotPolygon(m_dc, points);
00738 }
00739
00740 void KWmf::opPolyline(
00741 U32 ,
00742 QDataStream &operands)
00743 {
00744 S16 tmp;
00745
00746 operands >> tmp;
00747 QPolygon points(tmp);
00748
00749 for (int i = 0; i < tmp; i++)
00750 {
00751 points.setPoint(i, normalisePoint(operands));
00752 }
00753 gotPolyline(m_dc, points);
00754 }
00755
00756 void KWmf::opRectangle(
00757 U32 ,
00758 QDataStream &operands)
00759 {
00760 QPoint topLeft;
00761 QSize size;
00762
00763 topLeft = normalisePoint(operands);
00764 size = normaliseSize(operands);
00765 QRect rect(topLeft, size);
00766 QPolygon points(4);
00767
00768 points.setPoint(0, topLeft);
00769 points.setPoint(1, rect.topRight());
00770 points.setPoint(2, rect.bottomRight());
00771 points.setPoint(3, rect.bottomLeft());
00772 gotRectangle(m_dc, points);
00773 }
00774
00775 void KWmf::opRestoreDc(
00776 U32 ,
00777 QDataStream &operands)
00778 {
00779 S16 pop;
00780 S16 i;
00781
00782 operands >> pop;
00783 for (i = 0; i < pop; i++)
00784 {
00785 m_dc = m_savedDcs.pop();
00786 }
00787 }
00788
00789 void KWmf::opSaveDc(
00790 U32 ,
00791 QDataStream &)
00792 {
00793 m_savedDcs.push(m_dc);
00794
00795
00796 }
00797
00798 void KWmf::opWindowSetOrg(
00799 U32 ,
00800 QDataStream &operands)
00801 {
00802 S16 top;
00803 S16 left;
00804
00805 operands >> top >> left;
00806 m_windowOrgX = left;
00807 m_windowOrgY = top;
00808 }
00809
00810 void KWmf::opWindowSetExt(
00811 U32 ,
00812 QDataStream &operands)
00813 {
00814 S16 height;
00815 S16 width;
00816
00817 operands >> height >> width;
00818 if (width > 0)
00819 m_windowFlipX = 1;
00820 else
00821 m_windowFlipX = -1;
00822 if (height > 0)
00823 m_windowFlipY = 1;
00824 else
00825 m_windowFlipY = -1;
00826 }
00827
00828 void KWmf::penSet(
00829 unsigned color,
00830 unsigned style,
00831 unsigned width)
00832 {
00833 m_dc.m_penColor = color;
00834 m_dc.m_penStyle = style;
00835 m_dc.m_penWidth = width;
00836 }
00837
00838 void KWmf::skip(
00839 U32 words,
00840 QDataStream &operands)
00841 {
00842 if ((int)words < 0)
00843 {
00844 kError(s_area) << "skip: " << (int)words << endl;
00845 return;
00846 }
00847 if (words)
00848 {
00849 U32 i;
00850 S16 discard;
00851
00852 kDebug(s_area) << "skip: " << words << endl;
00853 for (i = 0; i < words; i++)
00854 {
00855 operands >> discard;
00856 }
00857 }
00858 }
00859
00860 void KWmf::walk(
00861 U32 words,
00862 QDataStream &operands)
00863 {
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880 S32 wordCount;
00881 S16 opcode;
00882 U32 length = 0;
00883
00884 while (length < words)
00885 {
00886 operands >> wordCount;
00887 operands >> opcode;
00888
00889
00890 if (length + wordCount > words)
00891 {
00892 wordCount = words - length;
00893 }
00894 length += wordCount;
00895 if (opcode == 0)
00896 {
00897
00898 break;
00899 }
00900
00901
00902
00903 invokeHandler(opcode, wordCount - 3, operands);
00904 }
00905
00906
00907 skip(words - length, operands);
00908 }
00909
00910 KWmf::DrawContext::DrawContext()
00911 {
00912
00913 m_brushColor = 0x808080;
00914 m_brushStyle = 1;
00915 m_penColor = 0x808080;
00916 m_penStyle = 1;
00917 m_penWidth = 1;
00918 }
00919
00920 void KWmf::WinObjBrushHandle::apply(
00921 KWmf &p)
00922 {
00923 p.brushSet(m_color, m_style);
00924 }
00925
00926 void KWmf::WinObjPenHandle::apply(
00927 KWmf &p)
00928 {
00929 p.penSet(m_color, m_style, m_width);
00930 }