⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graphics.c

📁 Wine-20031016
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Enhanced MetaFile driver graphics functions * * Copyright 1999 Huw D M Davies * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "config.h"#include "wine/port.h"#include <stdlib.h>#include <string.h>#include "gdi.h"#include "enhmfdrv/enhmetafiledrv.h"#include "wine/debug.h"WINE_DEFAULT_DEBUG_CHANNEL(enhmetafile);/********************************************************************** *	     EMFDRV_MoveTo */BOOLEMFDRV_MoveTo(PHYSDEV dev, INT x, INT y){    EMRMOVETOEX emr;    emr.emr.iType = EMR_MOVETOEX;    emr.emr.nSize = sizeof(emr);    emr.ptl.x = x;    emr.ptl.y = y;    return EMFDRV_WriteRecord( dev, &emr.emr );}/*********************************************************************** *           EMFDRV_LineTo */BOOLEMFDRV_LineTo( PHYSDEV dev, INT x, INT y ){    EMRLINETO emr;    RECTL bounds;    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;    DC *dc = physDev->dc;    emr.emr.iType = EMR_LINETO;    emr.emr.nSize = sizeof(emr);    emr.ptl.x = x;    emr.ptl.y = y;    if(!EMFDRV_WriteRecord( dev, &emr.emr ))    	return FALSE;    bounds.left   = min(x, dc->CursPosX);    bounds.top    = min(y, dc->CursPosY);    bounds.right  = max(x, dc->CursPosX);    bounds.bottom = max(y, dc->CursPosY);    EMFDRV_UpdateBBox( dev, &bounds );    return TRUE;}/*********************************************************************** *           EMFDRV_ArcChordPie */static BOOLEMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,		    INT xstart, INT ystart, INT xend, INT yend, DWORD iType ){    INT temp, xCentre, yCentre, i;    double angleStart, angleEnd;    double xinterStart, yinterStart, xinterEnd, yinterEnd;    EMRARC emr;    RECTL bounds;    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;    DC *dc = physDev->dc;    if(left == right || top == bottom) return FALSE;    if(left > right) {temp = left; left = right; right = temp;}    if(top > bottom) {temp = top; top = bottom; bottom = temp;}    if(dc->GraphicsMode == GM_COMPATIBLE) {        right--;	bottom--;    }    emr.emr.iType     = iType;    emr.emr.nSize     = sizeof(emr);    emr.rclBox.left   = left;    emr.rclBox.top    = top;    emr.rclBox.right  = right;    emr.rclBox.bottom = bottom;    emr.ptlStart.x    = xstart;    emr.ptlStart.y    = ystart;    emr.ptlEnd.x      = xend;    emr.ptlEnd.x      = yend;    /* Now calculate the BBox */    xCentre = (left + right + 1) / 2;    yCentre = (top + bottom + 1) / 2;    xstart -= xCentre;    ystart -= yCentre;    xend   -= xCentre;    yend   -= yCentre;    /* invert y co-ords to get angle anti-clockwise from x-axis */    angleStart = atan2( -(double)ystart, (double)xstart);    angleEnd   = atan2( -(double)yend, (double)xend);    /* These are the intercepts of the start/end lines with the arc */    xinterStart = (right - left + 1)/2 * cos(angleStart) + xCentre;    yinterStart = -(bottom - top + 1)/2 * sin(angleStart) + yCentre;    xinterEnd   = (right - left + 1)/2 * cos(angleEnd) + xCentre;    yinterEnd   = -(bottom - top + 1)/2 * sin(angleEnd) + yCentre;    if(angleStart < 0) angleStart += 2 * M_PI;    if(angleEnd < 0) angleEnd += 2 * M_PI;    if(angleEnd < angleStart) angleEnd += 2 * M_PI;    bounds.left   = min(xinterStart, xinterEnd);    bounds.top    = min(yinterStart, yinterEnd);    bounds.right  = max(xinterStart, xinterEnd);    bounds.bottom = max(yinterStart, yinterEnd);    for(i = 0; i <= 8; i++) {        if(i * M_PI / 2 < angleStart) /* loop until we're past start */	    continue;	if(i * M_PI / 2 > angleEnd)   /* if we're past end we're finished */	    break;	/* the arc touches the rectangle at the start of quadrant i, so adjust	   BBox to reflect this. */	switch(i % 4) {	case 0:	    bounds.right = right;	    break;	case 1:	    bounds.top = top;	    break;	case 2:	    bounds.left = left;	    break;	case 3:	    bounds.bottom = bottom;	    break;	}    }    /* If we're drawing a pie then make sure we include the centre */    if(iType == EMR_PIE) {        if(bounds.left > xCentre) bounds.left = xCentre;	else if(bounds.right < xCentre) bounds.right = xCentre;	if(bounds.top > yCentre) bounds.top = yCentre;	else if(bounds.bottom < yCentre) bounds.right = yCentre;    }    if(!EMFDRV_WriteRecord( dev, &emr.emr ))        return FALSE;    EMFDRV_UpdateBBox( dev, &bounds );    return TRUE;}/*********************************************************************** *           EMFDRV_Arc */BOOLEMFDRV_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,	    INT xstart, INT ystart, INT xend, INT yend ){    return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,			       xend, yend, EMR_ARC );}/*********************************************************************** *           EMFDRV_Pie */BOOLEMFDRV_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,	    INT xstart, INT ystart, INT xend, INT yend ){    return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,			       xend, yend, EMR_PIE );}/*********************************************************************** *           EMFDRV_Chord */BOOLEMFDRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,             INT xstart, INT ystart, INT xend, INT yend ){    return EMFDRV_ArcChordPie( dev, left, top, right, bottom, xstart, ystart,			       xend, yend, EMR_CHORD );}/*********************************************************************** *           EMFDRV_Ellipse */BOOLEMFDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom ){    EMRELLIPSE emr;    INT temp;    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;    DC *dc = physDev->dc;    TRACE("%d,%d - %d,%d\n", left, top, right, bottom);    if(left == right || top == bottom) return FALSE;    if(left > right) {temp = left; left = right; right = temp;}    if(top > bottom) {temp = top; top = bottom; bottom = temp;}    if(dc->GraphicsMode == GM_COMPATIBLE) {        right--;	bottom--;    }    emr.emr.iType     = EMR_ELLIPSE;    emr.emr.nSize     = sizeof(emr);    emr.rclBox.left   = left;    emr.rclBox.top    = top;    emr.rclBox.right  = right;    emr.rclBox.bottom = bottom;    EMFDRV_UpdateBBox( dev, &emr.rclBox );    return EMFDRV_WriteRecord( dev, &emr.emr );}/*********************************************************************** *           EMFDRV_Rectangle */BOOLEMFDRV_Rectangle(PHYSDEV dev, INT left, INT top, INT right, INT bottom){    EMRRECTANGLE emr;    INT temp;    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;    DC *dc = physDev->dc;    TRACE("%d,%d - %d,%d\n", left, top, right, bottom);    if(left == right || top == bottom) return FALSE;    if(left > right) {temp = left; left = right; right = temp;}    if(top > bottom) {temp = top; top = bottom; bottom = temp;}    if(dc->GraphicsMode == GM_COMPATIBLE) {        right--;	bottom--;    }    emr.emr.iType     = EMR_RECTANGLE;    emr.emr.nSize     = sizeof(emr);    emr.rclBox.left   = left;    emr.rclBox.top    = top;    emr.rclBox.right  = right;    emr.rclBox.bottom = bottom;    EMFDRV_UpdateBBox( dev, &emr.rclBox );    return EMFDRV_WriteRecord( dev, &emr.emr );}/*********************************************************************** *           EMFDRV_RoundRect */BOOLEMFDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,		  INT bottom, INT ell_width, INT ell_height ){    EMRROUNDRECT emr;    INT temp;    EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;    DC *dc = physDev->dc;    if(left == right || top == bottom) return FALSE;    if(left > right) {temp = left; left = right; right = temp;}    if(top > bottom) {temp = top; top = bottom; bottom = temp;}    if(dc->GraphicsMode == GM_COMPATIBLE) {        right--;	bottom--;    }    emr.emr.iType     = EMR_ROUNDRECT;    emr.emr.nSize     = sizeof(emr);    emr.rclBox.left   = left;    emr.rclBox.top    = top;    emr.rclBox.right  = right;    emr.rclBox.bottom = bottom;    emr.szlCorner.cx  = ell_width;    emr.szlCorner.cy  = ell_height;    EMFDRV_UpdateBBox( dev, &emr.rclBox );    return EMFDRV_WriteRecord( dev, &emr.emr );}/*********************************************************************** *           EMFDRV_SetPixel */COLORREFEMFDRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color ){    EMRSETPIXELV emr;    emr.emr.iType  = EMR_SETPIXELV;    emr.emr.nSize  = sizeof(emr);    emr.ptlPixel.x = x;    emr.ptlPixel.y = y;    emr.crColor = color;    if (EMFDRV_WriteRecord( dev, &emr.emr )) {        RECTL bounds;        bounds.left = bounds.right = x;        bounds.top = bounds.bottom = y;        EMFDRV_UpdateBBox( dev, &bounds );        return color;    }    return -1;}/********************************************************************** *          EMFDRV_Polylinegon * * Helper for EMFDRV_Poly{line|gon} */static BOOLEMFDRV_Polylinegon( PHYSDEV dev, const POINT* pt, INT count, DWORD iType ){    EMRPOLYLINE *emr;    DWORD size;    INT i;    BOOL ret;    size = sizeof(EMRPOLYLINE) + sizeof(POINTL) * (count - 1);    emr = HeapAlloc( GetProcessHeap(), 0, size );    emr->emr.iType = iType;    emr->emr.nSize = size;    emr->rclBounds.left = emr->rclBounds.right = pt[0].x;    emr->rclBounds.top = emr->rclBounds.bottom = pt[0].y;    for(i = 1; i < count; i++) {        if(pt[i].x < emr->rclBounds.left)	    emr->rclBounds.left = pt[i].x;	else if(pt[i].x > emr->rclBounds.right)	    emr->rclBounds.right = pt[i].x;	if(pt[i].y < emr->rclBounds.top)	    emr->rclBounds.top = pt[i].y;	else if(pt[i].y > emr->rclBounds.bottom)	    emr->rclBounds.bottom = pt[i].y;    }    emr->cptl = count;    memcpy(emr->aptl, pt, count * sizeof(POINTL));    ret = EMFDRV_WriteRecord( dev, &emr->emr );    if(ret)        EMFDRV_UpdateBBox( dev, &emr->rclBounds );    HeapFree( GetProcessHeap(), 0, emr );    return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -