📄 graphics.c
字号:
/********************************************************************** * EMFDRV_Polyline */BOOLEMFDRV_Polyline( PHYSDEV dev, const POINT* pt, INT count ){ return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYLINE );}/********************************************************************** * EMFDRV_Polygon */BOOLEMFDRV_Polygon( PHYSDEV dev, const POINT* pt, INT count ){ if(count < 2) return FALSE; return EMFDRV_Polylinegon( dev, pt, count, EMR_POLYGON );}/********************************************************************** * EMFDRV_PolyPolylinegon * * Helper for EMFDRV_PolyPoly{line|gon} */static BOOLEMFDRV_PolyPolylinegon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys, DWORD iType){ EMRPOLYPOLYLINE *emr; DWORD cptl = 0, poly, size, point; RECTL bounds; const POINT *pts; BOOL ret; bounds.left = bounds.right = pt[0].x; bounds.top = bounds.bottom = pt[0].y; pts = pt; for(poly = 0; poly < polys; poly++) { cptl += counts[poly]; for(point = 0; point < counts[poly]; point++) { if(bounds.left > pts->x) bounds.left = pts->x; else if(bounds.right < pts->x) bounds.right = pts->x; if(bounds.top > pts->y) bounds.top = pts->y; else if(bounds.bottom < pts->y) bounds.bottom = pts->y; pts++; } } size = sizeof(EMRPOLYPOLYLINE) + (polys - 1) * sizeof(DWORD) + (cptl - 1) * sizeof(POINTL); emr = HeapAlloc( GetProcessHeap(), 0, size ); emr->emr.iType = iType; emr->emr.nSize = size; emr->rclBounds = bounds; emr->nPolys = polys; emr->cptl = cptl; memcpy(emr->aPolyCounts, counts, polys * sizeof(DWORD)); memcpy(emr->aPolyCounts + polys, pt, cptl * sizeof(POINTL)); ret = EMFDRV_WriteRecord( dev, &emr->emr ); if(ret) EMFDRV_UpdateBBox( dev, &emr->rclBounds ); HeapFree( GetProcessHeap(), 0, emr ); return ret;}/********************************************************************** * EMFDRV_PolyPolyline */BOOLEMFDRV_PolyPolyline(PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polys){ return EMFDRV_PolyPolylinegon( dev, pt, (INT *)counts, polys, EMR_POLYPOLYLINE );}/********************************************************************** * EMFDRV_PolyPolygon */BOOLEMFDRV_PolyPolygon( PHYSDEV dev, const POINT* pt, const INT* counts, UINT polys ){ return EMFDRV_PolyPolylinegon( dev, pt, counts, polys, EMR_POLYPOLYGON );}/********************************************************************** * EMFDRV_ExtFloodFill */BOOLEMFDRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType ){ EMREXTFLOODFILL emr; emr.emr.iType = EMR_EXTFLOODFILL; emr.emr.nSize = sizeof(emr); emr.ptlStart.x = x; emr.ptlStart.y = y; emr.crColor = color; emr.iMode = fillType; return EMFDRV_WriteRecord( dev, &emr.emr );}/********************************************************************* * EMFDRV_FillRgn */BOOL EMFDRV_FillRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush ){ EMRFILLRGN *emr; DWORD size, rgnsize, index; BOOL ret; index = EMFDRV_CreateBrushIndirect( dev, hbrush ); if(!index) return FALSE; rgnsize = GetRegionData( hrgn, 0, NULL ); size = rgnsize + offsetof(EMRFILLRGN,RgnData); emr = HeapAlloc( GetProcessHeap(), 0, size ); GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData ); emr->emr.iType = EMR_FILLRGN; emr->emr.nSize = size; emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left; emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top; emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1; emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1; emr->cbRgnData = rgnsize; emr->ihBrush = index; ret = EMFDRV_WriteRecord( dev, &emr->emr ); if(ret) EMFDRV_UpdateBBox( dev, &emr->rclBounds ); HeapFree( GetProcessHeap(), 0, emr ); return ret;}/********************************************************************* * EMFDRV_FrameRgn */BOOL EMFDRV_FrameRgn( PHYSDEV dev, HRGN hrgn, HBRUSH hbrush, INT width, INT height ){ EMRFRAMERGN *emr; DWORD size, rgnsize, index; BOOL ret; index = EMFDRV_CreateBrushIndirect( dev, hbrush ); if(!index) return FALSE; rgnsize = GetRegionData( hrgn, 0, NULL ); size = rgnsize + offsetof(EMRFRAMERGN,RgnData); emr = HeapAlloc( GetProcessHeap(), 0, size ); GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData ); emr->emr.iType = EMR_FRAMERGN; emr->emr.nSize = size; emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left; emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top; emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1; emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1; emr->cbRgnData = rgnsize; emr->ihBrush = index; emr->szlStroke.cx = width; emr->szlStroke.cy = height; ret = EMFDRV_WriteRecord( dev, &emr->emr ); if(ret) EMFDRV_UpdateBBox( dev, &emr->rclBounds ); HeapFree( GetProcessHeap(), 0, emr ); return ret;}/********************************************************************* * EMFDRV_PaintInvertRgn * * Helper for EMFDRV_{Paint|Invert}Rgn */static BOOL EMFDRV_PaintInvertRgn( PHYSDEV dev, HRGN hrgn, DWORD iType ){ EMRINVERTRGN *emr; DWORD size, rgnsize; BOOL ret; rgnsize = GetRegionData( hrgn, 0, NULL ); size = rgnsize + offsetof(EMRINVERTRGN,RgnData); emr = HeapAlloc( GetProcessHeap(), 0, size ); GetRegionData( hrgn, rgnsize, (RGNDATA *)&emr->RgnData ); emr->emr.iType = iType; emr->emr.nSize = size; emr->rclBounds.left = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.left; emr->rclBounds.top = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.top; emr->rclBounds.right = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.right - 1; emr->rclBounds.bottom = ((RGNDATA *)&emr->RgnData)->rdh.rcBound.bottom - 1; emr->cbRgnData = rgnsize; ret = EMFDRV_WriteRecord( dev, &emr->emr ); if(ret) EMFDRV_UpdateBBox( dev, &emr->rclBounds ); HeapFree( GetProcessHeap(), 0, emr ); return ret;}/********************************************************************** * EMFDRV_PaintRgn */BOOLEMFDRV_PaintRgn( PHYSDEV dev, HRGN hrgn ){ return EMFDRV_PaintInvertRgn( dev, hrgn, EMR_PAINTRGN );}/********************************************************************** * EMFDRV_InvertRgn */BOOLEMFDRV_InvertRgn( PHYSDEV dev, HRGN hrgn ){ return EMFDRV_PaintInvertRgn( dev, hrgn, EMR_INVERTRGN );}/********************************************************************** * EMFDRV_SetBkColor */COLORREFEMFDRV_SetBkColor( PHYSDEV dev, COLORREF color ){ EMRSETBKCOLOR emr; emr.emr.iType = EMR_SETBKCOLOR; emr.emr.nSize = sizeof(emr); emr.crColor = color; return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;}/********************************************************************** * EMFDRV_SetTextColor */COLORREFEMFDRV_SetTextColor( PHYSDEV dev, COLORREF color ){ EMRSETTEXTCOLOR emr; emr.emr.iType = EMR_SETTEXTCOLOR; emr.emr.nSize = sizeof(emr); emr.crColor = color; return EMFDRV_WriteRecord( dev, &emr.emr ) ? color : CLR_INVALID;}/********************************************************************** * EMFDRV_ExtTextOut */BOOL EMFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx ){ EMREXTTEXTOUTW *pemr; DWORD nSize; BOOL ret; EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE*) dev; int textHeight = 0; int textWidth = 0; const UINT textAlign = GetTextAlign(physDev->hdc); nSize = sizeof(*pemr) + ((count+1) & ~1) * sizeof(WCHAR) + count * sizeof(INT); TRACE("%s count %d nSize = %ld\n", debugstr_wn(str, count), count, nSize); pemr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nSize); pemr->emr.iType = EMR_EXTTEXTOUTW; pemr->emr.nSize = nSize; pemr->iGraphicsMode = GetGraphicsMode(physDev->hdc); pemr->exScale = pemr->eyScale = 1.0; /* FIXME */ pemr->emrtext.ptlReference.x = x; pemr->emrtext.ptlReference.y = y; pemr->emrtext.nChars = count; pemr->emrtext.offString = sizeof(*pemr); memcpy((char*)pemr + pemr->emrtext.offString, str, count * sizeof(WCHAR)); pemr->emrtext.fOptions = flags; if(!lprect) { pemr->emrtext.rcl.left = pemr->emrtext.rcl.top = 0; pemr->emrtext.rcl.right = pemr->emrtext.rcl.bottom = -1; } else { pemr->emrtext.rcl.left = lprect->left; pemr->emrtext.rcl.top = lprect->top; pemr->emrtext.rcl.right = lprect->right; pemr->emrtext.rcl.bottom = lprect->bottom; } pemr->emrtext.offDx = pemr->emrtext.offString + ((count+1) & ~1) * sizeof(WCHAR); if(lpDx) { UINT i; SIZE strSize; memcpy((char*)pemr + pemr->emrtext.offDx, lpDx, count * sizeof(INT)); for (i = 0; i < count; i++) { textWidth += lpDx[i]; } GetTextExtentPoint32W(physDev->hdc, str, count, &strSize); textHeight = strSize.cy; } else { UINT i; INT *dx = (INT *)((char*)pemr + pemr->emrtext.offDx); SIZE charSize; for (i = 0; i < count; i++) { GetTextExtentPoint32W(physDev->hdc, str + i, 1, &charSize); dx[i] = charSize.cx; textWidth += charSize.cx; textHeight = max(textHeight, charSize.cy); } } switch (textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER)) { case TA_CENTER: { pemr->rclBounds.left = x - (textWidth / 2) - 1; pemr->rclBounds.right = x + (textWidth / 2) + 1; break; } case TA_RIGHT: { pemr->rclBounds.left = x - textWidth - 1; pemr->rclBounds.right = x; break; } default: { /* TA_LEFT */ pemr->rclBounds.left = x; pemr->rclBounds.right = x + textWidth + 1; } } switch (textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE)) { case TA_BASELINE: { TEXTMETRICW tm; GetTextMetricsW(physDev->hdc, &tm); /* Play safe here... it's better to have a bounding box */ /* that is too big than too small. */ pemr->rclBounds.top = y - textHeight - 1; pemr->rclBounds.bottom = y + tm.tmDescent + 1; break; } case TA_BOTTOM: { pemr->rclBounds.top = y - textHeight - 1; pemr->rclBounds.bottom = y; break; } default: { /* TA_TOP */ pemr->rclBounds.top = y; pemr->rclBounds.bottom = y + textHeight + 1; } } ret = EMFDRV_WriteRecord( dev, &pemr->emr ); if(ret) EMFDRV_UpdateBBox( dev, &pemr->rclBounds ); HeapFree( GetProcessHeap(), 0, pemr ); return ret;}/********************************************************************** * EMFDRV_SetArcDirection */INT EMFDRV_SetArcDirection(PHYSDEV dev, INT arcDirection){ EMRSETARCDIRECTION emr; emr.emr.iType = EMR_SETARCDIRECTION; emr.emr.nSize = sizeof(emr); emr.iArcDirection = arcDirection; EMFDRV_WriteRecord(dev, &emr.emr); /* We don't know the old arc direction and we don't care... */ return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -