示例#1
0
文件: graphics.c 项目: zapot/vinassa
/***********************************************************************
 *           PSDRV_Ellipse
 */
BOOL PSDRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom)
{
    INT x, y, w, h;
    RECT rect;

    TRACE("%d %d - %d %d\n", left, top, right, bottom);

    rect.left   = left;
    rect.top    = top;
    rect.right  = right;
    rect.bottom = bottom;
    LPtoDP( dev->hdc, (POINT *)&rect, 2 );

    x = (rect.left + rect.right) / 2;
    y = (rect.top + rect.bottom) / 2;
    w = rect.right - rect.left;
    h = rect.bottom - rect.top;

    PSDRV_WriteSpool(dev, "%Ellipse\n", 9);
    PSDRV_SetPen(dev);

    PSDRV_SetClip(dev);
    PSDRV_WriteNewPath(dev);
    PSDRV_WriteArc(dev, x, y, w, h, 0.0, 360.0);
    PSDRV_WriteClosePath(dev);
    PSDRV_Brush(dev,0);
    PSDRV_DrawLine(dev);
    PSDRV_ResetClip(dev);
    return TRUE;
}
示例#2
0
文件: graphics.c 项目: Sunmonds/wine
static BOOL paint_path( PHYSDEV dev, BOOL stroke, BOOL fill )
{
    POINT *points;
    BYTE *types;
    BOOL ret = FALSE;
    int i, size = GetPath( dev->hdc, NULL, NULL, 0 );

    if (size == -1) return FALSE;
    if (!size) return TRUE;
    points = HeapAlloc( GetProcessHeap(), 0, size * sizeof(*points) );
    types = HeapAlloc( GetProcessHeap(), 0, size * sizeof(*types) );
    if (!points || !types) goto done;
    if (GetPath( dev->hdc, points, types, size ) == -1) goto done;

    if (stroke) PSDRV_SetPen(dev);
    PSDRV_SetClip(dev);
    for (i = 0; i < size; i++)
    {
        switch (types[i])
        {
        case PT_MOVETO:
            PSDRV_WriteMoveTo( dev, points[i].x, points[i].y );
            break;
        case PT_LINETO:
        case PT_LINETO | PT_CLOSEFIGURE:
            PSDRV_WriteLineTo( dev, points[i].x, points[i].y );
            if (types[i] & PT_CLOSEFIGURE) PSDRV_WriteClosePath( dev );
            break;
        case PT_BEZIERTO:
        case PT_BEZIERTO | PT_CLOSEFIGURE:
            PSDRV_WriteCurveTo( dev, points + i );
            if (types[i] & PT_CLOSEFIGURE) PSDRV_WriteClosePath( dev );
            i += 2;
            break;
        }
    }
    if (fill) PSDRV_Brush( dev, GetPolyFillMode(dev->hdc) == ALTERNATE );
    if (stroke) PSDRV_DrawLine(dev);
    else PSDRV_WriteNewPath(dev);
    PSDRV_ResetClip(dev);

done:
    HeapFree( GetProcessHeap(), 0, points );
    HeapFree( GetProcessHeap(), 0, types );
    return ret;
}
示例#3
0
文件: graphics.c 项目: zapot/vinassa
/***********************************************************************
 *           PSDRV_DrawArc
 *
 * Does the work of Arc, Chord and Pie. lines is 0, 1 or 2 respectively.
 */
static BOOL PSDRV_DrawArc( PHYSDEV dev, INT left, INT top,
                           INT right, INT bottom, INT xstart, INT ystart,
                           INT xend, INT yend, int lines )
{
    INT x, y, h, w;
    double start_angle, end_angle, ratio;
    RECT rect;
    POINT start, end;

    rect.left = left;
    rect.top = top;
    rect.right = right;
    rect.bottom = bottom;
    LPtoDP( dev->hdc, (POINT *)&rect, 2 );
    start.x = xstart;
    start.y = ystart;
    end.x = xend;
    end.y = yend;
    LPtoDP( dev->hdc, &start, 1 );
    LPtoDP( dev->hdc, &end, 1 );

    x = (rect.left + rect.right) / 2;
    y = (rect.top + rect.bottom) / 2;
    w = rect.right - rect.left;
    h = rect.bottom - rect.top;

    if(w < 0) w = -w;
    if(h < 0) h = -h;
    ratio = ((double)w)/h;

    /* angle is the angle after the rectangle is transformed to a square and is
       measured anticlockwise from the +ve x-axis */

    start_angle = atan2((double)(y - start.y) * ratio, (double)(start.x - x));
    end_angle = atan2((double)(y - end.y) * ratio, (double)(end.x - x));

    start_angle *= 180.0 / PI;
    end_angle *= 180.0 / PI;

    PSDRV_WriteSpool(dev,"%DrawArc\n", 9);
    PSDRV_SetPen(dev);

    PSDRV_SetClip(dev);
    if(lines == 2) /* pie */
        PSDRV_WriteMoveTo(dev, x, y);
    else
        PSDRV_WriteNewPath( dev );

    PSDRV_WriteArc(dev, x, y, w, h, start_angle, end_angle);
    if(lines == 1 || lines == 2) { /* chord or pie */
        PSDRV_WriteClosePath(dev);
	PSDRV_Brush(dev,0);
    }
    PSDRV_DrawLine(dev);
    PSDRV_ResetClip(dev);

    return TRUE;
}
示例#4
0
文件: graphics.c 项目: zapot/vinassa
/***********************************************************************
 *           PSDRV_RoundRect
 */
BOOL PSDRV_RoundRect( PHYSDEV dev, INT left, INT top, INT right,
                      INT bottom, INT ell_width, INT ell_height )
{
    RECT rect[2];

    rect[0].left   = left;
    rect[0].top    = top;
    rect[0].right  = right;
    rect[0].bottom = bottom;
    rect[1].left   = 0;
    rect[1].top    = 0;
    rect[1].right  = ell_width;
    rect[1].bottom = ell_height;
    LPtoDP( dev->hdc, (POINT *)rect, 4 );

    left   = rect[0].left;
    top    = rect[0].top;
    right  = rect[0].right;
    bottom = rect[0].bottom;
    if (left > right) { INT tmp = left; left = right; right = tmp; }
    if (top > bottom) { INT tmp = top; top = bottom; bottom = tmp; }

    ell_width  = rect[1].right - rect[1].left;
    ell_height = rect[1].bottom - rect[1].top;
    if (ell_width > right - left) ell_width = right - left;
    if (ell_height > bottom - top) ell_height = bottom - top;

    PSDRV_WriteSpool(dev, "%RoundRect\n",11);
    PSDRV_SetPen(dev);

    PSDRV_SetClip(dev);
    PSDRV_WriteMoveTo( dev, left, top + ell_height/2 );
    PSDRV_WriteArc( dev, left + ell_width/2, top + ell_height/2, ell_width,
		    ell_height, 90.0, 180.0);
    PSDRV_WriteLineTo( dev, right - ell_width/2, top );
    PSDRV_WriteArc( dev, right - ell_width/2, top + ell_height/2, ell_width,
		    ell_height, 0.0, 90.0);
    PSDRV_WriteLineTo( dev, right, bottom - ell_height/2 );
    PSDRV_WriteArc( dev, right - ell_width/2, bottom - ell_height/2, ell_width,
		    ell_height, -90.0, 0.0);
    PSDRV_WriteLineTo( dev, right - ell_width/2, bottom);
    PSDRV_WriteArc( dev, left + ell_width/2, bottom - ell_height/2, ell_width,
		    ell_height, 180.0, -90.0);
    PSDRV_WriteClosePath( dev );

    PSDRV_Brush(dev,0);
    PSDRV_DrawLine(dev);
    PSDRV_ResetClip(dev);
    return TRUE;
}
示例#5
0
文件: graphics.c 项目: zapot/vinassa
/***********************************************************************
 *           PSDRV_PolyPolygon
 */
BOOL PSDRV_PolyPolygon( PHYSDEV dev, const POINT* pts, const INT* counts, UINT polygons )
{
    DWORD polygon, total;
    INT line;
    POINT *dev_pts, *pt;

    TRACE("\n");

    for (polygon = total = 0; polygon < polygons; polygon++) total += counts[polygon];
    if (!(dev_pts = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*dev_pts) ))) return FALSE;
    memcpy( dev_pts, pts, total * sizeof(*dev_pts) );
    LPtoDP( dev->hdc, dev_pts, total );

    pt = dev_pts;

    PSDRV_WriteSpool(dev, "%PolyPolygon\n",13);
    PSDRV_SetPen(dev);
    PSDRV_SetClip(dev);

    for(polygon = 0; polygon < polygons; polygon++) {
        PSDRV_WriteMoveTo(dev, pt->x, pt->y);
	pt++;
        for(line = 1; line < counts[polygon]; line++, pt++)
            PSDRV_WriteLineTo(dev, pt->x, pt->y);
	PSDRV_WriteClosePath(dev);
    }
    HeapFree( GetProcessHeap(), 0, dev_pts );

    if(GetPolyFillMode( dev->hdc ) == ALTERNATE)
        PSDRV_Brush(dev, 1);
    else /* WINDING */
        PSDRV_Brush(dev, 0);

    PSDRV_DrawLine(dev);
    PSDRV_ResetClip(dev);
    return TRUE;
}
示例#6
0
文件: escape.c 项目: howard5888/wineT
/**********************************************************************
 *           ExtEscape  (WINEPS.@)
 */
INT PSDRV_ExtEscape( PSDRV_PDEVICE *physDev, INT nEscape, INT cbInput, LPCVOID in_data,
                     INT cbOutput, LPVOID out_data )
{
    switch(nEscape)
    {
    case QUERYESCSUPPORT:
        if(cbInput < sizeof(INT))
        {
	    WARN("cbInput < sizeof(INT) (=%d) for QUERYESCSUPPORT\n", cbInput);
	    return 0;
	} else {
	    UINT num = *(const UINT *)in_data;
	    TRACE("QUERYESCSUPPORT for %d\n", num);

	    switch(num) {
	    case NEXTBAND:
	    /*case BANDINFO:*/
	    case SETCOPYCOUNT:
	    case GETTECHNOLOGY:
	    case SETLINECAP:
	    case SETLINEJOIN:
	    case SETMITERLIMIT:
	    case SETCHARSET:
	    case EXT_DEVICE_CAPS:
	    case SET_BOUNDS:
            case EPSPRINTING:
	    case POSTSCRIPT_DATA:
            case PASSTHROUGH:
            case POSTSCRIPT_PASSTHROUGH:
	    case POSTSCRIPT_IGNORE:
	    case BEGIN_PATH:
	    case CLIP_TO_PATH:
	    case END_PATH:
	    /*case DRAWPATTERNRECT:*/
	        return TRUE;

	    default:
		FIXME("QUERYESCSUPPORT(%d) - not supported.\n", num);
	        return FALSE;
	    }
	}

    case MFCOMMENT:
    {
	FIXME("MFCOMMENT(%p, %d)\n", in_data, cbInput);
	return 1;
    }
    case DRAWPATTERNRECT:
    {
	DRAWPATRECT	*dpr = (DRAWPATRECT*)in_data;

	FIXME("DRAWPATTERNRECT(pos (%ld,%ld), size %ldx%ld, style %d, pattern %x), stub!\n",
		dpr->ptPosition.x, dpr->ptPosition.y,
		dpr->ptSize.x, dpr->ptSize.y,
		dpr->wStyle, dpr->wPattern
	);
	return 1;
    }
    case BANDINFO:
    {
	BANDINFOSTRUCT	*ibi = (BANDINFOSTRUCT*)in_data;
	BANDINFOSTRUCT	*obi = (BANDINFOSTRUCT*)out_data;

	FIXME("BANDINFO(graphics %d, text %d, rect [%ldx%ld-%ldx%ld]), stub!\n",
		ibi->GraphicsFlag,
		ibi->TextFlag,
		ibi->GraphicsRect.top,
		ibi->GraphicsRect.bottom,
		ibi->GraphicsRect.left,
		ibi->GraphicsRect.right
	);
	memcpy (obi, ibi, sizeof(*ibi));
	return 1;
    }
    case NEXTBAND:
    {
        RECT *r = out_data;
	if(!physDev->job.banding) {
	    physDev->job.banding = TRUE;
            r->left   = 0;
            r->top    = 0;
            r->right  = physDev->horzRes;
            r->bottom = physDev->vertRes;
            TRACE("NEXTBAND returning %ld,%ld - %ld,%ld\n", r->left, r->top, r->right, r->bottom );
	    return 1;
	}
        r->left   = 0;
        r->top    = 0;
        r->right  = 0;
        r->bottom = 0;
	TRACE("NEXTBAND rect to 0,0 - 0,0\n" );
	physDev->job.banding = FALSE;
        return EndPage( physDev->hdc );
    }

    case SETCOPYCOUNT:
        {
            const INT *NumCopies = in_data;
            INT *ActualCopies = out_data;
            if(cbInput != sizeof(INT)) {
                WARN("cbInput != sizeof(INT) (=%d) for SETCOPYCOUNT\n", cbInput);
		return 0;
	    }
	    TRACE("SETCOPYCOUNT %d\n", *NumCopies);
	    *ActualCopies = 1;
	    return 1;
	}

    case GETTECHNOLOGY:
        {
	    LPSTR p = out_data;
	    strcpy(p, "PostScript");
	    *(p + strlen(p) + 1) = '\0'; /* 2 '\0's at end of string */
	    return 1;
	}

    case SETLINECAP:
        {
            INT newCap = *(const INT *)in_data;
            if(cbInput != sizeof(INT)) {
                WARN("cbInput != sizeof(INT) (=%d) for SETLINECAP\n", cbInput);
		return 0;
            }
	    TRACE("SETLINECAP %d\n", newCap);
	    return 0;
	}

    case SETLINEJOIN:
        {
            INT newJoin = *(const INT *)in_data;
            if(cbInput != sizeof(INT)) {
                WARN("cbInput != sizeof(INT) (=%d) for SETLINEJOIN\n", cbInput);
		return 0;
            }
	    TRACE("SETLINEJOIN %d\n", newJoin);
	    return 0;
	}

    case SETMITERLIMIT:
        {
            INT newLimit = *(const INT *)in_data;
            if(cbInput != sizeof(INT)) {
                WARN("cbInput != sizeof(INT) (=%d) for SETMITERLIMIT\n", cbInput);
		return 0;
            }
	    TRACE("SETMITERLIMIT %d\n", newLimit);
	    return 0;
	}

    case SETCHARSET:
      /* Undocumented escape used by winword6.
	 Switches between ANSI and a special charset.
	 If *lpInData == 1 we require that
	 0x91 is quoteleft
	 0x92 is quoteright
	 0x93 is quotedblleft
	 0x94 is quotedblright
	 0x95 is bullet
	 0x96 is endash
	 0x97 is emdash
	 0xa0 is non break space - yeah right.

	 If *lpInData == 0 we get ANSI.
	 Since there's nothing else there, let's just make these the default
	 anyway and see what happens...
      */
        return 1;

    case EXT_DEVICE_CAPS:
        {
            UINT cap = *(const UINT *)in_data;
            if(cbInput != sizeof(UINT)) {
                WARN("cbInput != sizeof(UINT) (=%d) for EXT_DEVICE_CAPS\n", cbInput);
		return 0;
            }
	    TRACE("EXT_DEVICE_CAPS %d\n", cap);
	    return 0;
	}

    case SET_BOUNDS:
        {
            const RECT *r = in_data;
            if(cbInput != sizeof(RECT)) {
                WARN("cbInput != sizeof(RECT) (=%d) for SET_BOUNDS\n", cbInput);
		return 0;
            }
	    TRACE("SET_BOUNDS (%ld,%ld) - (%ld,%ld)\n", r->left, r->top,
		  r->right, r->bottom);
	    return 0;
	}

    case EPSPRINTING:
	{
            UINT epsprint = *(const UINT*)in_data;
	    /* FIXME: In this mode we do not need to send page intros and page
	     * ends according to the doc. But I just ignore that detail
	     * for now.
	     */
	    TRACE("EPS Printing support %sable.\n",epsprint?"en":"dis");
	    return 1;
        }

    case POSTSCRIPT_DATA:
    case PASSTHROUGH:
    case POSTSCRIPT_PASSTHROUGH:
        {
            /* Write directly to spool file, bypassing normal PS driver
             * processing that is done along with writing PostScript code
             * to the spool.
	     * We have a WORD before the data counting the size, but
	     * cbInput is just this +2.
             * However Photoshop 7 has a bug that sets cbInput to 2 less than the
             * length of the string, rather than 2 more.  So we'll use the WORD at
             * in_data[0] instead.
             */
            if(!physDev->job.in_passthrough) {
                WriteSpool16(physDev->job.hJob, (LPSTR)psbegindocument, sizeof(psbegindocument)-1);
                physDev->job.in_passthrough = TRUE;
            }
            return WriteSpool16(physDev->job.hJob,((char*)in_data)+2,*(const WORD*)in_data);
        }

    case POSTSCRIPT_IGNORE:
      {
	BOOL ret = physDev->job.quiet;
        TRACE("POSTSCRIPT_IGNORE %d\n", *(const short*)in_data);
	physDev->job.quiet = *(const short*)in_data;
	return ret;
      }

    case GETSETPRINTORIENT:
	{
	    /* If lpInData is present, it is a 20 byte structure, first 32
	     * bit LONG value is the orientation. if lpInData is NULL, it
	     * returns the current orientation.
	     */
	    FIXME("GETSETPRINTORIENT not implemented (data %p)!\n",in_data);
	    return 1;
	}
    case BEGIN_PATH:
        TRACE("BEGIN_PATH\n");
	if(physDev->pathdepth)
	    FIXME("Nested paths not yet handled\n");
	return ++physDev->pathdepth;

    case END_PATH:
      {
	const struct PATH_INFO *info = (const struct PATH_INFO*)in_data;

	TRACE("END_PATH\n");
        if(!physDev->pathdepth) {
	    ERR("END_PATH called without a BEIGN_PATH\n");
	    return -1;
	}
	TRACE("RenderMode = %d, FillMode = %d, BkMode = %d\n",
	      info->RenderMode, info->FillMode, info->BkMode);
	switch(info->RenderMode) {
	case RENDERMODE_NO_DISPLAY:
	    PSDRV_WriteClosePath(physDev); /* not sure if this is necessary, but it can't hurt */
	    break;
	case RENDERMODE_OPEN:
	case RENDERMODE_CLOSED:
	default:
	    FIXME("END_PATH: RenderMode %d, not yet supported\n", info->RenderMode);
	    break;
	}
	return --physDev->pathdepth;
      }

    case CLIP_TO_PATH:
      {
	WORD mode = *(const WORD*)in_data;

	switch(mode) {
	case CLIP_SAVE:
	    TRACE("CLIP_TO_PATH: CLIP_SAVE\n");
	    PSDRV_WriteGSave(physDev);
	    return 1;
	case CLIP_RESTORE:
	    TRACE("CLIP_TO_PATH: CLIP_RESTORE\n");
	    PSDRV_WriteGRestore(physDev);
	    return 1;
	case CLIP_INCLUSIVE:
	    TRACE("CLIP_TO_PATH: CLIP_INCLUSIVE\n");
	    /* FIXME to clip or eoclip ? (see PATH_INFO.FillMode) */
	    PSDRV_WriteClip(physDev);
            PSDRV_WriteNewPath(physDev);
	    return 1;
	case CLIP_EXCLUSIVE:
	    FIXME("CLIP_EXCLUSIVE: not implemented\n");
	    return 0;
	default:
	    FIXME("Unknown CLIP_TO_PATH mode %d\n", mode);
	    return 0;
	}
      }
    default:
        FIXME("Unimplemented code 0x%x\n", nEscape);
	return 0;
    }
}