Example #1
0
static BOOL PSDRV_WriteImageMaskHeader(PHYSDEV dev, const BITMAPINFO *info, INT xDst,
                                       INT yDst, INT widthDst, INT heightDst,
                                       INT widthSrc, INT heightSrc)
{
    PSCOLOR bkgnd, foregnd;

    assert(info->bmiHeader.biBitCount == 1);

    /* We'll write the mask with -ve polarity so that 
       the foregnd color corresponds to a bit equal to
       0 in the bitmap.
    */
    PSDRV_CreateColor(dev, &foregnd, RGB(info->bmiColors[0].rgbRed,
                                         info->bmiColors[0].rgbGreen,
                                         info->bmiColors[0].rgbBlue) );
    PSDRV_CreateColor(dev, &bkgnd, RGB(info->bmiColors[1].rgbRed,
                                       info->bmiColors[1].rgbGreen,
                                       info->bmiColors[1].rgbBlue) );

    PSDRV_WriteGSave(dev);
    PSDRV_WriteNewPath(dev);
    PSDRV_WriteRectangle(dev, xDst, yDst, widthDst, heightDst);
    PSDRV_WriteSetColor(dev, &bkgnd);
    PSDRV_WriteFill(dev);
    PSDRV_WriteGRestore(dev);

    PSDRV_WriteSetColor(dev, &foregnd);
    PSDRV_WriteImage(dev, 1, xDst, yDst, widthDst, heightDst,
		     widthSrc, heightSrc, TRUE, info->bmiHeader.biHeight < 0);

    return TRUE;
}
Example #2
0
/***********************************************************************
 *           PSDRV_PaintRgn
 */
BOOL PSDRV_PaintRgn( PHYSDEV dev, HRGN hrgn )
{
    RGNDATA *rgndata = NULL;
    RECT *pRect;
    DWORD size, i;

    TRACE("hdc=%p\n", dev->hdc);

    size = GetRegionData(hrgn, 0, NULL);
    rgndata = HeapAlloc( GetProcessHeap(), 0, size );
    if(!rgndata) {
        ERR("Can't allocate buffer\n");
        return FALSE;
    }
    
    GetRegionData(hrgn, size, rgndata);
    if (rgndata->rdh.nCount == 0)
        goto end;

    LPtoDP(dev->hdc, (POINT*)rgndata->Buffer, rgndata->rdh.nCount * 2);

    PSDRV_SetClip(dev);
    for(i = 0, pRect = (RECT*)rgndata->Buffer; i < rgndata->rdh.nCount; i++, pRect++)
        PSDRV_WriteRectangle(dev, pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top);

    PSDRV_Brush(dev, 0);
    PSDRV_WriteNewPath(dev);
    PSDRV_ResetClip(dev);

 end:
    HeapFree(GetProcessHeap(), 0, rgndata);
    return TRUE;
}
Example #3
0
/***********************************************************************
 *           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;
}
Example #4
0
/***********************************************************************
 *           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;
}
Example #5
0
/***********************************************************************
 *           PSDRV_DrawLine
 */
static void PSDRV_DrawLine( PHYSDEV dev )
{
    PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );

    if(physDev->pathdepth)
        return;

    if (physDev->pen.style == PS_NULL)
	PSDRV_WriteNewPath(dev);
    else
	PSDRV_WriteStroke(dev);
}
Example #6
0
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;
}
Example #7
0
/**********************************************************************
 *           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;
    }
}