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