metafile.c
来自「一个类似windows」· C语言 代码 · 共 613 行 · 第 1/2 页
C
613 行
/*
* Unit tests for metafile functions
*
* Copyright (c) 2002 Dmitry Timoshkov
*
* 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 <assert.h>
#include <stdio.h>
#include <math.h>
#include "wine/test.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
static LOGFONTA orig_lf;
static BOOL emr_processed = FALSE;
/* Arbitrarily chosen values for the second co-ordinate of a metafile line */
#define LINE_X 55.0f
#define LINE_Y 15.0f
static int CALLBACK emf_enum_proc(HDC hdc, HANDLETABLE *handle_table,
const ENHMETARECORD *emr, int n_objs, LPARAM param)
{
static int n_record;
DWORD i;
const INT *dx;
INT *orig_dx = (INT *)param;
LOGFONTA device_lf;
INT ret;
trace("hdc %p, emr->iType %ld, emr->nSize %ld, param %p\n",
hdc, emr->iType, emr->nSize, (void *)param);
if(!hdc) return 1;
PlayEnhMetaFileRecord(hdc, handle_table, emr, n_objs);
switch (emr->iType)
{
case EMR_HEADER:
n_record = 0;
break;
case EMR_EXTTEXTOUTA:
{
const EMREXTTEXTOUTA *emr_ExtTextOutA = (const EMREXTTEXTOUTA *)emr;
dx = (const INT *)((const char *)emr + emr_ExtTextOutA->emrtext.offDx);
ret = GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(device_lf), &device_lf);
ok( ret == sizeof(device_lf), "GetObjectA error %ld\n", GetLastError());
/* compare up to lfOutPrecision, other values are not interesting,
* and in fact sometimes arbitrary adapted by Win9x.
*/
ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n");
ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n");
for(i = 0; i < emr_ExtTextOutA->emrtext.nChars; i++)
{
ok(orig_dx[i] == dx[i], "pass %d: dx[%ld] (%d) didn't match %d\n",
n_record, i, dx[i], orig_dx[i]);
}
n_record++;
emr_processed = TRUE;
break;
}
case EMR_EXTTEXTOUTW:
{
const EMREXTTEXTOUTW *emr_ExtTextOutW = (const EMREXTTEXTOUTW *)emr;
dx = (const INT *)((const char *)emr + emr_ExtTextOutW->emrtext.offDx);
ret = GetObjectA(GetCurrentObject(hdc, OBJ_FONT), sizeof(device_lf), &device_lf);
ok( ret == sizeof(device_lf), "GetObjectA error %ld\n", GetLastError());
/* compare up to lfOutPrecision, other values are not interesting,
* and in fact sometimes arbitrary adapted by Win9x.
*/
ok(!memcmp(&orig_lf, &device_lf, FIELD_OFFSET(LOGFONTA, lfOutPrecision)), "fonts don't match\n");
ok(!lstrcmpA(orig_lf.lfFaceName, device_lf.lfFaceName), "font names don't match\n");
for(i = 0; i < emr_ExtTextOutW->emrtext.nChars; i++)
{
ok(orig_dx[i] == dx[i], "pass %d: dx[%ld] (%d) didn't match %d\n",
n_record, i, dx[i], orig_dx[i]);
}
n_record++;
emr_processed = TRUE;
break;
}
default:
break;
}
return 1;
}
static void test_ExtTextOut(void)
{
HWND hwnd;
HDC hdcDisplay, hdcMetafile;
HENHMETAFILE hMetafile;
HFONT hFont;
static const char text[] = "Simple text to test ExtTextOut on metafiles";
INT i, len, dx[256];
static const RECT rc = { 0, 0, 100, 100 };
BOOL ret;
assert(sizeof(dx)/sizeof(dx[0]) >= lstrlenA(text));
/* Win9x doesn't play EMFs on invisible windows */
hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
0, 0, 200, 200, 0, 0, 0, NULL);
ok(hwnd != 0, "CreateWindowExA error %ld\n", GetLastError());
hdcDisplay = GetDC(hwnd);
ok(hdcDisplay != 0, "GetDC error %ld\n", GetLastError());
trace("hdcDisplay %p\n", hdcDisplay);
SetMapMode(hdcDisplay, MM_TEXT);
memset(&orig_lf, 0, sizeof(orig_lf));
orig_lf.lfCharSet = ANSI_CHARSET;
orig_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
orig_lf.lfWeight = FW_DONTCARE;
orig_lf.lfHeight = 7;
orig_lf.lfQuality = DEFAULT_QUALITY;
lstrcpyA(orig_lf.lfFaceName, "Arial");
hFont = CreateFontIndirectA(&orig_lf);
ok(hFont != 0, "CreateFontIndirectA error %ld\n", GetLastError());
hFont = SelectObject(hdcDisplay, hFont);
len = lstrlenA(text);
for (i = 0; i < len; i++)
{
ret = GetCharWidthA(hdcDisplay, text[i], text[i], &dx[i]);
ok( ret, "GetCharWidthA error %ld\n", GetLastError());
}
hFont = SelectObject(hdcDisplay, hFont);
hdcMetafile = CreateEnhMetaFileA(hdcDisplay, NULL, NULL, NULL);
ok(hdcMetafile != 0, "CreateEnhMetaFileA error %ld\n", GetLastError());
trace("hdcMetafile %p\n", hdcMetafile);
ok(GetDeviceCaps(hdcMetafile, TECHNOLOGY) == DT_RASDISPLAY,
"GetDeviceCaps(TECHNOLOGY) has to return DT_RASDISPLAY for a display based EMF\n");
hFont = SelectObject(hdcMetafile, hFont);
/* 1. pass NULL lpDx */
ret = ExtTextOutA(hdcMetafile, 0, 0, 0, &rc, text, lstrlenA(text), NULL);
ok( ret, "ExtTextOutA error %ld\n", GetLastError());
/* 2. pass custom lpDx */
ret = ExtTextOutA(hdcMetafile, 0, 20, 0, &rc, text, lstrlenA(text), dx);
ok( ret, "ExtTextOutA error %ld\n", GetLastError());
hFont = SelectObject(hdcMetafile, hFont);
ret = DeleteObject(hFont);
ok( ret, "DeleteObject error %ld\n", GetLastError());
hMetafile = CloseEnhMetaFile(hdcMetafile);
ok(hMetafile != 0, "CloseEnhMetaFile error %ld\n", GetLastError());
ok(!GetObjectType(hdcMetafile), "CloseEnhMetaFile has to destroy metafile hdc\n");
ret = PlayEnhMetaFile(hdcDisplay, hMetafile, &rc);
ok( ret, "PlayEnhMetaFile error %ld\n", GetLastError());
ret = EnumEnhMetaFile(hdcDisplay, hMetafile, emf_enum_proc, dx, &rc);
ok( ret, "EnumEnhMetaFile error %ld\n", GetLastError());
ok(emr_processed, "EnumEnhMetaFile couldn't find EMR_EXTTEXTOUTA or EMR_EXTTEXTOUTW record\n");
ok(!EnumEnhMetaFile(hdcDisplay, hMetafile, emf_enum_proc, dx, NULL),
"A valid hdc has to require a valid rc\n");
ok(EnumEnhMetaFile(NULL, hMetafile, emf_enum_proc, dx, NULL),
"A null hdc does not require a valid rc\n");
ret = DeleteEnhMetaFile(hMetafile);
ok( ret, "DeleteEnhMetaFile error %ld\n", GetLastError());
ret = ReleaseDC(hwnd, hdcDisplay);
ok( ret, "ReleaseDC error %ld\n", GetLastError());
}
/* Win-format metafile (mfdrv) tests */
/* These tests compare the generated metafiles byte-by-byte */
/* with the nominal results. */
/* Maximum size of sample metafiles in bytes. */
#define MF_BUFSIZE 256
/* 8x8 bitmap data for a pattern brush */
static const unsigned char SAMPLE_PATTERN_BRUSH[] = {
0x01, 0x00, 0x02, 0x00,
0x03, 0x00, 0x04, 0x00,
0x05, 0x00, 0x06, 0x00,
0x07, 0x00, 0x08, 0x00
};
/* Sample metafiles to be compared to the outputs of the
* test functions.
*/
static const unsigned char MF_BLANK_BITS[] = {
0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x0c, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const unsigned char MF_GRAPHICS_BITS[] = {
0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x22, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x14, 0x02,
0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,
0x13, 0x02, 0x02, 0x00, 0x02, 0x00, 0x05, 0x00,
0x00, 0x00, 0x14, 0x02, 0x01, 0x00, 0x01, 0x00,
0x07, 0x00, 0x00, 0x00, 0x18, 0x04, 0x02, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00
};
static const unsigned char MF_PATTERN_BRUSH_BITS[] = {
0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x3d, 0x00,
0x00, 0x00, 0x01, 0x00, 0x2d, 0x00, 0x00, 0x00,
0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x42, 0x01,
0x03, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0x00, 0x08, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x2d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00
};
/* For debugging or dumping the raw metafiles produced by
* new test functions.
*/
static void dump_mf_bits (const HMETAFILE mf, const char *desc)
{
char buf[MF_BUFSIZE];
UINT mfsize, i;
mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
printf ("MetaFile %s has bits:\n{\n ", desc);
for (i=0; i<mfsize; i++)
{
printf ("0x%.2hhx", buf[i]);
if (i == mfsize-1)
printf ("\n");
else if (i % 8 == 7)
printf (",\n ");
else
printf (", ");
}
printf ("};\n");
}
/* Compare the metafile produced by a test function with the
* expected raw metafile data in "bits".
* Return value is 0 for a perfect match,
* -1 if lengths aren't equal,
* otherwise returns the number of non-matching bytes.
*/
static int compare_mf_bits (const HMETAFILE mf, const char *bits, UINT bsize,
const char *desc)
{
char buf[MF_BUFSIZE];
UINT mfsize, i;
int diff;
mfsize = GetMetaFileBitsEx (mf, MF_BUFSIZE, buf);
ok (mfsize > 0, "%s: GetMetaFileBitsEx failed.\n", desc);
if (mfsize < MF_BUFSIZE)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?