예제 #1
0
파일: init.c 프로젝트: Barrell/wine
/**********************************************************************
 *          CreateEnhMetaFileA   (GDI32.@)
 */
HDC WINAPI CreateEnhMetaFileA(
    HDC hdc,           /* [in] optional reference DC */
    LPCSTR filename,   /* [in] optional filename for disk metafiles */
    const RECT *rect,  /* [in] optional bounding rectangle */
    LPCSTR description /* [in] optional description */
    )
{
    LPWSTR filenameW = NULL;
    LPWSTR descriptionW = NULL;
    HDC hReturnDC;
    DWORD len1, len2, total;

    if(filename)
    {
        total = MultiByteToWideChar( CP_ACP, 0, filename, -1, NULL, 0 );
        filenameW = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
        MultiByteToWideChar( CP_ACP, 0, filename, -1, filenameW, total );
    }
    if(description) {
        len1 = strlen(description);
	len2 = strlen(description + len1 + 1);
        total = MultiByteToWideChar( CP_ACP, 0, description, len1 + len2 + 3, NULL, 0 );
	descriptionW = HeapAlloc( GetProcessHeap(), 0, total * sizeof(WCHAR) );
        MultiByteToWideChar( CP_ACP, 0, description, len1 + len2 + 3, descriptionW, total );
    }

    hReturnDC = CreateEnhMetaFileW(hdc, filenameW, rect, descriptionW);

    HeapFree( GetProcessHeap(), 0, filenameW );
    HeapFree( GetProcessHeap(), 0, descriptionW );

    return hReturnDC;
}
GpStatus WINGDIPAPI GdipRecordMetafile(HDC hdc, EmfType type, GDIPCONST GpRectF *frameRect,
                                       MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
{
    HDC record_dc;
    REAL dpix, dpiy;
    REAL framerect_factor_x, framerect_factor_y;
    RECT rc, *lprc;
    GpStatus stat;

    TRACE("(%p %d %p %d %p %p)\n", hdc, type, frameRect, frameUnit, desc, metafile);

    if (!hdc || type < EmfTypeEmfOnly || type > EmfTypeEmfPlusDual || !metafile)
        return InvalidParameter;

    dpix = (REAL)GetDeviceCaps(hdc, HORZRES) / GetDeviceCaps(hdc, HORZSIZE) * 25.4;
    dpiy = (REAL)GetDeviceCaps(hdc, VERTRES) / GetDeviceCaps(hdc, VERTSIZE) * 25.4;

    if (frameRect)
    {
        switch (frameUnit)
        {
        case MetafileFrameUnitPixel:
            framerect_factor_x = 2540.0 / dpix;
            framerect_factor_y = 2540.0 / dpiy;
            break;
        case MetafileFrameUnitPoint:
            framerect_factor_x = framerect_factor_y = 2540.0 / 72.0;
            break;
        case MetafileFrameUnitInch:
            framerect_factor_x = framerect_factor_y = 2540.0;
            break;
        case MetafileFrameUnitDocument:
            framerect_factor_x = framerect_factor_y = 2540.0 / 300.0;
            break;
        case MetafileFrameUnitMillimeter:
            framerect_factor_x = framerect_factor_y = 100.0;
            break;
        case MetafileFrameUnitGdi:
            framerect_factor_x = framerect_factor_y = 1.0;
            break;
        default:
            return InvalidParameter;
        }

        rc.left = framerect_factor_x * frameRect->X;
        rc.top = framerect_factor_y * frameRect->Y;
        rc.right = rc.left + framerect_factor_x * frameRect->Width;
        rc.bottom = rc.top + framerect_factor_y * frameRect->Height;

        lprc = &rc;
    }
    else
        lprc = NULL;

    record_dc = CreateEnhMetaFileW(hdc, NULL, lprc, desc);

    if (!record_dc)
        return GenericError;

    *metafile = heap_alloc_zero(sizeof(GpMetafile));
    if(!*metafile)
    {
        DeleteEnhMetaFile(CloseEnhMetaFile(record_dc));
        return OutOfMemory;
    }

    (*metafile)->image.type = ImageTypeMetafile;
    (*metafile)->image.flags   = ImageFlagsNone;
    (*metafile)->image.palette = NULL;
    (*metafile)->image.xres = dpix;
    (*metafile)->image.yres = dpiy;
    (*metafile)->bounds.X = (*metafile)->bounds.Y = 0.0;
    (*metafile)->bounds.Width = (*metafile)->bounds.Height = 1.0;
    (*metafile)->unit = UnitPixel;
    (*metafile)->metafile_type = type;
    (*metafile)->record_dc = record_dc;
    (*metafile)->comment_data = NULL;
    (*metafile)->comment_data_size = 0;
    (*metafile)->comment_data_length = 0;
    (*metafile)->hemf = NULL;

    if (!frameRect)
    {
        (*metafile)->auto_frame = TRUE;
        (*metafile)->auto_frame_min.X = 0;
        (*metafile)->auto_frame_min.Y = 0;
        (*metafile)->auto_frame_max.X = -1;
        (*metafile)->auto_frame_max.Y = -1;
    }

    stat = METAFILE_WriteHeader(*metafile, hdc);

    if (stat != Ok)
    {
        DeleteEnhMetaFile(CloseEnhMetaFile(record_dc));
        heap_free(*metafile);
        *metafile = NULL;
        return OutOfMemory;
    }

    return stat;
}