1 /* 2 * Enhanced MetaFile driver dc value functions 3 * 4 * Copyright 1999 Huw D M Davies 5 * Copyright 2016 Alexandre Julliard 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include <assert.h> 23 #include "enhmfdrv/enhmetafiledrv.h" 24 25 /* get the emf physdev from the path physdev */ 26 static inline PHYSDEV get_emfdev( PHYSDEV path ) 27 { 28 return &CONTAINING_RECORD( path, EMFDRV_PDEVICE, pathdev )->dev; 29 } 30 31 static const struct gdi_dc_funcs emfpath_driver; 32 33 INT EMFDRV_SaveDC( PHYSDEV dev ) 34 { 35 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSaveDC ); 36 INT ret = next->funcs->pSaveDC( next ); 37 38 if (ret) 39 { 40 EMRSAVEDC emr; 41 emr.emr.iType = EMR_SAVEDC; 42 emr.emr.nSize = sizeof(emr); 43 EMFDRV_WriteRecord( dev, &emr.emr ); 44 } 45 return ret; 46 } 47 48 BOOL EMFDRV_RestoreDC( PHYSDEV dev, INT level ) 49 { 50 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRestoreDC ); 51 EMFDRV_PDEVICE* physDev = get_emf_physdev( dev ); 52 DC *dc = get_physdev_dc( dev ); 53 EMRRESTOREDC emr; 54 BOOL ret; 55 56 emr.emr.iType = EMR_RESTOREDC; 57 emr.emr.nSize = sizeof(emr); 58 59 if (level < 0) 60 emr.iRelative = level; 61 else 62 emr.iRelative = level - dc->saveLevel - 1; 63 64 physDev->restoring++; 65 ret = next->funcs->pRestoreDC( next, level ); 66 physDev->restoring--; 67 68 if (ret) EMFDRV_WriteRecord( dev, &emr.emr ); 69 return ret; 70 } 71 72 UINT EMFDRV_SetTextAlign( PHYSDEV dev, UINT align ) 73 { 74 EMRSETTEXTALIGN emr; 75 emr.emr.iType = EMR_SETTEXTALIGN; 76 emr.emr.nSize = sizeof(emr); 77 emr.iMode = align; 78 return EMFDRV_WriteRecord( dev, &emr.emr ) ? align : GDI_ERROR; 79 } 80 81 BOOL EMFDRV_SetTextJustification(PHYSDEV dev, INT nBreakExtra, INT nBreakCount) 82 { 83 EMRSETTEXTJUSTIFICATION emr; 84 emr.emr.iType = EMR_SETTEXTJUSTIFICATION; 85 emr.emr.nSize = sizeof(emr); 86 emr.nBreakExtra = nBreakExtra; 87 emr.nBreakCount = nBreakCount; 88 return EMFDRV_WriteRecord(dev, &emr.emr); 89 } 90 91 INT EMFDRV_SetBkMode( PHYSDEV dev, INT mode ) 92 { 93 EMRSETBKMODE emr; 94 emr.emr.iType = EMR_SETBKMODE; 95 emr.emr.nSize = sizeof(emr); 96 emr.iMode = mode; 97 return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0; 98 } 99 100 COLORREF EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color ) 101 { 102 EMRSETBKCOLOR emr; 103 EMFDRV_PDEVICE *physDev = get_emf_physdev( dev ); 104 105 if (physDev->restoring) return color; /* don't output records during RestoreDC */ 106 107 emr.emr.iType = EMR_SETBKCOLOR; 108 emr.emr.nSize = sizeof(emr); 109 emr.crColor = color; 110 return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID; 111 } 112 113 114 COLORREF EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color ) 115 { 116 EMRSETTEXTCOLOR emr; 117 EMFDRV_PDEVICE *physDev = get_emf_physdev( dev ); 118 119 if (physDev->restoring) return color; /* don't output records during RestoreDC */ 120 121 emr.emr.iType = EMR_SETTEXTCOLOR; 122 emr.emr.nSize = sizeof(emr); 123 emr.crColor = color; 124 return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID; 125 } 126 127 INT EMFDRV_SetROP2( PHYSDEV dev, INT rop ) 128 { 129 EMRSETROP2 emr; 130 emr.emr.iType = EMR_SETROP2; 131 emr.emr.nSize = sizeof(emr); 132 emr.iMode = rop; 133 return EMFDRV_WriteRecord( dev, &emr.emr ) ? rop : 0; 134 } 135 136 INT EMFDRV_SetPolyFillMode( PHYSDEV dev, INT mode ) 137 { 138 EMRSETPOLYFILLMODE emr; 139 emr.emr.iType = EMR_SETPOLYFILLMODE; 140 emr.emr.nSize = sizeof(emr); 141 emr.iMode = mode; 142 return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0; 143 } 144 145 INT EMFDRV_SetStretchBltMode( PHYSDEV dev, INT mode ) 146 { 147 EMRSETSTRETCHBLTMODE emr; 148 emr.emr.iType = EMR_SETSTRETCHBLTMODE; 149 emr.emr.nSize = sizeof(emr); 150 emr.iMode = mode; 151 return EMFDRV_WriteRecord( dev, &emr.emr ) ? mode : 0; 152 } 153 154 INT EMFDRV_SetArcDirection(PHYSDEV dev, INT arcDirection) 155 { 156 EMRSETARCDIRECTION emr; 157 158 emr.emr.iType = EMR_SETARCDIRECTION; 159 emr.emr.nSize = sizeof(emr); 160 emr.iArcDirection = arcDirection; 161 return EMFDRV_WriteRecord(dev, &emr.emr) ? arcDirection : 0; 162 } 163 164 INT EMFDRV_ExcludeClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) 165 { 166 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExcludeClipRect ); 167 EMREXCLUDECLIPRECT emr; 168 169 emr.emr.iType = EMR_EXCLUDECLIPRECT; 170 emr.emr.nSize = sizeof(emr); 171 emr.rclClip.left = left; 172 emr.rclClip.top = top; 173 emr.rclClip.right = right; 174 emr.rclClip.bottom = bottom; 175 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR; 176 return next->funcs->pExcludeClipRect( next, left, top, right, bottom ); 177 } 178 179 INT EMFDRV_IntersectClipRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom) 180 { 181 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pIntersectClipRect ); 182 EMRINTERSECTCLIPRECT emr; 183 184 emr.emr.iType = EMR_INTERSECTCLIPRECT; 185 emr.emr.nSize = sizeof(emr); 186 emr.rclClip.left = left; 187 emr.rclClip.top = top; 188 emr.rclClip.right = right; 189 emr.rclClip.bottom = bottom; 190 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR; 191 return next->funcs->pIntersectClipRect( next, left, top, right, bottom ); 192 } 193 194 INT EMFDRV_OffsetClipRgn( PHYSDEV dev, INT x, INT y ) 195 { 196 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetClipRgn ); 197 EMROFFSETCLIPRGN emr; 198 199 emr.emr.iType = EMR_OFFSETCLIPRGN; 200 emr.emr.nSize = sizeof(emr); 201 emr.ptlOffset.x = x; 202 emr.ptlOffset.y = y; 203 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return ERROR; 204 return next->funcs->pOffsetClipRgn( next, x, y ); 205 } 206 207 INT EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode ) 208 { 209 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExtSelectClipRgn ); 210 EMREXTSELECTCLIPRGN *emr; 211 DWORD size, rgnsize; 212 BOOL ret; 213 214 if (!hrgn) 215 { 216 if (mode != RGN_COPY) return ERROR; 217 rgnsize = 0; 218 } 219 else rgnsize = GetRegionData( hrgn, 0, NULL ); 220 221 size = rgnsize + offsetof(EMREXTSELECTCLIPRGN,RgnData); 222 emr = HeapAlloc( GetProcessHeap(), 0, size ); 223 if (rgnsize) GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData ); 224 225 emr->emr.iType = EMR_EXTSELECTCLIPRGN; 226 emr->emr.nSize = size; 227 emr->cbRgnData = rgnsize; 228 emr->iMode = mode; 229 230 ret = EMFDRV_WriteRecord( dev, &emr->emr ); 231 HeapFree( GetProcessHeap(), 0, emr ); 232 return ret ? next->funcs->pExtSelectClipRgn( next, hrgn, mode ) : ERROR; 233 } 234 235 INT EMFDRV_SetMapMode( PHYSDEV dev, INT mode ) 236 { 237 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode ); 238 EMRSETMAPMODE emr; 239 emr.emr.iType = EMR_SETMAPMODE; 240 emr.emr.nSize = sizeof(emr); 241 emr.iMode = mode; 242 243 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0; 244 return next->funcs->pSetMapMode( next, mode ); 245 } 246 247 BOOL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size ) 248 { 249 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportExtEx ); 250 EMRSETVIEWPORTEXTEX emr; 251 252 emr.emr.iType = EMR_SETVIEWPORTEXTEX; 253 emr.emr.nSize = sizeof(emr); 254 emr.szlExtent.cx = cx; 255 emr.szlExtent.cy = cy; 256 257 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; 258 return next->funcs->pSetViewportExtEx( next, cx, cy, size ); 259 } 260 261 BOOL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size ) 262 { 263 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowExtEx ); 264 EMRSETWINDOWEXTEX emr; 265 266 emr.emr.iType = EMR_SETWINDOWEXTEX; 267 emr.emr.nSize = sizeof(emr); 268 emr.szlExtent.cx = cx; 269 emr.szlExtent.cy = cy; 270 271 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; 272 return next->funcs->pSetWindowExtEx( next, cx, cy, size ); 273 } 274 275 BOOL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) 276 { 277 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportOrgEx ); 278 EMRSETVIEWPORTORGEX emr; 279 280 emr.emr.iType = EMR_SETVIEWPORTORGEX; 281 emr.emr.nSize = sizeof(emr); 282 emr.ptlOrigin.x = x; 283 emr.ptlOrigin.y = y; 284 285 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; 286 return next->funcs->pSetViewportOrgEx( next, x, y, pt ); 287 } 288 289 BOOL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) 290 { 291 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowOrgEx ); 292 EMRSETWINDOWORGEX emr; 293 294 emr.emr.iType = EMR_SETWINDOWORGEX; 295 emr.emr.nSize = sizeof(emr); 296 emr.ptlOrigin.x = x; 297 emr.ptlOrigin.y = y; 298 299 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; 300 return next->funcs->pSetWindowOrgEx( next, x, y, pt ); 301 } 302 303 BOOL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size ) 304 { 305 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleViewportExtEx ); 306 EMRSCALEVIEWPORTEXTEX emr; 307 308 emr.emr.iType = EMR_SCALEVIEWPORTEXTEX; 309 emr.emr.nSize = sizeof(emr); 310 emr.xNum = xNum; 311 emr.xDenom = xDenom; 312 emr.yNum = yNum; 313 emr.yDenom = yDenom; 314 315 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; 316 return next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size ); 317 } 318 319 BOOL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size ) 320 { 321 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleWindowExtEx ); 322 EMRSCALEWINDOWEXTEX emr; 323 324 emr.emr.iType = EMR_SCALEWINDOWEXTEX; 325 emr.emr.nSize = sizeof(emr); 326 emr.xNum = xNum; 327 emr.xDenom = xDenom; 328 emr.yNum = yNum; 329 emr.yDenom = yDenom; 330 331 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; 332 return next->funcs->pScaleWindowExtEx( next, xNum, xDenom, yNum, yDenom, size ); 333 } 334 335 DWORD EMFDRV_SetLayout( PHYSDEV dev, DWORD layout ) 336 { 337 EMRSETLAYOUT emr; 338 339 emr.emr.iType = EMR_SETLAYOUT; 340 emr.emr.nSize = sizeof(emr); 341 emr.iMode = layout; 342 return EMFDRV_WriteRecord( dev, &emr.emr ) ? layout : GDI_ERROR; 343 } 344 345 BOOL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform) 346 { 347 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWorldTransform ); 348 EMRSETWORLDTRANSFORM emr; 349 350 emr.emr.iType = EMR_SETWORLDTRANSFORM; 351 emr.emr.nSize = sizeof(emr); 352 emr.xform = *xform; 353 354 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; 355 return next->funcs->pSetWorldTransform( next, xform ); 356 } 357 358 BOOL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode) 359 { 360 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pModifyWorldTransform ); 361 EMRMODIFYWORLDTRANSFORM emr; 362 363 emr.emr.iType = EMR_MODIFYWORLDTRANSFORM; 364 emr.emr.nSize = sizeof(emr); 365 emr.xform = *xform; 366 emr.iMode = mode; 367 368 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; 369 return next->funcs->pModifyWorldTransform( next, xform, mode ); 370 } 371 372 BOOL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) 373 { 374 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetViewportOrgEx ); 375 EMRSETVIEWPORTORGEX emr; 376 POINT prev; 377 378 GetViewportOrgEx( dev->hdc, &prev ); 379 380 emr.emr.iType = EMR_SETVIEWPORTORGEX; 381 emr.emr.nSize = sizeof(emr); 382 emr.ptlOrigin.x = prev.x + x; 383 emr.ptlOrigin.y = prev.y + y; 384 385 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; 386 return next->funcs->pOffsetViewportOrgEx( next, x, y, pt ); 387 } 388 389 BOOL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) 390 { 391 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetWindowOrgEx ); 392 EMRSETWINDOWORGEX emr; 393 POINT prev; 394 395 GetWindowOrgEx( dev->hdc, &prev ); 396 397 emr.emr.iType = EMR_SETWINDOWORGEX; 398 emr.emr.nSize = sizeof(emr); 399 emr.ptlOrigin.x = prev.x + x; 400 emr.ptlOrigin.y = prev.y + y; 401 402 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; 403 return next->funcs->pOffsetWindowOrgEx( next, x, y, pt ); 404 } 405 406 DWORD EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags ) 407 { 408 EMRSETMAPPERFLAGS emr; 409 410 emr.emr.iType = EMR_SETMAPPERFLAGS; 411 emr.emr.nSize = sizeof(emr); 412 emr.dwFlags = flags; 413 414 return EMFDRV_WriteRecord( dev, &emr.emr ) ? flags : GDI_ERROR; 415 } 416 417 BOOL EMFDRV_AbortPath( PHYSDEV dev ) 418 { 419 EMRABORTPATH emr; 420 421 emr.emr.iType = EMR_ABORTPATH; 422 emr.emr.nSize = sizeof(emr); 423 424 return EMFDRV_WriteRecord( dev, &emr.emr ); 425 } 426 427 BOOL EMFDRV_BeginPath( PHYSDEV dev ) 428 { 429 EMFDRV_PDEVICE *physDev = get_emf_physdev( dev ); 430 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pBeginPath ); 431 EMRBEGINPATH emr; 432 DC *dc = get_physdev_dc( dev ); 433 434 emr.emr.iType = EMR_BEGINPATH; 435 emr.emr.nSize = sizeof(emr); 436 437 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; 438 if (physDev->path) return TRUE; /* already open */ 439 440 if (!next->funcs->pBeginPath( next )) return FALSE; 441 push_dc_driver( &dc->physDev, &physDev->pathdev, &emfpath_driver ); 442 physDev->path = TRUE; 443 return TRUE; 444 } 445 446 BOOL EMFDRV_CloseFigure( PHYSDEV dev ) 447 { 448 EMRCLOSEFIGURE emr; 449 450 emr.emr.iType = EMR_CLOSEFIGURE; 451 emr.emr.nSize = sizeof(emr); 452 453 EMFDRV_WriteRecord( dev, &emr.emr ); 454 return FALSE; /* always fails without a path */ 455 } 456 457 BOOL EMFDRV_EndPath( PHYSDEV dev ) 458 { 459 EMRENDPATH emr; 460 461 emr.emr.iType = EMR_ENDPATH; 462 emr.emr.nSize = sizeof(emr); 463 464 EMFDRV_WriteRecord( dev, &emr.emr ); 465 return FALSE; /* always fails without a path */ 466 } 467 468 BOOL EMFDRV_FlattenPath( PHYSDEV dev ) 469 { 470 EMRFLATTENPATH emr; 471 472 emr.emr.iType = EMR_FLATTENPATH; 473 emr.emr.nSize = sizeof(emr); 474 475 return EMFDRV_WriteRecord( dev, &emr.emr ); 476 } 477 478 BOOL EMFDRV_SelectClipPath( PHYSDEV dev, INT iMode ) 479 { 480 // PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSelectClipPath ); This HACK breaks test_emf_clipping 481 EMRSELECTCLIPPATH emr; 482 // BOOL ret = FALSE; 483 // HRGN hrgn; 484 485 emr.emr.iType = EMR_SELECTCLIPPATH; 486 emr.emr.nSize = sizeof(emr); 487 emr.iMode = iMode; 488 489 if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; 490 /* hrgn = PathToRegion( dev->hdc ); 491 if (hrgn) 492 { 493 ret = next->funcs->pExtSelectClipRgn( next, hrgn, iMode ); 494 DeleteObject( hrgn ); 495 } ERR("EMFDRV_SelectClipPath ret %d\n",ret); 496 return ret;*/ 497 return TRUE; 498 } 499 500 BOOL EMFDRV_WidenPath( PHYSDEV dev ) 501 { 502 EMRWIDENPATH emr; 503 504 emr.emr.iType = EMR_WIDENPATH; 505 emr.emr.nSize = sizeof(emr); 506 507 return EMFDRV_WriteRecord( dev, &emr.emr ); 508 } 509 510 INT EMFDRV_GetDeviceCaps(PHYSDEV dev, INT cap) 511 { 512 EMFDRV_PDEVICE *physDev = get_emf_physdev( dev ); 513 514 return GetDeviceCaps( physDev->ref_dc, cap ); 515 } 516 517 518 /*********************************************************************** 519 * emfpathdrv_AbortPath 520 */ 521 static BOOL emfpathdrv_AbortPath( PHYSDEV dev ) 522 { 523 PHYSDEV emfdev = get_emfdev( dev ); 524 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pAbortPath ); 525 DC *dc = get_physdev_dc( dev ); 526 527 emfpath_driver.pDeleteDC( pop_dc_driver( dc, &emfpath_driver )); 528 emfdev->funcs->pAbortPath( emfdev ); 529 return next->funcs->pAbortPath( next ); 530 } 531 532 /*********************************************************************** 533 * emfpathdrv_AngleArc 534 */ 535 static BOOL emfpathdrv_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius, FLOAT start, FLOAT sweep ) 536 { 537 PHYSDEV emfdev = get_emfdev( dev ); 538 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pAngleArc ); 539 540 return (emfdev->funcs->pAngleArc( emfdev, x, y, radius, start, sweep ) && 541 next->funcs->pAngleArc( next, x, y, radius, start, sweep )); 542 } 543 544 /*********************************************************************** 545 * emfpathdrv_Arc 546 */ 547 static BOOL emfpathdrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom, 548 INT xstart, INT ystart, INT xend, INT yend ) 549 { 550 PHYSDEV emfdev = get_emfdev( dev ); 551 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArc ); 552 553 return (emfdev->funcs->pArc( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) && 554 next->funcs->pArc( next, left, top, right, bottom, xstart, ystart, xend, yend )); 555 } 556 557 /*********************************************************************** 558 * emfpathdrv_ArcTo 559 */ 560 static BOOL emfpathdrv_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom, 561 INT xstart, INT ystart, INT xend, INT yend ) 562 { 563 PHYSDEV emfdev = get_emfdev( dev ); 564 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArcTo ); 565 566 return (emfdev->funcs->pArcTo( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) && 567 next->funcs->pArcTo( next, left, top, right, bottom, xstart, ystart, xend, yend )); 568 } 569 570 /*********************************************************************** 571 * emfpathdrv_BeginPath 572 */ 573 static BOOL emfpathdrv_BeginPath( PHYSDEV dev ) 574 { 575 PHYSDEV emfdev = get_emfdev( dev ); 576 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pBeginPath ); 577 578 return (emfdev->funcs->pBeginPath( emfdev ) && next->funcs->pBeginPath( next )); 579 } 580 581 /*********************************************************************** 582 * emfpathdrv_Chord 583 */ 584 static BOOL emfpathdrv_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom, 585 INT xstart, INT ystart, INT xend, INT yend ) 586 { 587 PHYSDEV emfdev = get_emfdev( dev ); 588 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pChord ); 589 590 return (emfdev->funcs->pChord( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) && 591 next->funcs->pChord( next, left, top, right, bottom, xstart, ystart, xend, yend )); 592 } 593 594 /*********************************************************************** 595 * emfpathdrv_CloseFigure 596 */ 597 static BOOL emfpathdrv_CloseFigure( PHYSDEV dev ) 598 { 599 PHYSDEV emfdev = get_emfdev( dev ); 600 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pCloseFigure ); 601 602 emfdev->funcs->pCloseFigure( emfdev ); 603 return next->funcs->pCloseFigure( next ); 604 } 605 606 /*********************************************************************** 607 * emfpathdrv_CreateDC 608 */ 609 static BOOL emfpathdrv_CreateDC( PHYSDEV *dev, LPCWSTR driver, LPCWSTR device, 610 LPCWSTR output, const DEVMODEW *devmode ) 611 { 612 assert( 0 ); /* should never be called */ 613 return TRUE; 614 } 615 616 /************************************************************* 617 * emfpathdrv_DeleteDC 618 */ 619 static BOOL emfpathdrv_DeleteDC( PHYSDEV dev ) 620 { 621 EMFDRV_PDEVICE *physdev = (EMFDRV_PDEVICE *)get_emfdev( dev ); 622 623 physdev->path = FALSE; 624 return TRUE; 625 } 626 627 /*********************************************************************** 628 * emfpathdrv_Ellipse 629 */ 630 static BOOL emfpathdrv_Ellipse( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 ) 631 { 632 PHYSDEV emfdev = get_emfdev( dev ); 633 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pEllipse ); 634 635 return (emfdev->funcs->pEllipse( emfdev, x1, y1, x2, y2 ) && 636 next->funcs->pEllipse( next, x1, y1, x2, y2 )); 637 } 638 639 /*********************************************************************** 640 * emfpathdrv_EndPath 641 */ 642 static BOOL emfpathdrv_EndPath( PHYSDEV dev ) 643 { 644 PHYSDEV emfdev = get_emfdev( dev ); 645 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pEndPath ); 646 DC *dc = get_physdev_dc( dev ); 647 648 emfpath_driver.pDeleteDC( pop_dc_driver( dc, &emfpath_driver )); 649 emfdev->funcs->pEndPath( emfdev ); 650 return next->funcs->pEndPath( next ); 651 } 652 653 /*********************************************************************** 654 * emfpathdrv_ExtTextOut 655 */ 656 static BOOL emfpathdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *rect, 657 LPCWSTR str, UINT count, const INT *dx ) 658 { 659 PHYSDEV emfdev = get_emfdev( dev ); 660 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pExtTextOut ); 661 662 return (emfdev->funcs->pExtTextOut( emfdev, x, y, flags, rect, str, count, dx ) && 663 next->funcs->pExtTextOut( next, x, y, flags, rect, str, count, dx )); 664 } 665 666 /*********************************************************************** 667 * emfpathdrv_LineTo 668 */ 669 static BOOL emfpathdrv_LineTo( PHYSDEV dev, INT x, INT y ) 670 { 671 PHYSDEV emfdev = get_emfdev( dev ); 672 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pLineTo ); 673 674 return (emfdev->funcs->pLineTo( emfdev, x, y ) && next->funcs->pLineTo( next, x, y )); 675 } 676 677 /*********************************************************************** 678 * emfpathdrv_MoveTo 679 */ 680 static BOOL emfpathdrv_MoveTo( PHYSDEV dev, INT x, INT y ) 681 { 682 PHYSDEV emfdev = get_emfdev( dev ); 683 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pMoveTo ); 684 685 return (emfdev->funcs->pMoveTo( emfdev, x, y ) && next->funcs->pMoveTo( next, x, y )); 686 } 687 688 /*********************************************************************** 689 * emfpathdrv_Pie 690 */ 691 static BOOL emfpathdrv_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom, 692 INT xstart, INT ystart, INT xend, INT yend ) 693 { 694 PHYSDEV emfdev = get_emfdev( dev ); 695 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPie ); 696 697 return (emfdev->funcs->pPie( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) && 698 next->funcs->pPie( next, left, top, right, bottom, xstart, ystart, xend, yend )); 699 } 700 701 /*********************************************************************** 702 * emfpathdrv_PolyBezier 703 */ 704 static BOOL emfpathdrv_PolyBezier( PHYSDEV dev, const POINT *pts, DWORD count ) 705 { 706 PHYSDEV emfdev = get_emfdev( dev ); 707 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyBezier ); 708 709 return (emfdev->funcs->pPolyBezier( emfdev, pts, count ) && 710 next->funcs->pPolyBezier( next, pts, count )); 711 } 712 713 /*********************************************************************** 714 * emfpathdrv_PolyBezierTo 715 */ 716 static BOOL emfpathdrv_PolyBezierTo( PHYSDEV dev, const POINT *pts, DWORD count ) 717 { 718 PHYSDEV emfdev = get_emfdev( dev ); 719 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyBezierTo ); 720 721 return (emfdev->funcs->pPolyBezierTo( emfdev, pts, count ) && 722 next->funcs->pPolyBezierTo( next, pts, count )); 723 } 724 725 /*********************************************************************** 726 * emfpathdrv_PolyDraw 727 */ 728 static BOOL emfpathdrv_PolyDraw( PHYSDEV dev, const POINT *pts, const BYTE *types, DWORD count ) 729 { 730 PHYSDEV emfdev = get_emfdev( dev ); 731 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyDraw ); 732 733 return (emfdev->funcs->pPolyDraw( emfdev, pts, types, count ) && 734 next->funcs->pPolyDraw( next, pts, types, count )); 735 } 736 737 /*********************************************************************** 738 * emfpathdrv_PolyPolygon 739 */ 740 static BOOL emfpathdrv_PolyPolygon( PHYSDEV dev, const POINT *pts, const INT *counts, UINT polygons ) 741 { 742 PHYSDEV emfdev = get_emfdev( dev ); 743 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolygon ); 744 745 return (emfdev->funcs->pPolyPolygon( emfdev, pts, counts, polygons ) && 746 next->funcs->pPolyPolygon( next, pts, counts, polygons )); 747 } 748 749 /*********************************************************************** 750 * emfpathdrv_PolyPolyline 751 */ 752 static BOOL emfpathdrv_PolyPolyline( PHYSDEV dev, const POINT *pts, const DWORD *counts, DWORD polylines ) 753 { 754 PHYSDEV emfdev = get_emfdev( dev ); 755 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolyline ); 756 757 return (emfdev->funcs->pPolyPolyline( emfdev, pts, counts, polylines ) && 758 next->funcs->pPolyPolyline( next, pts, counts, polylines )); 759 } 760 761 /*********************************************************************** 762 * emfpathdrv_Polygon 763 */ 764 static BOOL emfpathdrv_Polygon( PHYSDEV dev, const POINT *pts, INT count ) 765 { 766 PHYSDEV emfdev = get_emfdev( dev ); 767 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolygon ); 768 769 return (emfdev->funcs->pPolygon( emfdev, pts, count ) && 770 next->funcs->pPolygon( next, pts, count )); 771 } 772 773 /*********************************************************************** 774 * emfpathdrv_Polyline 775 */ 776 static BOOL emfpathdrv_Polyline( PHYSDEV dev, const POINT *pts, INT count ) 777 { 778 PHYSDEV emfdev = get_emfdev( dev ); 779 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyline ); 780 781 return (emfdev->funcs->pPolyline( emfdev, pts, count ) && 782 next->funcs->pPolyline( next, pts, count )); 783 } 784 785 /*********************************************************************** 786 * emfpathdrv_PolylineTo 787 */ 788 static BOOL emfpathdrv_PolylineTo( PHYSDEV dev, const POINT *pts, INT count ) 789 { 790 PHYSDEV emfdev = get_emfdev( dev ); 791 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolylineTo ); 792 793 return (emfdev->funcs->pPolylineTo( emfdev, pts, count ) && 794 next->funcs->pPolylineTo( next, pts, count )); 795 } 796 797 /*********************************************************************** 798 * emfpathdrv_Rectangle 799 */ 800 static BOOL emfpathdrv_Rectangle( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2 ) 801 { 802 PHYSDEV emfdev = get_emfdev( dev ); 803 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRectangle ); 804 805 return (emfdev->funcs->pRectangle( emfdev, x1, y1, x2, y2 ) && 806 next->funcs->pRectangle( next, x1, y1, x2, y2 )); 807 } 808 809 /*********************************************************************** 810 * emfpathdrv_RoundRect 811 */ 812 static BOOL emfpathdrv_RoundRect( PHYSDEV dev, INT x1, INT y1, INT x2, INT y2, 813 INT ell_width, INT ell_height ) 814 { 815 PHYSDEV emfdev = get_emfdev( dev ); 816 PHYSDEV next = GET_NEXT_PHYSDEV( dev, pRoundRect ); 817 818 return (emfdev->funcs->pRoundRect( emfdev, x1, y1, x2, y2, ell_width, ell_height ) && 819 next->funcs->pRoundRect( next, x1, y1, x2, y2, ell_width, ell_height )); 820 } 821 822 static const struct gdi_dc_funcs emfpath_driver = 823 { 824 NULL, /* pAbortDoc */ 825 emfpathdrv_AbortPath, /* pAbortPath */ 826 NULL, /* pAlphaBlend */ 827 emfpathdrv_AngleArc, /* pAngleArc */ 828 emfpathdrv_Arc, /* pArc */ 829 emfpathdrv_ArcTo, /* pArcTo */ 830 emfpathdrv_BeginPath, /* pBeginPath */ 831 NULL, /* pBlendImage */ 832 emfpathdrv_Chord, /* pChord */ 833 emfpathdrv_CloseFigure, /* pCloseFigure */ 834 NULL, /* pCreateCompatibleDC */ 835 emfpathdrv_CreateDC, /* pCreateDC */ 836 emfpathdrv_DeleteDC, /* pDeleteDC */ 837 NULL, /* pDeleteObject */ 838 NULL, /* pDeviceCapabilities */ 839 emfpathdrv_Ellipse, /* pEllipse */ 840 NULL, /* pEndDoc */ 841 NULL, /* pEndPage */ 842 emfpathdrv_EndPath, /* pEndPath */ 843 NULL, /* pEnumFonts */ 844 NULL, /* pEnumICMProfiles */ 845 NULL, /* pExcludeClipRect */ 846 NULL, /* pExtDeviceMode */ 847 NULL, /* pExtEscape */ 848 NULL, /* pExtFloodFill */ 849 NULL, /* pExtSelectClipRgn */ 850 emfpathdrv_ExtTextOut, /* pExtTextOut */ 851 NULL, /* pFillPath */ 852 NULL, /* pFillRgn */ 853 NULL, /* pFlattenPath */ 854 NULL, /* pFontIsLinked */ 855 NULL, /* pFrameRgn */ 856 NULL, /* pGdiComment */ 857 NULL, /* pGetBoundsRect */ 858 NULL, /* pGetCharABCWidths */ 859 NULL, /* pGetCharABCWidthsI */ 860 NULL, /* pGetCharWidth */ 861 NULL, /* pGetCharWidthInfo */ 862 #ifdef __REACTOS__ 863 EMFDRV_GetDeviceCaps, //// Work around HACK. 864 #else 865 NULL, /* pGetDeviceCaps */ 866 #endif 867 NULL, /* pGetDeviceGammaRamp */ 868 NULL, /* pGetFontData */ 869 NULL, /* pGetFontRealizationInfo */ 870 NULL, /* pGetFontUnicodeRanges */ 871 NULL, /* pGetGlyphIndices */ 872 NULL, /* pGetGlyphOutline */ 873 NULL, /* pGetICMProfile */ 874 NULL, /* pGetImage */ 875 NULL, /* pGetKerningPairs */ 876 NULL, /* pGetNearestColor */ 877 NULL, /* pGetOutlineTextMetrics */ 878 NULL, /* pGetPixel */ 879 NULL, /* pGetSystemPaletteEntries */ 880 NULL, /* pGetTextCharsetInfo */ 881 NULL, /* pGetTextExtentExPoint */ 882 NULL, /* pGetTextExtentExPointI */ 883 NULL, /* pGetTextFace */ 884 NULL, /* pGetTextMetrics */ 885 NULL, /* pGradientFill */ 886 NULL, /* pIntersectClipRect */ 887 NULL, /* pInvertRgn */ 888 emfpathdrv_LineTo, /* pLineTo */ 889 NULL, /* pModifyWorldTransform */ 890 emfpathdrv_MoveTo, /* pMoveTo */ 891 NULL, /* pOffsetClipRgn */ 892 NULL, /* pOffsetViewportOrg */ 893 NULL, /* pOffsetWindowOrg */ 894 NULL, /* pPaintRgn */ 895 NULL, /* pPatBlt */ 896 emfpathdrv_Pie, /* pPie */ 897 emfpathdrv_PolyBezier, /* pPolyBezier */ 898 emfpathdrv_PolyBezierTo, /* pPolyBezierTo */ 899 emfpathdrv_PolyDraw, /* pPolyDraw */ 900 emfpathdrv_PolyPolygon, /* pPolyPolygon */ 901 emfpathdrv_PolyPolyline, /* pPolyPolyline */ 902 emfpathdrv_Polygon, /* pPolygon */ 903 emfpathdrv_Polyline, /* pPolyline */ 904 emfpathdrv_PolylineTo, /* pPolylineTo */ 905 NULL, /* pPutImage */ 906 NULL, /* pRealizeDefaultPalette */ 907 NULL, /* pRealizePalette */ 908 emfpathdrv_Rectangle, /* pRectangle */ 909 NULL, /* pResetDC */ 910 NULL, /* pRestoreDC */ 911 emfpathdrv_RoundRect, /* pRoundRect */ 912 NULL, /* pSaveDC */ 913 NULL, /* pScaleViewportExt */ 914 NULL, /* pScaleWindowExt */ 915 NULL, /* pSelectBitmap */ 916 NULL, /* pSelectBrush */ 917 NULL, /* pSelectClipPath */ 918 NULL, /* pSelectFont */ 919 NULL, /* pSelectPalette */ 920 NULL, /* pSelectPen */ 921 NULL, /* pSetArcDirection */ 922 NULL, /* pSetBkColor */ 923 NULL, /* pSetBkMode */ 924 NULL, /* pSetDCBrushColor */ 925 NULL, /* pSetDCPenColor */ 926 NULL, /* pSetDIBColorTable */ 927 NULL, /* pSetDIBitsToDevice */ 928 NULL, /* pSetDeviceClipping */ 929 NULL, /* pSetDeviceGammaRamp */ 930 NULL, /* pSetLayout */ 931 NULL, /* pSetMapMode */ 932 NULL, /* pSetMapperFlags */ 933 NULL, /* pSetPixel */ 934 NULL, /* pSetPolyFillMode */ 935 NULL, /* pSetROP2 */ 936 NULL, /* pSetRelAbs */ 937 NULL, /* pSetStretchBltMode */ 938 NULL, /* pSetTextAlign */ 939 NULL, /* pSetTextCharacterExtra */ 940 NULL, /* pSetTextColor */ 941 NULL, /* pSetTextJustification */ 942 NULL, /* pSetViewportExt */ 943 NULL, /* pSetViewportOrg */ 944 NULL, /* pSetWindowExt */ 945 NULL, /* pSetWindowOrg */ 946 NULL, /* pSetWorldTransform */ 947 NULL, /* pStartDoc */ 948 NULL, /* pStartPage */ 949 NULL, /* pStretchBlt */ 950 NULL, /* pStretchDIBits */ 951 NULL, /* pStrokeAndFillPath */ 952 NULL, /* pStrokePath */ 953 NULL, /* pUnrealizePalette */ 954 NULL, /* pWidenPath */ 955 NULL, /* wine_get_wgl_driver */ 956 GDI_PRIORITY_PATH_DRV + 1 /* priority */ 957 }; 958