ReactOS 0.4.17-dev-117-g313be0c
font.c File Reference
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "wine/test.h"
#include "pshpack2.h"
#include "poppack.h"
Include dependency graph for font.c:

Go to the source code of this file.

Classes

struct  font_data
 
struct  enum_font_data
 
struct  enum_fullname_data
 
struct  enum_fullname_data_w
 
struct  enum_font_dataW
 
struct  TT_OS2_V4
 
struct  cmap_header
 
struct  cmap_encoding_record
 
struct  cmap_format_0
 
struct  cmap_format_4
 
struct  cmap_format_4_seg
 
struct  sfnt_name
 
struct  font_realization_info
 
struct  file_info
 
struct  TT_Hori_Header
 

Macros

#define match_off_by_1(a, b, exact)   match_off_by_n((a), (b), (exact) ? 0 : 1)
 
#define near_match(a, b)   match_off_by_n((a), (b), 6)
 
#define expect(expected, got)   ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
 
#define GET_BE_WORD(x)   MAKEWORD(HIBYTE(x), LOBYTE(x))
 
#define GET_BE_DWORD(x)   MAKELONG(GET_BE_WORD(HIWORD(x)), GET_BE_WORD(LOWORD(x)));
 
#define MS_MAKE_TAG(ch0, ch1, ch2, ch3)
 
#define MS_OS2_TAG   MS_MAKE_TAG('O','S','/','2')
 
#define MS_CMAP_TAG   MS_MAKE_TAG('c','m','a','p')
 
#define MS_NAME_TAG   MS_MAKE_TAG('n','a','m','e')
 
#define FH_SCALE   0x80000000
 
#define TT_OS2_V0_SIZE   (FIELD_OFFSET(TT_OS2_V4, ulCodePageRange1))
 
#define TT_PLATFORM_APPLE_UNICODE   0
 
#define TT_PLATFORM_MACINTOSH   1
 
#define TT_PLATFORM_MICROSOFT   3
 
#define TT_APPLE_ID_DEFAULT   0
 
#define TT_APPLE_ID_ISO_10646   2
 
#define TT_APPLE_ID_UNICODE_2_0   3
 
#define TT_MS_ID_SYMBOL_CS   0
 
#define TT_MS_ID_UNICODE_CS   1
 
#define TT_MS_LANGID_ENGLISH_UNITED_STATES   0x0409
 
#define TT_NAME_ID_FONT_FAMILY   1
 
#define TT_NAME_ID_FONT_SUBFAMILY   2
 
#define TT_NAME_ID_UNIQUE_ID   3
 
#define TT_NAME_ID_FULL_NAME   4
 
#define TT_MAC_ID_SIMPLIFIED_CHINESE   25
 
#define SCALE_NTM(value)   (MulDiv(ntm->tmHeight, (value), cell_height))
 

Typedefs

typedef struct sfnt_name sfnt_name
 

Enumerations

enum  cmap_type { cmap_none , cmap_ms_unicode , cmap_ms_symbol }
 

Functions

static BOOL match_off_by_n (int a, int b, unsigned int n)
 
static LONG (WINAPI *pGdiGetCharDimensions)(HDC hdc
 
static DWORD (WINAPI *pGdiGetCodePage)(HDC hdc)
 
static BOOL (WINAPI *pGetCharWidthInfo)(HDC hdc
 
static void init (void)
 
static INT CALLBACK is_truetype_font_installed_proc (const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 
static BOOL is_truetype_font_installed (const char *name)
 
static INT CALLBACK is_font_installed_proc (const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 
static BOOL is_font_installed (const char *name)
 
static voidget_res_data (const char *fontname, DWORD *rsrc_size)
 
static BOOL write_tmp_file (const void *data, DWORD *size, char *tmp_name)
 
static BOOL write_ttf_file (const char *fontname, char *tmp_name)
 
static void check_font (const char *test, const LOGFONTA *lf, HFONT hfont)
 
static HFONT create_font (const char *test, const LOGFONTA *lf)
 
static void test_logfont (void)
 
static INT CALLBACK font_enum_proc (const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 
static void compare_tm (const TEXTMETRICA *tm, const TEXTMETRICA *otm)
 
static void test_font_metrics (const char *context, HDC hdc, HFONT hfont, LONG lfHeight, LONG lfWidth, const char *test_str, INT test_str_len, const TEXTMETRICA *tm_orig, const SIZE *size_orig, INT width_of_A_orig, INT scale_x, INT scale_y)
 
static void test_bitmap_font (void)
 
static void test_outline_font (void)
 
static INT CALLBACK find_font_proc (const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 
static BOOL is_CJK (void)
 
static void test_bitmap_font_metrics (void)
 
static void test_GdiGetCharDimensions (void)
 
static int CALLBACK create_font_proc (const LOGFONTA *lpelfe, const TEXTMETRICA *lpntme, DWORD FontType, LPARAM lParam)
 
static void ABCWidths_helper (const char *description, HDC hdc, WORD *glyphs, const ABC *base_abci, const ABC *base_abcw, const ABCFLOAT *base_abcf)
 
static void test_GetCharABCWidths (void)
 
static void test_text_extents (void)
 
static void free_font (void *font)
 
static voidload_font (const char *font_name, DWORD *font_size)
 
static void test_GetGlyphIndices (void)
 
static void test_GetKerningPairs (void)
 
static void test_height (HDC hdc, const struct font_data *fd)
 
static voidfind_ttf_table (void *ttf, DWORD size, DWORD tag)
 
static void test_height_selection_vdmx (HDC hdc)
 
static void test_height_selection (void)
 
static UINT get_font_fsselection (LOGFONTA *lf)
 
static void test_GetOutlineTextMetrics (void)
 
static void testJustification (const char *context, HDC hdc, PCSTR str, RECT *clientArea)
 
static void test_SetTextJustification (void)
 
static BOOL get_glyph_indices (INT charset, UINT code_page, WORD *idx, UINT count, BOOL unicode)
 
static void test_TranslateCharsetInfo (void)
 
static void test_font_charset (void)
 
static void test_GdiGetCodePage (void)
 
static void test_GetFontUnicodeRanges (void)
 
static INT CALLBACK arial_enum_proc (const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
 
static INT CALLBACK arial_enum_procw (const LOGFONTW *lf, const TEXTMETRICW *tm, DWORD type, LPARAM lParam)
 
static void get_charset_stats (struct enum_font_data *efd, int *ansi_charset, int *symbol_charset, int *russian_charset)
 
static void get_charset_statsW (struct enum_font_dataW *efd, int *ansi_charset, int *symbol_charset, int *russian_charset)
 
static void test_EnumFontFamilies (const char *font_name, INT font_charset)
 
static INT CALLBACK enum_multi_charset_font_proc (const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
 
static INT CALLBACK enum_font_data_proc (const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 
static INT CALLBACK enum_fullname_data_proc (const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 
static INT CALLBACK enum_fullname_data_proc_w (const LOGFONTW *lf, const TEXTMETRICW *ntm, DWORD type, LPARAM lParam)
 
static void test_EnumFontFamiliesEx_default_charset (void)
 
static void test_negative_width (HDC hdc, const LOGFONTA *lf)
 
static void expect_ff (const TEXTMETRICA *tmA, const TT_OS2_V4 *os2, WORD family, const char *name)
 
static BOOL get_first_last_from_cmap0 (void *ptr, DWORD *first, DWORD *last)
 
static void get_seg4 (cmap_format_4 *cmap, USHORT seg_num, cmap_format_4_seg *seg)
 
static BOOL get_first_last_from_cmap4 (void *ptr, DWORD *first, DWORD *last, DWORD limit)
 
static voidget_cmap (cmap_header *header, USHORT plat_id, USHORT enc_id)
 
static BOOL get_first_last_from_cmap (HDC hdc, DWORD *first, DWORD *last, cmap_type *cmap_type)
 
static WORD get_mac_code_page (const sfnt_name *name)
 
static int match_name_table_language (const sfnt_name *name, LANGID lang)
 
static BOOL get_ttf_nametable_entry (HDC hdc, WORD name_id, WCHAR *out_buf, SIZE_T out_size, LCID language_id)
 
static void test_text_metrics (const LOGFONTA *lf, const NEWTEXTMETRICA *ntm)
 
static INT CALLBACK enum_truetype_font_proc (const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 
static void test_GetTextMetrics (void)
 
static void test_nonexistent_font (void)
 
static void test_RealizationInfo (void)
 
static void test_GetTextFace (void)
 
static void test_orientation (void)
 
static void test_oemcharset (void)
 
static int CALLBACK create_fixed_pitch_font_proc (const LOGFONTA *lpelfe, const TEXTMETRICA *lpntme, DWORD FontType, LPARAM lParam)
 
static void test_GetGlyphOutline (void)
 
static void test_GetTextMetrics2 (const char *fontname, int font_height)
 
static void test_GetCharacterPlacement (void)
 
static void test_CreateFontIndirect (void)
 
static void test_CreateFontIndirectEx (void)
 
static void test_realization_info (const char *name, DWORD size, BOOL is_memory_resource)
 
static void test_AddFontMemResource (void)
 
static INT CALLBACK enum_fonts_proc (const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
 
static INT CALLBACK enum_all_fonts_proc (const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
 
static INT CALLBACK enum_with_magic_retval_proc (const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
 
static void test_EnumFonts (void)
 
static INT CALLBACK enum_ms_shell_dlg_proc (const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 
static INT CALLBACK enum_ms_shell_dlg2_proc (const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 
static void test_EnumFonts_subst (void)
 
static INT CALLBACK is_font_installed_fullname_proc (const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 
static BOOL is_font_installed_fullname (const char *family, const char *fullname)
 
static void test_fullname (void)
 
static WCHARprepend_at (WCHAR *family)
 
static void test_fullname2_helper (const char *Family)
 
static void test_fullname2 (void)
 
static void test_GetGlyphOutline_empty_contour (void)
 
static void test_GetGlyphOutline_metric_clipping (void)
 
static void test_GetGlyphOutline_character (void)
 
static void test_fstype_fixup (void)
 
static void test_CreateScalableFontResource (void)
 
static void check_vertical_font (const char *name, BOOL *installed, BOOL *selected, GLYPHMETRICS *gm, WORD *gi)
 
static void check_vertical_metrics (const char *face)
 
static void test_vertical_font (void)
 
static INT CALLBACK has_vertical_font_proc (const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 
static void test_east_asian_font_selection (void)
 
static int get_font_dpi (const LOGFONTA *lf, int *height)
 
static void test_stock_fonts (void)
 
static void test_max_height (void)
 
static void test_vertical_order (void)
 
static void test_GetCharWidth32 (void)
 
static void test_fake_bold_font (void)
 
static void test_bitmap_font_glyph_index (void)
 
static void test_GetCharWidthI (void)
 
static INT CALLBACK long_enum_proc (const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lparam)
 
static void test_long_names (void)
 
static void test_ttf_names (void)
 
static void test_lang_names (void)
 
static void test_GetCharWidthInfo (void)
 
static int CALLBACK get_char_width_proc (const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM ctx)
 
static void test_char_width (void)
 
static void test_GetCharacterPlacement_kerning (void)
 
static void test_select_object (void)
 
static void test_GetOutlineTextMetrics_subst (void)
 
static INT CALLBACK test_font_weight_enum (const LOGFONTW *lf, const TEXTMETRICW *tm, DWORD type, LPARAM lparam)
 
static void test_font_weight (void)
 
 START_TEST (font)
 

Variables

static LPTEXTMETRICW lptm
 
static LPTEXTMETRICW LONGheight
 
static void *static DWORD *static DWORD *static DWORD
 
static void *static DWORD *static DWORD *static void SIZE_T
 
static void *static DWORD *static DWORD *static void SIZE_T *static UINT64
 
static HMODULE hgdi32 = 0
 
static const MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} }
 
static WORD system_lang_id
 
static const LANGID mac_langid_table []
 

Macro Definition Documentation

◆ expect

#define expect (   expected,
  got 
)    ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)

Definition at line 40 of file font.c.

◆ FH_SCALE

#define FH_SCALE   0x80000000

Definition at line 707 of file font.c.

◆ GET_BE_DWORD

#define GET_BE_DWORD (   x)    MAKELONG(GET_BE_WORD(HIWORD(x)), GET_BE_WORD(LOWORD(x)));

Definition at line 59 of file font.c.

◆ GET_BE_WORD

#define GET_BE_WORD (   x)    MAKEWORD(HIBYTE(x), LOBYTE(x))

Definition at line 58 of file font.c.

◆ match_off_by_1

#define match_off_by_1 (   a,
  b,
  exact 
)    match_off_by_n((a), (b), (exact) ? 0 : 1)

Definition at line 38 of file font.c.

◆ MS_CMAP_TAG

#define MS_CMAP_TAG   MS_MAKE_TAG('c','m','a','p')

Definition at line 66 of file font.c.

◆ MS_MAKE_TAG

#define MS_MAKE_TAG (   ch0,
  ch1,
  ch2,
  ch3 
)
Value:
((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DWORD
Definition: nt_native.h:44
unsigned char BYTE
Definition: xxhash.c:193

Definition at line 62 of file font.c.

◆ MS_NAME_TAG

#define MS_NAME_TAG   MS_MAKE_TAG('n','a','m','e')

Definition at line 67 of file font.c.

◆ MS_OS2_TAG

#define MS_OS2_TAG   MS_MAKE_TAG('O','S','/','2')

Definition at line 65 of file font.c.

◆ near_match

#define near_match (   a,
  b 
)    match_off_by_n((a), (b), 6)

Definition at line 39 of file font.c.

◆ SCALE_NTM

#define SCALE_NTM (   value)    (MulDiv(ntm->tmHeight, (value), cell_height))

◆ TT_APPLE_ID_DEFAULT

#define TT_APPLE_ID_DEFAULT   0

Definition at line 3572 of file font.c.

◆ TT_APPLE_ID_ISO_10646

#define TT_APPLE_ID_ISO_10646   2

Definition at line 3573 of file font.c.

◆ TT_APPLE_ID_UNICODE_2_0

#define TT_APPLE_ID_UNICODE_2_0   3

Definition at line 3574 of file font.c.

◆ TT_MAC_ID_SIMPLIFIED_CHINESE

#define TT_MAC_ID_SIMPLIFIED_CHINESE   25

Definition at line 3582 of file font.c.

◆ TT_MS_ID_SYMBOL_CS

#define TT_MS_ID_SYMBOL_CS   0

Definition at line 3575 of file font.c.

◆ TT_MS_ID_UNICODE_CS

#define TT_MS_ID_UNICODE_CS   1

Definition at line 3576 of file font.c.

◆ TT_MS_LANGID_ENGLISH_UNITED_STATES

#define TT_MS_LANGID_ENGLISH_UNITED_STATES   0x0409

Definition at line 3577 of file font.c.

◆ TT_NAME_ID_FONT_FAMILY

#define TT_NAME_ID_FONT_FAMILY   1

Definition at line 3578 of file font.c.

◆ TT_NAME_ID_FONT_SUBFAMILY

#define TT_NAME_ID_FONT_SUBFAMILY   2

Definition at line 3579 of file font.c.

◆ TT_NAME_ID_FULL_NAME

#define TT_NAME_ID_FULL_NAME   4

Definition at line 3581 of file font.c.

◆ TT_NAME_ID_UNIQUE_ID

#define TT_NAME_ID_UNIQUE_ID   3

Definition at line 3580 of file font.c.

◆ TT_OS2_V0_SIZE

#define TT_OS2_V0_SIZE   (FIELD_OFFSET(TT_OS2_V4, ulCodePageRange1))

Definition at line 3385 of file font.c.

◆ TT_PLATFORM_APPLE_UNICODE

#define TT_PLATFORM_APPLE_UNICODE   0

Definition at line 3569 of file font.c.

◆ TT_PLATFORM_MACINTOSH

#define TT_PLATFORM_MACINTOSH   1

Definition at line 3570 of file font.c.

◆ TT_PLATFORM_MICROSOFT

#define TT_PLATFORM_MICROSOFT   3

Definition at line 3571 of file font.c.

Typedef Documentation

◆ sfnt_name

Enumeration Type Documentation

◆ cmap_type

Enumerator
cmap_none 
cmap_ms_unicode 
cmap_ms_symbol 

Definition at line 3512 of file font.c.

3513{
3514 cmap_none,
3517} cmap_type;
cmap_type
Definition: font.c:3513
@ cmap_ms_unicode
Definition: font.c:3515
@ cmap_none
Definition: font.c:3514
@ cmap_ms_symbol
Definition: font.c:3516

Function Documentation

◆ ABCWidths_helper()

static void ABCWidths_helper ( const char description,
HDC  hdc,
WORD glyphs,
const ABC base_abci,
const ABC base_abcw,
const ABCFLOAT base_abcf 
)
static

Definition at line 1078 of file font.c.

1079{
1080 ABC abc[1];
1081 ABCFLOAT abcf[1];
1082 BOOL ret = FALSE;
1083
1084 ret = GetCharABCWidthsI(hdc, 0, 1, glyphs, abc);
1085 ok(ret, "%s: GetCharABCWidthsI should have succeeded\n", description);
1086 ok ((INT)abc->abcB > 0, "%s: abcB should be positive\n", description);
1087 ok(abc->abcA * base_abci->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
1088 ok(abc->abcC * base_abci->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
1089
1090 ret = GetCharABCWidthsI(hdc, glyphs[0], 1, NULL, abc);
1091 ok(ret, "%s: GetCharABCWidthsI should have succeeded\n", description);
1092 ok ((INT)abc->abcB > 0, "%s: abcB should be positive\n", description);
1093 ok(abc->abcA * base_abci->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
1094 ok(abc->abcC * base_abci->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
1095
1096 ret = GetCharABCWidthsW(hdc, 'i', 'i', abc);
1097 ok(ret, "%s: GetCharABCWidthsW should have succeeded\n", description);
1098 ok ((INT)abc->abcB > 0, "%s: abcB should be positive\n", description);
1099 ok(abc->abcA * base_abcw->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
1100 ok(abc->abcC * base_abcw->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
1101
1102 ret = GetCharABCWidthsFloatW(hdc, 'i', 'i', abcf);
1103 ok(ret, "%s: GetCharABCWidthsFloatW should have succeeded\n", description);
1104 ok (abcf->abcfB > 0.0, "%s: abcfB should be positive\n", description);
1105 ok(abcf->abcfA * base_abcf->abcfA >= 0.0, "%s: abcfA's sign should be unchanged\n", description);
1106 ok(abcf->abcfC * base_abcf->abcfC >= 0.0, "%s: abcfC's sign should be unchanged\n", description);
1107}
#define ok(value,...)
Definition: atltest.h:57
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
return ret
Definition: mutex.c:146
unsigned int BOOL
Definition: ntddk_ex.h:94
HDC hdc
Definition: main.c:9
FLOAT abcfA
Definition: wingdi.h:1862
FLOAT abcfC
Definition: wingdi.h:1864
FLOAT abcfB
Definition: wingdi.h:1863
Definition: wingdi.h:1856
int abcA
Definition: wingdi.h:1857
UINT abcB
Definition: wingdi.h:1858
int abcC
Definition: wingdi.h:1859
int32_t INT
Definition: typedefs.h:58
const char * description
Definition: directx.c:2497
BOOL WINAPI GetCharABCWidthsFloatW(_In_ HDC hdc, _In_ UINT iFirst, _In_ UINT iLast, _Out_writes_(iLast+1 - iFirst) LPABCFLOAT lpABC)
BOOL WINAPI GetCharABCWidthsI(_In_ HDC hdc, _In_ UINT giFirst, _In_ UINT cgi, _In_reads_opt_(cgi) LPWORD pgi, _Out_writes_(cgi) LPABC pabc)
BOOL WINAPI GetCharABCWidthsW(_In_ HDC hdc, _In_ UINT wFirst, _In_ UINT wLast, _Out_writes_(wLast - wFirst+1) LPABC lpABC)

Referenced by test_GetCharABCWidths().

◆ arial_enum_proc()

static INT CALLBACK arial_enum_proc ( const LOGFONTA lf,
const TEXTMETRICA tm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 2861 of file font.c.

2862{
2863 struct enum_font_data *efd = (struct enum_font_data *)lParam;
2864 const NEWTEXTMETRICA *ntm = (const NEWTEXTMETRICA *)tm;
2865
2866 ok(lf->lfHeight == tm->tmHeight, "lfHeight %ld != tmHeight %ld\n", lf->lfHeight, tm->tmHeight);
2867
2868 if (type != TRUETYPE_FONTTYPE) return 1;
2869
2870 ok(ntm->ntmCellHeight + ntm->ntmCellHeight/5 >= ntm->ntmSizeEM, "ntmCellHeight %d should be close to ntmSizeEM %d\n", ntm->ntmCellHeight, ntm->ntmSizeEM);
2871
2872 if (efd->total >= efd->size)
2873 {
2874 efd->size = max( (efd->total + 1) * 2, 256 );
2875 efd->lf = realloc( efd->lf, efd->size * sizeof(*efd->lf) );
2876 if (!efd->lf) return 0;
2877 }
2878 efd->lf[efd->total++] = *lf;
2879
2880 return 1;
2881}
LPARAM lParam
Definition: combotst.c:139
#define realloc
Definition: debug_ros.c:6
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
LONG lfHeight
Definition: dimm.idl:42
LOGFONTA * lf
Definition: font.c:2840
UINT ntmCellHeight
Definition: wingdi.h:3086
#define max(a, b)
Definition: svc.c:63
#define TRUETYPE_FONTTYPE
Definition: wingdi.h:1109

Referenced by test_EnumFontFamilies().

◆ arial_enum_procw()

static INT CALLBACK arial_enum_procw ( const LOGFONTW lf,
const TEXTMETRICW tm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 2883 of file font.c.

2884{
2885 struct enum_font_dataW *efd = (struct enum_font_dataW *)lParam;
2886 const NEWTEXTMETRICW *ntm = (const NEWTEXTMETRICW *)tm;
2887
2888 ok(lf->lfHeight == tm->tmHeight, "lfHeight %ld != tmHeight %ld\n", lf->lfHeight, tm->tmHeight);
2889
2890 if (type != TRUETYPE_FONTTYPE) return 1;
2891
2892 ok(ntm->ntmCellHeight + ntm->ntmCellHeight/5 >= ntm->ntmSizeEM, "ntmCellHeight %d should be close to ntmSizeEM %d\n", ntm->ntmCellHeight, ntm->ntmSizeEM);
2893
2894 if (efd->total >= efd->size)
2895 {
2896 efd->size = max( (efd->total + 1) * 2, 256 );
2897 efd->lf = realloc( efd->lf, efd->size * sizeof(*efd->lf) );
2898 if (!efd->lf) return 0;
2899 }
2900 efd->lf[efd->total++] = *lf;
2901
2902 return 1;
2903}
LONG lfHeight
Definition: dimm.idl:59
LOGFONTW * lf
Definition: font.c:2858
UINT ntmCellHeight
Definition: wingdi.h:3112

Referenced by test_EnumFontFamilies().

◆ BOOL()

static BOOL ( WINAPI pGetCharWidthInfo)
static

◆ check_font()

static void check_font ( const char test,
const LOGFONTA lf,
HFONT  hfont 
)
static

Definition at line 166 of file font.c.

167{
168 LOGFONTA getobj_lf;
169 int ret;
170
171 if (!hfont)
172 return;
173
174 ret = GetObjectA(hfont, sizeof(getobj_lf), &getobj_lf);
175 ok(ret == sizeof(LOGFONTA), "%s: GetObject returned %d\n", test, ret);
176 ok(lf->lfHeight == getobj_lf.lfHeight, "lfHeight: expect %08lx got %08lx\n", lf->lfHeight, getobj_lf.lfHeight);
177 ok(lf->lfWidth == getobj_lf.lfWidth, "lfWidth: expect %08lx got %08lx\n", lf->lfWidth, getobj_lf.lfWidth);
178 ok(lf->lfEscapement == getobj_lf.lfEscapement, "lfEscapement: expect %08lx got %08lx\n", lf->lfEscapement, getobj_lf.lfEscapement);
179 ok(lf->lfOrientation == getobj_lf.lfOrientation, "lfOrientation: expect %08lx got %08lx\n", lf->lfOrientation, getobj_lf.lfOrientation);
180 ok(lf->lfWeight == getobj_lf.lfWeight, "lfWeight: expect %08lx got %08lx\n", lf->lfWeight, getobj_lf.lfWeight);
181 ok(lf->lfItalic == getobj_lf.lfItalic, "lfItalic: expect %02x got %02x\n", lf->lfItalic, getobj_lf.lfItalic);
182 ok(lf->lfUnderline == getobj_lf.lfUnderline, "lfUnderline: expect %02x got %02x\n", lf->lfUnderline, getobj_lf.lfUnderline);
183 ok(lf->lfStrikeOut == getobj_lf.lfStrikeOut, "lfStrikeOut: expect %02x got %02x\n", lf->lfStrikeOut, getobj_lf.lfStrikeOut);
184 ok(lf->lfCharSet == getobj_lf.lfCharSet, "lfCharSet: expect %02x got %02x\n", lf->lfCharSet, getobj_lf.lfCharSet);
185 ok(lf->lfOutPrecision == getobj_lf.lfOutPrecision, "lfOutPrecision: expect %02x got %02x\n", lf->lfOutPrecision, getobj_lf.lfOutPrecision);
186 ok(lf->lfClipPrecision == getobj_lf.lfClipPrecision, "lfClipPrecision: expect %02x got %02x\n", lf->lfClipPrecision, getobj_lf.lfClipPrecision);
187 ok(lf->lfQuality == getobj_lf.lfQuality, "lfQuality: expect %02x got %02x\n", lf->lfQuality, getobj_lf.lfQuality);
188 ok(lf->lfPitchAndFamily == getobj_lf.lfPitchAndFamily, "lfPitchAndFamily: expect %02x got %02x\n", lf->lfPitchAndFamily, getobj_lf.lfPitchAndFamily);
189 ok(!lstrcmpA(lf->lfFaceName, getobj_lf.lfFaceName), "%s: font names don't match: %s != %s\n", test, lf->lfFaceName, getobj_lf.lfFaceName);
190}
static HFONT hfont
int WINAPI lstrcmpA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4104
#define test
Definition: rosglue.h:37
BYTE lfStrikeOut
Definition: dimm.idl:49
BYTE lfClipPrecision
Definition: dimm.idl:52
BYTE lfUnderline
Definition: dimm.idl:48
BYTE lfQuality
Definition: dimm.idl:53
BYTE lfOutPrecision
Definition: dimm.idl:51
LONG lfOrientation
Definition: dimm.idl:45
BYTE lfItalic
Definition: dimm.idl:47
BYTE lfPitchAndFamily
Definition: dimm.idl:54
LONG lfEscapement
Definition: dimm.idl:44
BYTE lfCharSet
Definition: dimm.idl:50
LONG lfWeight
Definition: dimm.idl:46
CHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:55
LONG lfWidth
Definition: dimm.idl:43
int WINAPI GetObjectA(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)

Referenced by create_font(), test_CreateFontIndirectEx(), test_logfont(), and test_negative_width().

◆ check_vertical_font()

static void check_vertical_font ( const char name,
BOOL installed,
BOOL selected,
GLYPHMETRICS gm,
WORD gi 
)
static

Definition at line 6111 of file font.c.

6112{
6113 LOGFONTA lf;
6114 HFONT hfont, hfont_prev;
6115 HDC hdc;
6116 char facename[100];
6117 DWORD ret;
6118 static const WCHAR str[] = { 0x2025 };
6119
6120 *installed = is_truetype_font_installed(name);
6121
6122 lf.lfHeight = -18;
6123 lf.lfWidth = 0;
6124 lf.lfEscapement = 0;
6125 lf.lfOrientation = 0;
6126 lf.lfWeight = FW_DONTCARE;
6127 lf.lfItalic = 0;
6128 lf.lfUnderline = 0;
6129 lf.lfStrikeOut = 0;
6135 strcpy(lf.lfFaceName, name);
6136
6138 ok(hfont != NULL, "CreateFontIndirectA failed\n");
6139
6140 hdc = GetDC(NULL);
6141
6142 hfont_prev = SelectObject(hdc, hfont);
6143 ok(hfont_prev != NULL, "SelectObject failed\n");
6144
6145 ret = GetTextFaceA(hdc, sizeof facename, facename);
6146 ok(ret, "GetTextFaceA failed\n");
6147 *selected = !strcmp(facename, name);
6148
6149 ret = GetGlyphOutlineW(hdc, 0x2025, GGO_METRICS, gm, 0, NULL, &mat);
6150 ok(ret != GDI_ERROR, "GetGlyphOutlineW failed\n");
6151 if (!*selected)
6152 memset(gm, 0, sizeof *gm);
6153
6154 ret = GetGlyphIndicesW(hdc, str, 1, gi, 0);
6155 ok(ret != GDI_ERROR, "GetGlyphIndicesW failed\n");
6156
6157 SelectObject(hdc, hfont_prev);
6159 ReleaseDC(NULL, hdc);
6160}
static char selected[MAX_PATH+1]
Definition: dirdlg.c:7
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
pKey DeleteObject()
static HDC
Definition: imagelist.c:88
static const MAT2 mat
Definition: font.c:51
static BOOL is_truetype_font_installed(const char *name)
Definition: font.c:91
short WCHAR
Definition: pedump.c:58
const WCHAR * str
strcpy
Definition: string.h:131
#define memset(x, y, z)
Definition: compat.h:39
Definition: name.c:39
#define DEFAULT_PITCH
Definition: wingdi.h:443
#define FW_DONTCARE
Definition: wingdi.h:368
DWORD WINAPI GetGlyphIndicesW(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpstr, _In_ int c, _Out_writes_(c) LPWORD pgi, _In_ DWORD fl)
#define OUT_TT_ONLY_PRECIS
Definition: wingdi.h:422
HFONT WINAPI CreateFontIndirectA(_In_ const LOGFONTA *)
#define DEFAULT_QUALITY
Definition: wingdi.h:436
#define FF_DONTCARE
Definition: wingdi.h:448
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
int WINAPI GetTextFaceA(_In_ HDC hdc, _In_ int c, _Out_writes_to_opt_(c, return) LPSTR lpName)
#define DEFAULT_CHARSET
Definition: wingdi.h:384
#define GDI_ERROR
Definition: wingdi.h:1309
#define CLIP_DEFAULT_PRECIS
Definition: wingdi.h:426
#define GGO_METRICS
Definition: wingdi.h:848
DWORD WINAPI GetGlyphOutlineW(_In_ HDC hdc, _In_ UINT uChar, _In_ UINT fuFormat, _Out_ LPGLYPHMETRICS lpgm, _In_ DWORD cjBuffer, _Out_writes_bytes_opt_(cjBuffer) LPVOID pvBuffer, _In_ CONST MAT2 *lpmat2)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HDC WINAPI GetDC(_In_opt_ HWND)

Referenced by test_vertical_font().

◆ check_vertical_metrics()

static void check_vertical_metrics ( const char face)
static

Definition at line 6162 of file font.c.

6163{
6164 LOGFONTA lf;
6165 HFONT hfont, hfont_prev;
6166 HDC hdc;
6167 DWORD ret;
6168 GLYPHMETRICS rgm, vgm;
6169 const UINT code = 0x5EAD, height = 1000;
6170 WORD idx;
6171 ABC abc, vabc;
6173 USHORT numOfLongVerMetrics;
6174
6175 hdc = GetDC(NULL);
6176
6177 memset(&lf, 0, sizeof(lf));
6178 strcpy(lf.lfFaceName, face);
6179 lf.lfHeight = -height;
6181 lf.lfEscapement = lf.lfOrientation = 900;
6183 hfont_prev = SelectObject(hdc, hfont);
6184 ret = GetGlyphOutlineW(hdc, code, GGO_METRICS, &rgm, 0, NULL, &mat);
6185 ok(ret != GDI_ERROR, "GetGlyphOutlineW failed\n");
6186 ret = GetCharABCWidthsW(hdc, code, code, &abc);
6187 ok(ret, "GetCharABCWidthsW failed\n");
6188 DeleteObject(SelectObject(hdc, hfont_prev));
6189
6190 memset(&lf, 0, sizeof(lf));
6191 strcpy(lf.lfFaceName, "@");
6192 strcat(lf.lfFaceName, face);
6193 lf.lfHeight = -height;
6196 hfont_prev = SelectObject(hdc, hfont);
6197 ret = GetGlyphOutlineW(hdc, code, GGO_METRICS, &vgm, 0, NULL, &mat);
6198 ok(ret != GDI_ERROR, "GetGlyphOutlineW failed\n");
6199 ret = GetCharABCWidthsW(hdc, code, code, &vabc);
6200 ok(ret, "GetCharABCWidthsW failed\n");
6201 ok(vabc.abcA == vgm.gmptGlyphOrigin.x, "expected %d, got %ld\n",
6202 vabc.abcA, vgm.gmptGlyphOrigin.x);
6203 ok(vabc.abcB == vgm.gmBlackBoxX, "expected %d, got %d\n",
6204 vabc.abcB, vgm.gmBlackBoxX);
6205 ok(vabc.abcA + vabc.abcB + vabc.abcC == vgm.gmCellIncX,
6206 "expected %d, got %d\n",
6207 vabc.abcA + vabc.abcB + vabc.abcC, vgm.gmCellIncX);
6208
6209 memset(&otm, 0, sizeof(otm));
6210 otm.otmSize = sizeof(otm);
6211 ret = GetOutlineTextMetricsA(hdc, sizeof(otm), &otm);
6212 ok(ret != 0, "GetOutlineTextMetricsA failed\n");
6213
6214 if (GetFontData(hdc, MS_MAKE_TAG('v','h','e','a'), sizeof(SHORT) * 17,
6215 &numOfLongVerMetrics, sizeof(numOfLongVerMetrics)) != GDI_ERROR) {
6216 int offset;
6217 SHORT topSideBearing;
6218
6219 ret = GetGlyphIndicesW(hdc, (LPCWSTR)&code, 1, &idx, 0);
6220 ok(ret != 0, "GetGlyphIndicesW failed\n");
6221 numOfLongVerMetrics = GET_BE_WORD(numOfLongVerMetrics);
6222 if (numOfLongVerMetrics > idx)
6223 offset = idx * 2 + 1;
6224 else
6225 offset = numOfLongVerMetrics * 2 + (idx - numOfLongVerMetrics);
6226 ret = GetFontData(hdc, MS_MAKE_TAG('v','m','t','x'), offset * sizeof(SHORT),
6227 &topSideBearing, sizeof(SHORT));
6228 ok(ret != GDI_ERROR, "GetFontData(vmtx) failed\n");
6229 topSideBearing = GET_BE_WORD(topSideBearing);
6231 MulDiv(topSideBearing, height, otm.otmEMSquare), FALSE),
6232 "expected %d, got %ld\n",
6233 MulDiv(topSideBearing, height, otm.otmEMSquare), vgm.gmptGlyphOrigin.x);
6234 }
6235 else
6236 {
6237 ok(vgm.gmptGlyphOrigin.x == rgm.gmptGlyphOrigin.x + vgm.gmCellIncX + otm.otmDescent,
6238 "got %ld, expected rgm.origin.x(%ld) + vgm.cellIncX(%d) + descent(%d)\n",
6240 }
6241
6242 ok(vgm.gmptGlyphOrigin.y == abc.abcA + abc.abcB + otm.otmDescent,
6243 "got %d, expected abcA(%d) + abcB(%u) + descent(%d)\n",
6244 (INT)vgm.gmptGlyphOrigin.y, abc.abcA, abc.abcB, otm.otmDescent);
6245
6246 DeleteObject(SelectObject(hdc, hfont_prev));
6247 ReleaseDC(NULL, hdc);
6248}
unsigned int idx
Definition: utils.c:41
#define GET_BE_WORD(x)
Definition: font.c:109
unsigned short WORD
Definition: ntddk_ex.h:93
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLintptr offset
Definition: glext.h:5920
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
#define match_off_by_1(a, b, exact)
Definition: font.c:38
#define MS_MAKE_TAG(ch0, ch1, ch2, ch3)
Definition: font.c:62
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
unsigned int UINT
Definition: ndis.h:50
short SHORT
Definition: pedump.c:59
unsigned short USHORT
Definition: pedump.c:61
strcat
Definition: string.h:92
short gmCellIncX
Definition: wingdi.h:2891
UINT gmBlackBoxX
Definition: wingdi.h:2888
POINT gmptGlyphOrigin
Definition: wingdi.h:2890
Definition: inflate.c:139
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
const uint16_t * LPCWSTR
Definition: typedefs.h:57
DWORD WINAPI GetFontData(HDC hdc, DWORD dwTable, DWORD dwOffset, LPVOID lpvBuffer, DWORD cbData)
Definition: font.c:2801
UINT WINAPI GetOutlineTextMetricsA(_In_ HDC hdc, _In_ UINT cjCopy, _Out_writes_bytes_opt_(cjCopy) LPOUTLINETEXTMETRICA potm)

Referenced by test_vertical_font().

◆ compare_tm()

static void compare_tm ( const TEXTMETRICA tm,
const TEXTMETRICA otm 
)
static

Definition at line 240 of file font.c.

241{
242 ok(tm->tmHeight == otm->tmHeight, "tmHeight %ld != %ld\n", tm->tmHeight, otm->tmHeight);
243 ok(tm->tmAscent == otm->tmAscent, "tmAscent %ld != %ld\n", tm->tmAscent, otm->tmAscent);
244 ok(tm->tmDescent == otm->tmDescent, "tmDescent %ld != %ld\n", tm->tmDescent, otm->tmDescent);
245 ok(tm->tmInternalLeading == otm->tmInternalLeading, "tmInternalLeading %ld != %ld\n", tm->tmInternalLeading, otm->tmInternalLeading);
246 ok(tm->tmExternalLeading == otm->tmExternalLeading, "tmExternalLeading %ld != %ld\n", tm->tmExternalLeading, otm->tmExternalLeading);
247 ok(tm->tmAveCharWidth == otm->tmAveCharWidth, "tmAveCharWidth %ld != %ld\n", tm->tmAveCharWidth, otm->tmAveCharWidth);
248 ok(tm->tmMaxCharWidth == otm->tmMaxCharWidth, "tmMaxCharWidth %ld != %ld\n", tm->tmMaxCharWidth, otm->tmMaxCharWidth);
249 ok(tm->tmWeight == otm->tmWeight, "tmWeight %ld != %ld\n", tm->tmWeight, otm->tmWeight);
250 ok(tm->tmOverhang == otm->tmOverhang, "tmOverhang %ld != %ld\n", tm->tmOverhang, otm->tmOverhang);
251 ok(tm->tmDigitizedAspectX == otm->tmDigitizedAspectX, "tmDigitizedAspectX %ld != %ld\n", tm->tmDigitizedAspectX, otm->tmDigitizedAspectX);
252 ok(tm->tmDigitizedAspectY == otm->tmDigitizedAspectY, "tmDigitizedAspectY %ld != %ld\n", tm->tmDigitizedAspectY, otm->tmDigitizedAspectY);
253 ok(tm->tmFirstChar == otm->tmFirstChar, "tmFirstChar %d != %d\n", tm->tmFirstChar, otm->tmFirstChar);
254 ok(tm->tmLastChar == otm->tmLastChar, "tmLastChar %d != %d\n", tm->tmLastChar, otm->tmLastChar);
255 ok(tm->tmDefaultChar == otm->tmDefaultChar, "tmDefaultChar %d != %d\n", tm->tmDefaultChar, otm->tmDefaultChar);
256 ok(tm->tmBreakChar == otm->tmBreakChar, "tmBreakChar %d != %d\n", tm->tmBreakChar, otm->tmBreakChar);
257 ok(tm->tmItalic == otm->tmItalic, "tmItalic %d != %d\n", tm->tmItalic, otm->tmItalic);
258 ok(tm->tmUnderlined == otm->tmUnderlined, "tmUnderlined %d != %d\n", tm->tmUnderlined, otm->tmUnderlined);
259 ok(tm->tmStruckOut == otm->tmStruckOut, "tmStruckOut %d != %d\n", tm->tmStruckOut, otm->tmStruckOut);
260 ok(tm->tmPitchAndFamily == otm->tmPitchAndFamily, "tmPitchAndFamily %d != %d\n", tm->tmPitchAndFamily, otm->tmPitchAndFamily);
261 ok(tm->tmCharSet == otm->tmCharSet, "tmCharSet %d != %d\n", tm->tmCharSet, otm->tmCharSet);
262}
BYTE tmStruckOut
Definition: wingdi.h:2824
BYTE tmPitchAndFamily
Definition: wingdi.h:2825
BYTE tmCharSet
Definition: wingdi.h:2826
LONG tmDescent
Definition: wingdi.h:2809
LONG tmDigitizedAspectX
Definition: wingdi.h:2816
BYTE tmFirstChar
Definition: wingdi.h:2818
LONG tmExternalLeading
Definition: wingdi.h:2811
LONG tmWeight
Definition: wingdi.h:2814
BYTE tmBreakChar
Definition: wingdi.h:2821
LONG tmInternalLeading
Definition: wingdi.h:2810
BYTE tmLastChar
Definition: wingdi.h:2819
BYTE tmUnderlined
Definition: wingdi.h:2823
LONG tmMaxCharWidth
Definition: wingdi.h:2813
LONG tmAveCharWidth
Definition: wingdi.h:2812
BYTE tmDefaultChar
Definition: wingdi.h:2820
LONG tmAscent
Definition: wingdi.h:2808
LONG tmOverhang
Definition: wingdi.h:2815
LONG tmHeight
Definition: wingdi.h:2807
BYTE tmItalic
Definition: wingdi.h:2822
LONG tmDigitizedAspectY
Definition: wingdi.h:2817

Referenced by test_font_metrics().

◆ create_fixed_pitch_font_proc()

static int CALLBACK create_fixed_pitch_font_proc ( const LOGFONTA lpelfe,
const TEXTMETRICA lpntme,
DWORD  FontType,
LPARAM  lParam 
)
static

Definition at line 4632 of file font.c.

4635{
4636 const NEWTEXTMETRICEXA *lpntmex = (const NEWTEXTMETRICEXA *)lpntme;
4637 CHARSETINFO csi;
4638 LOGFONTA lf = *lpelfe;
4639 HFONT hfont;
4640 DWORD found_subset;
4641
4642 /* skip bitmap, proportional or vertical font */
4643 if ((FontType & TRUETYPE_FONTTYPE) == 0 ||
4644 (lf.lfPitchAndFamily & 0xf) != FIXED_PITCH ||
4645 lf.lfFaceName[0] == '@')
4646 return 1;
4647
4648 /* skip linked font */
4649 if (!TranslateCharsetInfo((DWORD*)(INT_PTR)lpelfe->lfCharSet, &csi, TCI_SRCCHARSET) ||
4650 (lpntmex->ntmFontSig.fsCsb[0] & csi.fs.fsCsb[0]) == 0)
4651 return 1;
4652
4653 /* skip linked font, like SimSun-ExtB */
4654 switch (lpelfe->lfCharSet) {
4655 case SHIFTJIS_CHARSET:
4656 found_subset = lpntmex->ntmFontSig.fsUsb[1] & (1 << 17); /* Hiragana */
4657 break;
4658 case GB2312_CHARSET:
4660 found_subset = lpntmex->ntmFontSig.fsUsb[1] & (1 << 16); /* CJK Symbols And Punctuation */
4661 break;
4662 case HANGEUL_CHARSET:
4663 found_subset = lpntmex->ntmFontSig.fsUsb[1] & (1 << 24); /* Hangul Syllables */
4664 break;
4665 default:
4666 found_subset = lpntmex->ntmFontSig.fsUsb[0] & (1 << 0); /* Basic Latin */
4667 break;
4668 }
4669 if (!found_subset)
4670 return 1;
4671
4672 /* test with an odd height */
4673 lf.lfHeight = -19;
4674 lf.lfWidth = 0;
4676 if (hfont)
4677 {
4678 *(HFONT *)lParam = hfont;
4679 return 0;
4680 }
4681 return 1;
4682}
FONTSIGNATURE fs
Definition: wingdi.h:1994
DWORD fsUsb[4]
Definition: wingdi.h:1988
DWORD fsCsb[2]
Definition: wingdi.h:1989
FONTSIGNATURE ntmFontSig
Definition: wingdi.h:3118
int32_t INT_PTR
Definition: typedefs.h:64
#define FIXED_PITCH
Definition: wingdi.h:444
#define HANGEUL_CHARSET
Definition: wingdi.h:387
#define CHINESEBIG5_CHARSET
Definition: wingdi.h:390
#define TCI_SRCCHARSET
Definition: wingdi.h:961
#define SHIFTJIS_CHARSET
Definition: wingdi.h:386
BOOL WINAPI TranslateCharsetInfo(_Inout_ PDWORD, _Out_ LPCHARSETINFO, _In_ DWORD)
#define GB2312_CHARSET
Definition: wingdi.h:389

Referenced by test_GetGlyphOutline().

◆ create_font()

static HFONT create_font ( const char test,
const LOGFONTA lf 
)
static

Definition at line 192 of file font.c.

193{
194 HFONT hfont = CreateFontIndirectA(lf);
195 ok(hfont != 0, "%s: CreateFontIndirect failed\n", test);
196 if (hfont)
197 check_font(test, lf, hfont);
198 return hfont;
199}
static void check_font(const char *test, const LOGFONTA *lf, HFONT hfont)
Definition: font.c:166

Referenced by test_bitmap_font(), test_bitmap_font_metrics(), test_GetFontUnicodeRanges(), test_logfont(), test_orientation(), test_outline_font(), test_select_object(), and test_SetTextJustification().

◆ create_font_proc()

static int CALLBACK create_font_proc ( const LOGFONTA lpelfe,
const TEXTMETRICA lpntme,
DWORD  FontType,
LPARAM  lParam 
)
static

Definition at line 1059 of file font.c.

1062{
1063 if (FontType & TRUETYPE_FONTTYPE)
1064 {
1065 HFONT hfont;
1066
1067 hfont = CreateFontIndirectA(lpelfe);
1068 if (hfont)
1069 {
1070 *(HFONT *)lParam = hfont;
1071 return 0;
1072 }
1073 }
1074
1075 return 1;
1076}

Referenced by test_GetCharABCWidths(), and test_GetGlyphOutline().

◆ DWORD()

static DWORD ( WINAPI pGdiGetCodePage)
static

◆ enum_all_fonts_proc()

static INT CALLBACK enum_all_fonts_proc ( const LOGFONTA elf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lparam 
)
static

Definition at line 5365 of file font.c.

5366{
5367 int ret;
5368 LOGFONTA *lf;
5369
5370 if (type != TRUETYPE_FONTTYPE) return 1;
5371
5372 lf = (LOGFONTA *)lparam;
5373 ret = strcmp(lf->lfFaceName, elf->lfFaceName);
5374 if(ret == 0)
5375 {
5376 ok(ntm->tmWeight == elf->lfWeight, "expected %ld got %ld\n", ntm->tmWeight, elf->lfWeight);
5377 *lf = *elf;
5378 return 0;
5379 }
5380 return 1;
5381}
@ lparam
Definition: SystemMenu.c:31

Referenced by test_EnumFonts().

◆ enum_font_data_proc()

static INT CALLBACK enum_font_data_proc ( const LOGFONTA lf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 3170 of file font.c.

3171{
3172 struct enum_font_data *efd = (struct enum_font_data *)lParam;
3173
3174 if (type != TRUETYPE_FONTTYPE) return 1;
3175
3176 if (efd->total >= efd->size)
3177 {
3178 efd->size = max( (efd->total + 1) * 2, 256 );
3179 efd->lf = realloc( efd->lf, efd->size * sizeof(*efd->lf) );
3180 if (!efd->lf) return 0;
3181 }
3182 efd->lf[efd->total++] = *lf;
3183
3184 return 1;
3185}

Referenced by test_EnumFontFamiliesEx_default_charset(), and test_vertical_order().

◆ enum_fonts_proc()

static INT CALLBACK enum_fonts_proc ( const LOGFONTA elf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lparam 
)
static

Definition at line 5352 of file font.c.

5353{
5354 LOGFONTA *lf;
5355
5356 if (type != TRUETYPE_FONTTYPE) return 1;
5357
5358 ok(ntm->tmWeight == elf->lfWeight, "expected %ld got %ld\n", ntm->tmWeight, elf->lfWeight);
5359
5360 lf = (LOGFONTA *)lparam;
5361 *lf = *elf;
5362 return 0;
5363}

Referenced by test_EnumFonts().

◆ enum_fullname_data_proc()

static INT CALLBACK enum_fullname_data_proc ( const LOGFONTA lf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 3187 of file font.c.

3188{
3189 struct enum_fullname_data *efnd = (struct enum_fullname_data *)lParam;
3190
3191 if (type != TRUETYPE_FONTTYPE) return 1;
3192
3193 if (efnd->total >= efnd->size)
3194 {
3195 efnd->size = max( (efnd->total + 1) * 2, 256 );
3196 efnd->elf = realloc( efnd->elf, efnd->size * sizeof(*efnd->elf) );
3197 if (!efnd->elf) return 0;
3198 }
3199 efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
3200
3201 return 1;
3202}
ENUMLOGFONTA * elf
Definition: font.c:2846

Referenced by test_fullname2_helper(), test_lang_names(), and test_ttf_names().

◆ enum_fullname_data_proc_w()

static INT CALLBACK enum_fullname_data_proc_w ( const LOGFONTW lf,
const TEXTMETRICW ntm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 3204 of file font.c.

3205{
3206 struct enum_fullname_data_w *efnd = (struct enum_fullname_data_w *)lParam;
3207
3208 if (type != TRUETYPE_FONTTYPE) return 1;
3209
3210 if (efnd->total >= efnd->size)
3211 {
3212 efnd->size = max( (efnd->total + 1) * 2, 256 );
3213 efnd->elf = realloc( efnd->elf, efnd->size * sizeof(*efnd->elf) );
3214 if (!efnd->elf) return 0;
3215 }
3216 efnd->elf[efnd->total++] = *(ENUMLOGFONTW *)lf;
3217
3218 return 1;
3219}
ENUMLOGFONTW * elf
Definition: font.c:2852

Referenced by test_lang_names().

◆ enum_ms_shell_dlg2_proc()

static INT CALLBACK enum_ms_shell_dlg2_proc ( const LOGFONTA lf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 5477 of file font.c.

5478{
5479 struct enum_fullname_data *efnd = (struct enum_fullname_data *)lParam;
5480
5481 if (winetest_debug > 2)
5482 trace("enumed font \"%s\", charset %d, height %ld, weight %ld, italic %d\n",
5483 lf->lfFaceName, lf->lfCharSet, lf->lfHeight, lf->lfWeight, lf->lfItalic);
5484
5485 if (type != TRUETYPE_FONTTYPE) return 1;
5486 if (strcmp(lf->lfFaceName, "MS Shell Dlg 2") != 0) return 1;
5487
5488 if (efnd->total >= efnd->size)
5489 {
5490 efnd->size = max( (efnd->total + 1) * 2, 256 );
5491 efnd->elf = realloc( efnd->elf, efnd->size * sizeof(*efnd->elf) );
5492 if (!efnd->elf) return 0;
5493 }
5494 efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
5495 return 0;
5496}
#define trace
Definition: atltest.h:70
int winetest_debug

Referenced by test_EnumFonts_subst().

◆ enum_ms_shell_dlg_proc()

static INT CALLBACK enum_ms_shell_dlg_proc ( const LOGFONTA lf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 5456 of file font.c.

5457{
5458 struct enum_fullname_data *efnd = (struct enum_fullname_data *)lParam;
5459
5460 if (winetest_debug > 2)
5461 trace("enumed font \"%s\", charset %d, height %ld, weight %ld, italic %d\n",
5462 lf->lfFaceName, lf->lfCharSet, lf->lfHeight, lf->lfWeight, lf->lfItalic);
5463
5464 if (type != TRUETYPE_FONTTYPE) return 1;
5465 if (strcmp(lf->lfFaceName, "MS Shell Dlg") != 0) return 1;
5466
5467 if (efnd->total >= efnd->size)
5468 {
5469 efnd->size = max( (efnd->total + 1) * 2, 256 );
5470 efnd->elf = realloc( efnd->elf, efnd->size * sizeof(*efnd->elf) );
5471 if (!efnd->elf) return 0;
5472 }
5473 efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
5474 return 0;
5475}

Referenced by test_EnumFonts_subst().

◆ enum_multi_charset_font_proc()

static INT CALLBACK enum_multi_charset_font_proc ( const LOGFONTA lf,
const TEXTMETRICA tm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 3149 of file font.c.

3150{
3151 const NEWTEXTMETRICEXA *ntm = (const NEWTEXTMETRICEXA *)tm;
3153 const DWORD valid_bits = 0x003f01ff;
3154 CHARSETINFO csi;
3155 DWORD fs;
3156
3157 if (type != TRUETYPE_FONTTYPE) return TRUE;
3158
3159 if (TranslateCharsetInfo(ULongToPtr(target->lfCharSet), &csi, TCI_SRCCHARSET)) {
3160 fs = ntm->ntmFontSig.fsCsb[0] & valid_bits;
3161 if ((fs & csi.fs.fsCsb[0]) && (fs & ~csi.fs.fsCsb[0]) && (fs & FS_LATIN1)) {
3162 *target = *lf;
3163 return FALSE;
3164 }
3165 }
3166
3167 return TRUE;
3168}
#define ULongToPtr(ul)
Definition: basetsd.h:86
#define TRUE
Definition: types.h:120
#define fs
Definition: i386-dis.c:444
Definition: ffs.h:70
Definition: tools.h:99
#define FS_LATIN1
Definition: wingdi.h:560

Referenced by test_EnumFontFamiliesEx_default_charset().

◆ enum_truetype_font_proc()

static INT CALLBACK enum_truetype_font_proc ( const LOGFONTA lf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 4090 of file font.c.

4091{
4092 INT *enumed = (INT *)lParam;
4093
4094 if (type == TRUETYPE_FONTTYPE)
4095 {
4096 (*enumed)++;
4097 test_text_metrics(lf, (const NEWTEXTMETRICA *)ntm);
4098 }
4099 return 1;
4100}
static void test_text_metrics(const LOGFONTA *lf, const NEWTEXTMETRICA *ntm)
Definition: font.c:3853

Referenced by test_GetTextMetrics().

◆ enum_with_magic_retval_proc()

static INT CALLBACK enum_with_magic_retval_proc ( const LOGFONTA elf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lparam 
)
static

Definition at line 5383 of file font.c.

5384{
5385 return lparam;
5386}

Referenced by test_EnumFonts().

◆ expect_ff()

static void expect_ff ( const TEXTMETRICA tmA,
const TT_OS2_V4 os2,
WORD  family,
const char name 
)
static

Definition at line 3438 of file font.c.

3439{
3440 ok((tmA->tmPitchAndFamily & 0xf0) == family ||
3442 "%s: expected family %02x got %02x. panose %d-%d-%d-%d-...\n",
3443 name, family, tmA->tmPitchAndFamily, os2->panose.bFamilyType, os2->panose.bSerifStyle,
3444 os2->panose.bWeight, os2->panose.bProportion);
3445}
#define broken(x)
Definition: atltest.h:178
LANGID WINAPI GetSystemDefaultLangID(void)
Definition: locale.c:1199
#define LANG_ENGLISH
Definition: nls.h:52
#define PRIMARYLANGID(l)
Definition: nls.h:16
PANOSE panose
Definition: font.c:3352
BYTE bSerifStyle
Definition: wingdi.h:2316
BYTE bProportion
Definition: wingdi.h:2318
BYTE bWeight
Definition: wingdi.h:2317
BYTE bFamilyType
Definition: wingdi.h:2315

Referenced by test_text_metrics().

◆ find_font_proc()

static INT CALLBACK find_font_proc ( const LOGFONTA elf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 690 of file font.c.

691{
692 LOGFONTA *lf = (LOGFONTA *)lParam;
693
694 if (elf->lfHeight == lf->lfHeight && !strcmp(elf->lfFaceName, lf->lfFaceName))
695 {
696 *lf = *elf;
697 return 0; /* stop enumeration */
698 }
699 return 1; /* continue enumeration */
700}

Referenced by test_bitmap_font_metrics().

◆ find_ttf_table()

static void * find_ttf_table ( void ttf,
DWORD  size,
DWORD  tag 
)
static

Definition at line 1948 of file font.c.

1949{
1950 WORD i, num_tables = GET_BE_WORD(*((WORD *)ttf + 2));
1951 DWORD *table = (DWORD *)ttf + 3;
1952
1953 for (i = 0; i < num_tables; i++)
1954 {
1955 if (table[0] == tag)
1956 return (BYTE *)ttf + GET_BE_DWORD(table[2]);
1957 table += 4;
1958 }
1959 return NULL;
1960}
#define GET_BE_DWORD(x)
Definition: font.c:110
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: ecma_167.h:138

Referenced by test_height_selection_vdmx().

◆ font_enum_proc()

static INT CALLBACK font_enum_proc ( const LOGFONTA elf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 228 of file font.c.

229{
230 if (type & RASTER_FONTTYPE)
231 {
232 LOGFONTA *lf = (LOGFONTA *)lParam;
233 *lf = *elf;
234 return 0; /* stop enumeration */
235 }
236
237 return 1; /* continue enumeration */
238}
#define RASTER_FONTTYPE
Definition: wingdi.h:1107

Referenced by gdi_get_font_metrics(), and test_bitmap_font().

◆ free_font()

static void free_font ( void font)
static

Definition at line 1539 of file font.c.

1540{
1542}
#define UnmapViewOfFile
Definition: compat.h:746
Definition: mk_font.cpp:20

Referenced by test_AddFontMemResource(), and test_GetGlyphIndices().

◆ get_char_width_proc()

static int CALLBACK get_char_width_proc ( const LOGFONTA lf,
const TEXTMETRICA tm,
DWORD  type,
LPARAM  ctx 
)
static

Definition at line 7553 of file font.c.

7555{
7556 HFONT font = CreateFontIndirectA(lf);
7557 HDC dc = GetDC(NULL);
7558 const char c = 'm';
7559 ABCFLOAT abcf;
7560 int i, i32;
7561 BOOL ret;
7562 float f;
7563 ABC abc;
7564
7565#ifdef __REACTOS__
7566 if (!strcmp(lf->lfFaceName, "Segoe UI Emoji ")) // Fails on Vista x64 testbot
7567 {
7568 win_skip("broken font: %s\n", lf->lfFaceName);
7569 return 1;
7570 }
7571#endif
7572
7574
7575 ret = GetCharWidthFloatA(dc, c, c, &f);
7576 ok(ret, "%s: GetCharWidthFloat() failed\n", lf->lfFaceName);
7577 ret = GetCharWidth32A(dc, c, c, &i32);
7578 ok(ret, "%s: GetCharWidth32A() failed\n", lf->lfFaceName);
7579 ret = GetCharWidthA(dc, c, c, &i);
7580 ok(ret, "%s: GetCharWidthA() failed\n", lf->lfFaceName);
7581 ok(i == i32, "%s: mismatched widths %d/%d\n", lf->lfFaceName, i, i32);
7582 ok((float)i / 16.0f == f, "%s: mismatched widths %d/%.8e\n", lf->lfFaceName, i, f);
7583
7584 ret = GetCharABCWidthsFloatA(dc, c, c, &abcf);
7585 ok(ret, "%s: GetCharABCWidths() failed\n", lf->lfFaceName);
7586 if (!strcmp(lf->lfFaceName, "Noto Color Emoji"))
7587 skip("broken Noto Color Emoji font");
7588 else if (GetCharABCWidthsA(dc, c, c, &abc))
7589 ok((float)abc.abcB == abcf.abcfB, "%s: mismatched widths %d/%.8e\n", lf->lfFaceName, abc.abcB, abcf.abcfB);
7590
7591 ReleaseDC(NULL, dc);
7593 return 1;
7594}
#define skip(...)
Definition: atltest.h:64
HDC dc
Definition: cylfrac.c:34
const GLubyte * c
Definition: glext.h:8905
GLfloat f
Definition: glext.h:7540
#define f
Definition: ke_i.h:83
#define win_skip
Definition: minitest.h:67
BOOL WINAPI GetCharABCWidthsFloatA(_In_ HDC hdc, _In_ UINT iFirst, _In_ UINT iLast, _Out_writes_(iLast+1 - iFirst) LPABCFLOAT lpABC)
BOOL WINAPI GetCharABCWidthsA(_In_ HDC hdc, _In_ UINT wFirst, _In_ UINT wLast, _Out_writes_(wLast - wFirst+1) LPABC lpABC)
BOOL WINAPI GetCharWidthFloatA(_In_ HDC hdc, _In_ UINT iFirst, _In_ UINT iLast, _Out_writes_(iLast+1 - iFirst) PFLOAT lpBuffer)
BOOL WINAPI GetCharWidth32A(_In_ HDC hdc, _In_ UINT iFirst, _In_ UINT iLast, _Out_writes_(iLast+1 - iFirst) LPINT lpBuffer)
BOOL WINAPI GetCharWidthA(_In_ HDC hdc, _In_ UINT iFirst, _In_ UINT iLast, _Out_writes_(iLast+1 - iFirst) LPINT lpBuffer)

Referenced by test_char_width().

◆ get_charset_stats()

static void get_charset_stats ( struct enum_font_data efd,
int ansi_charset,
int symbol_charset,
int russian_charset 
)
static

Definition at line 2905 of file font.c.

2908{
2909 int i;
2910
2911 *ansi_charset = 0;
2912 *symbol_charset = 0;
2913 *russian_charset = 0;
2914
2915 for (i = 0; i < efd->total; i++)
2916 {
2917 switch (efd->lf[i].lfCharSet)
2918 {
2919 case ANSI_CHARSET:
2920 (*ansi_charset)++;
2921 break;
2922 case SYMBOL_CHARSET:
2923 (*symbol_charset)++;
2924 break;
2925 case RUSSIAN_CHARSET:
2926 (*russian_charset)++;
2927 break;
2928 }
2929 }
2930}
#define RUSSIAN_CHARSET
Definition: wingdi.h:396
#define ANSI_CHARSET
Definition: wingdi.h:383
#define SYMBOL_CHARSET
Definition: wingdi.h:385

Referenced by test_EnumFontFamilies().

◆ get_charset_statsW()

static void get_charset_statsW ( struct enum_font_dataW efd,
int ansi_charset,
int symbol_charset,
int russian_charset 
)
static

Definition at line 2932 of file font.c.

2935{
2936 int i;
2937
2938 *ansi_charset = 0;
2939 *symbol_charset = 0;
2940 *russian_charset = 0;
2941
2942 for (i = 0; i < efd->total; i++)
2943 {
2944 switch (efd->lf[i].lfCharSet)
2945 {
2946 case ANSI_CHARSET:
2947 (*ansi_charset)++;
2948 break;
2949 case SYMBOL_CHARSET:
2950 (*symbol_charset)++;
2951 break;
2952 case RUSSIAN_CHARSET:
2953 (*russian_charset)++;
2954 break;
2955 }
2956 }
2957}
BYTE lfCharSet
Definition: dimm.idl:67

Referenced by test_EnumFontFamilies().

◆ get_cmap()

static void * get_cmap ( cmap_header header,
USHORT  plat_id,
USHORT  enc_id 
)
static

Definition at line 3498 of file font.c.

3499{
3500 USHORT i;
3502
3503 for(i = 0; i < GET_BE_WORD(header->num_tables); i++)
3504 {
3505 if(GET_BE_WORD(record->plat_id) == plat_id && GET_BE_WORD(record->enc_id) == enc_id)
3506 return (BYTE *)header + GET_BE_DWORD(record->offset);
3507 record++;
3508 }
3509 return NULL;
3510}

Referenced by get_first_last_from_cmap().

◆ get_first_last_from_cmap()

static BOOL get_first_last_from_cmap ( HDC  hdc,
DWORD first,
DWORD last,
cmap_type cmap_type 
)
static

Definition at line 3519 of file font.c.

3520{
3521 LONG size, ret;
3523 void *cmap;
3524 BOOL r = FALSE;
3525 WORD format;
3526
3527 size = GetFontData(hdc, MS_CMAP_TAG, 0, NULL, 0);
3528 ok(size != GDI_ERROR, "no cmap table found\n");
3529 if(size == GDI_ERROR) return FALSE;
3530
3531 header = malloc(size);
3533 ok(ret == size, "GetFontData should return %lu not %lu\n", size, ret);
3534 ok(GET_BE_WORD(header->version) == 0, "got cmap version %d\n", GET_BE_WORD(header->version));
3535
3536 cmap = get_cmap(header, 3, 1);
3537 if(cmap)
3539 else
3540 {
3541 cmap = get_cmap(header, 3, 0);
3542 if(cmap) *cmap_type = cmap_ms_symbol;
3543 }
3544 if(!cmap)
3545 {
3547 goto end;
3548 }
3549
3550 format = GET_BE_WORD(*(WORD *)cmap);
3551 switch(format)
3552 {
3553 case 0:
3555 break;
3556 case 4:
3558 break;
3559 default:
3560 skip("unhandled cmap format %d\n", format);
3561 break;
3562 }
3563
3564end:
3565 free(header);
3566 return r;
3567}
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
const GLint * first
Definition: glext.h:5794
#define MS_CMAP_TAG
Definition: font.c:66
static void * get_cmap(cmap_header *header, USHORT plat_id, USHORT enc_id)
Definition: font.c:3498
static BOOL get_first_last_from_cmap4(void *ptr, DWORD *first, DWORD *last, DWORD limit)
Definition: font.c:3473
static BOOL get_first_last_from_cmap0(void *ptr, DWORD *first, DWORD *last)
Definition: font.c:3447
static const LARGE_INTEGER *static const HANDLE const LARGE_INTEGER *static PSLIST_ENTRY PSLIST_ENTRY last
Definition: sync.c:64
long LONG
Definition: pedump.c:60
Definition: format.c:58

Referenced by test_text_metrics().

◆ get_first_last_from_cmap0()

static BOOL get_first_last_from_cmap0 ( void ptr,
DWORD first,
DWORD last 
)
static

Definition at line 3447 of file font.c.

3448{
3449 int i;
3451
3452 *first = 256;
3453
3454 for(i = 0; i < 256; i++)
3455 {
3456 if(cmap->glyph_ids[i] == 0) continue;
3457 *last = i;
3458 if(*first == 256) *first = i;
3459 }
3460 if(*first == 256) return FALSE;
3461 return TRUE;
3462}
static PVOID ptr
Definition: dispmode.c:27
BYTE glyph_ids[256]
Definition: font.c:3406

Referenced by get_first_last_from_cmap().

◆ get_first_last_from_cmap4()

static BOOL get_first_last_from_cmap4 ( void ptr,
DWORD first,
DWORD last,
DWORD  limit 
)
static

Definition at line 3473 of file font.c.

3474{
3475 int i;
3477 USHORT seg_count = GET_BE_WORD(cmap->seg_countx2) / 2;
3478
3479 *first = 0x10000;
3480
3481 for(i = 0; i < seg_count; i++)
3482 {
3484
3485 get_seg4(cmap, i, &seg);
3486
3487 if(seg.start_count > 0xfffe) break;
3488
3489 if(*first == 0x10000) *first = seg.start_count;
3490
3491 *last = min(seg.end_count, 0xfffe);
3492 }
3493
3494 if(*first == 0x10000) return FALSE;
3495 return TRUE;
3496}
static void get_seg4(cmap_format_4 *cmap, USHORT seg_num, cmap_format_4_seg *seg)
Definition: font.c:3464
#define min(a, b)
Definition: monoChain.cc:55
USHORT start_count
Definition: font.c:3433
USHORT end_count
Definition: font.c:3432
USHORT seg_countx2
Definition: font.c:3415

Referenced by get_first_last_from_cmap().

◆ get_font_dpi()

static int get_font_dpi ( const LOGFONTA lf,
int height 
)
static

Definition at line 6360 of file font.c.

6361{
6363 HFONT hfont;
6365 int ret;
6366
6368 ok(hfont != 0, "CreateFontIndirect failed\n");
6369
6372 ok(ret, "GetTextMetrics failed\n");
6373 ret = tm.tmDigitizedAspectX;
6374 if (height) *height = tm.tmHeight;
6375
6376 DeleteDC(hdc);
6378
6379 return ret;
6380}
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
BOOL WINAPI GetTextMetricsA(_In_ HDC, _Out_ LPTEXTMETRICA)
Definition: text.c:200
BOOL WINAPI DeleteDC(_In_ HDC)

Referenced by test_stock_fonts().

◆ get_font_fsselection()

static UINT get_font_fsselection ( LOGFONTA lf)
static

Definition at line 2154 of file font.c.

2155{
2156 OUTLINETEXTMETRICA *otm;
2157 HFONT hfont, hfont_old;
2158 DWORD ret, otm_size;
2159 UINT fsSelection;
2160 HDC hdc;
2161
2162 hdc = GetDC(0);
2164 ok(hfont != NULL, "failed to create a font\n");
2165
2166 hfont_old = SelectObject(hdc, hfont);
2167
2168 otm_size = GetOutlineTextMetricsA(hdc, 0, NULL);
2169 otm = malloc(otm_size);
2170 otm->otmSize = sizeof(*otm);
2171 ret = GetOutlineTextMetricsA(hdc, otm->otmSize, otm);
2172 ok(ret == otm->otmSize, "expected %u, got %lu, error %ld\n", otm->otmSize, ret, GetLastError());
2173 fsSelection = otm->otmfsSelection;
2174 free(otm);
2175 SelectObject(hdc, hfont_old);
2177 ReleaseDC(0, hdc);
2178
2179 return fsSelection;
2180}
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by test_GetOutlineTextMetrics().

◆ get_glyph_indices()

static BOOL get_glyph_indices ( INT  charset,
UINT  code_page,
WORD idx,
UINT  count,
BOOL  unicode 
)
static

Definition at line 2478 of file font.c.

2479{
2480 HDC hdc;
2481 LOGFONTA lf;
2482 HFONT hfont, hfont_old;
2483 CHARSETINFO csi;
2485 INT cs;
2486 DWORD i, ret;
2487 char name[64];
2488
2489 assert(count <= 128);
2490
2491 memset(&lf, 0, sizeof(lf));
2492
2493 lf.lfCharSet = charset;
2494 lf.lfHeight = 10;
2495 lstrcpyA(lf.lfFaceName, "Arial");
2496 SetLastError(0xdeadbeef);
2498 ok(hfont != 0, "CreateFontIndirectA error %lu\n", GetLastError());
2499
2500 hdc = GetDC(0);
2501 hfont_old = SelectObject(hdc, hfont);
2502
2503 cs = GetTextCharsetInfo(hdc, &fs, 0);
2504 ok(cs == charset, "expected %d, got %d\n", charset, cs);
2505
2506 SetLastError(0xdeadbeef);
2507 ret = GetTextFaceA(hdc, sizeof(name), name);
2508 ok(ret, "GetTextFaceA error %lu\n", GetLastError());
2509
2510 if (charset == SYMBOL_CHARSET)
2511 {
2512 ok(strcmp("Arial", name), "face name should NOT be Arial\n");
2513 ok(fs.fsCsb[0] & (1u << 31), "symbol encoding should be available\n");
2514 }
2515 else
2516 {
2517 ok(!strcmp("Arial", name), "face name should be Arial, not %s\n", name);
2518 ok(!(fs.fsCsb[0] & (1u << 31)), "symbol encoding should NOT be available\n");
2519 }
2520
2522 {
2523 trace("Can't find codepage for charset %d\n", cs);
2524 ReleaseDC(0, hdc);
2525 return FALSE;
2526 }
2527 ok(csi.ciACP == code_page, "expected %d, got %d\n", code_page, csi.ciACP);
2528
2529 if (pGdiGetCodePage != NULL && pGdiGetCodePage(hdc) != code_page)
2530 {
2531 skip("Font code page %ld, looking for code page %d\n",
2532 pGdiGetCodePage(hdc), code_page);
2533 ReleaseDC(0, hdc);
2534 return FALSE;
2535 }
2536
2537 if (unicode)
2538 {
2539 char ansi_buf[128];
2540 WCHAR unicode_buf[128];
2541
2542 for (i = 0; i < count; i++) ansi_buf[i] = (BYTE)(i + 128);
2543
2544 MultiByteToWideChar(code_page, 0, ansi_buf, count, unicode_buf, count);
2545
2546 SetLastError(0xdeadbeef);
2547 ret = GetGlyphIndicesW(hdc, unicode_buf, count, idx, 0);
2548 ok(ret == count, "GetGlyphIndicesW expected %d got %ld, error %lu\n",
2549 count, ret, GetLastError());
2550 }
2551 else
2552 {
2553 char ansi_buf[128];
2554
2555 for (i = 0; i < count; i++) ansi_buf[i] = (BYTE)(i + 128);
2556
2557 SetLastError(0xdeadbeef);
2558 ret = GetGlyphIndicesA(hdc, ansi_buf, count, idx, 0);
2559 ok(ret == count, "GetGlyphIndicesA expected %d got %ld, error %lu\n",
2560 count, ret, GetLastError());
2561 }
2562
2563 SelectObject(hdc, hfont_old);
2565
2566 ReleaseDC(0, hdc);
2567
2568 return TRUE;
2569}
CFF_Charset charset
Definition: cffcmap.c:137
_Out_opt_ UINT * code_page
#define SetLastError(x)
Definition: compat.h:752
#define MultiByteToWideChar
Definition: compat.h:110
#define assert(_expr)
Definition: assert.h:32
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define cs
Definition: i386-dis.c:442
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
int WINAPI GetTextCharsetInfo(_In_ HDC, _Out_opt_ LPFONTSIGNATURE, _In_ DWORD)
DWORD WINAPI GetGlyphIndicesA(_In_ HDC hdc, _In_reads_(c) LPCSTR lpstr, _In_ int c, _Out_writes_(c) LPWORD pgi, _In_ DWORD fl)

Referenced by test_font_charset().

◆ get_mac_code_page()

static WORD get_mac_code_page ( const sfnt_name name)
inlinestatic

Definition at line 3718 of file font.c.

3719{
3720 if (GET_BE_WORD(name->encoding_id) == TT_MAC_ID_SIMPLIFIED_CHINESE) return 10008; /* special case */
3721 return 10000 + GET_BE_WORD(name->encoding_id);
3722}
#define TT_MAC_ID_SIMPLIFIED_CHINESE
Definition: font.c:1183

◆ get_res_data()

static void * get_res_data ( const char fontname,
DWORD rsrc_size 
)
static

Definition at line 120 of file font.c.

121{
122 HRSRC rsrc;
123 void *rsrc_data;
124
126 if (!rsrc) return NULL;
127
128 rsrc_data = LockResource(LoadResource(GetModuleHandleA(NULL), rsrc));
129 if (!rsrc_data) return NULL;
130
131 *rsrc_size = SizeofResource(GetModuleHandleA(NULL), rsrc);
132 if (!*rsrc_size) return NULL;
133
134 return rsrc_data;
135}
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HRSRC WINAPI FindResourceA(HMODULE hModule, LPCSTR name, LPCSTR type)
Definition: res.c:155
DWORD WINAPI SizeofResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:568
LPVOID WINAPI LockResource(HGLOBAL handle)
Definition: res.c:550
HGLOBAL WINAPI LoadResource(HINSTANCE hModule, HRSRC hRsrc)
Definition: res.c:532
#define RT_RCDATA
Definition: pedump.c:372
const char * LPCSTR
Definition: typedefs.h:52

Referenced by test_height_selection_vdmx(), and write_ttf_file().

◆ get_seg4()

static void get_seg4 ( cmap_format_4 cmap,
USHORT  seg_num,
cmap_format_4_seg seg 
)
static

Definition at line 3464 of file font.c.

3465{
3466 USHORT segs = GET_BE_WORD(cmap->seg_countx2) / 2;
3467 seg->end_count = GET_BE_WORD(cmap->end_count[seg_num]);
3468 seg->start_count = GET_BE_WORD(cmap->end_count[segs + 1 + seg_num]);
3469 seg->id_delta = GET_BE_WORD(cmap->end_count[2 * segs + 1 + seg_num]);
3470 seg->id_range_offset = GET_BE_WORD(cmap->end_count[3 * segs + 1 + seg_num]);
3471}
USHORT id_delta
Definition: font.c:3434
USHORT id_range_offset
Definition: font.c:3435
USHORT end_count[1]
Definition: font.c:3420

Referenced by get_first_last_from_cmap4().

◆ get_ttf_nametable_entry()

static BOOL get_ttf_nametable_entry ( HDC  hdc,
WORD  name_id,
WCHAR out_buf,
SIZE_T  out_size,
LCID  language_id 
)
static

Definition at line 3771 of file font.c.

3772{
3773 struct sfnt_name_header
3774 {
3775 USHORT format;
3776 USHORT number_of_record;
3777 USHORT storage_offset;
3778 } *header;
3780 BOOL r = FALSE;
3782 LONG c, ret;
3783 WCHAR *name;
3784 BYTE *data;
3785 USHORT i;
3786 int res, best_lang = 0, best_index = -1;
3787
3788 size = GetFontData(hdc, MS_NAME_TAG, 0, NULL, 0);
3789 ok(size != GDI_ERROR, "no name table found\n");
3790 if(size == GDI_ERROR) return FALSE;
3791
3792 data = malloc(size);
3794 ok(ret == size, "GetFontData should return %lu not %lu\n", size, ret);
3795
3796 header = (void *)data;
3797 header->format = GET_BE_WORD(header->format);
3798 header->number_of_record = GET_BE_WORD(header->number_of_record);
3799 header->storage_offset = GET_BE_WORD(header->storage_offset);
3800 if (header->format != 0)
3801 {
3802 skip("got format %u\n", header->format);
3803 goto out;
3804 }
3805 if (header->number_of_record == 0 || sizeof(*header) + header->number_of_record * sizeof(*entry) > size)
3806 {
3807 skip("number records out of range: %d\n", header->number_of_record);
3808 goto out;
3809 }
3810 if (header->storage_offset >= size)
3811 {
3812 skip("storage_offset %u > size %lu\n", header->storage_offset, size);
3813 goto out;
3814 }
3815
3816 entry = (void *)&header[1];
3817 for (i = 0; i < header->number_of_record; i++)
3818 {
3819 if (GET_BE_WORD(entry[i].name_id) != name_id) continue;
3820 res = match_name_table_language( &entry[i], language_id);
3821 if (res > best_lang)
3822 {
3823 best_lang = res;
3824 best_index = i;
3825 }
3826 }
3827
3828 offset = header->storage_offset + GET_BE_WORD(entry[best_index].offset);
3829 length = GET_BE_WORD(entry[best_index].length);
3830 if (offset + length > size)
3831 {
3832 skip("entry %d is out of range\n", best_index);
3833 goto out;
3834 }
3835 if (length >= out_size)
3836 {
3837 skip("buffer too small for entry %d\n", best_index);
3838 goto out;
3839 }
3840
3841 name = (WCHAR *)(data + offset);
3842 for (c = 0; c < length / 2; c++)
3843 out_buf[c] = GET_BE_WORD(name[c]);
3844 out_buf[c] = 0;
3845
3846 r = TRUE;
3847
3848out:
3849 free(data);
3850 return r;
3851}
static int match_name_table_language(const tt_name_record *name, LANGID lang)
Definition: font.c:1351
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint res
Definition: glext.h:9613
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
uint32_t entry
Definition: isohybrid.c:63
#define c
Definition: ke_i.h:80
#define MS_NAME_TAG
Definition: font.c:67
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:72
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

Referenced by test_fullname(), and test_fullname2_helper().

◆ has_vertical_font_proc()

static INT CALLBACK has_vertical_font_proc ( const LOGFONTA lf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 6303 of file font.c.

6305{
6306 if (lf->lfFaceName[0] == '@') {
6307 return 0;
6308 }
6309 return 1;
6310}

Referenced by test_east_asian_font_selection().

◆ init()

static void init ( void  )
static

Definition at line 69 of file font.c.

70{
71 hgdi32 = GetModuleHandleA("gdi32.dll");
72
73 pGdiGetCharDimensions = (void *)GetProcAddress(hgdi32, "GdiGetCharDimensions");
74 pGdiGetCodePage = (void *) GetProcAddress(hgdi32,"GdiGetCodePage");
75 pGetCharWidthInfo = (void *)GetProcAddress(hgdi32, "GetCharWidthInfo");
76 pGdiRealizationInfo = (void *)GetProcAddress(hgdi32, "GdiRealizationInfo");
77 pGetFontRealizationInfo = (void *)GetProcAddress(hgdi32, "GetFontRealizationInfo");
78 pGetFontFileInfo = (void *)GetProcAddress(hgdi32, "GetFontFileInfo");
79 pGetFontFileData = (void *)GetProcAddress(hgdi32, "GetFontFileData");
80
82}
#define GetProcAddress(x, y)
Definition: compat.h:753
static HMODULE hgdi32
Definition: font.c:50
static WORD system_lang_id
Definition: font.c:52

Referenced by START_TEST().

◆ is_CJK()

static BOOL is_CJK ( void  )
static

Definition at line 702 of file font.c.

703{
705}
#define LANG_CHINESE
Definition: nls.h:42
#define LANG_JAPANESE
Definition: nls.h:76
#define LANG_KOREAN
Definition: nls.h:84

Referenced by test_bitmap_font_metrics().

◆ is_font_installed()

static BOOL is_font_installed ( const char name)
static

Definition at line 108 of file font.c.

109{
110 HDC hdc = GetDC(0);
111 BOOL ret = FALSE;
112
114 ret = TRUE;
115
116 ReleaseDC(0, hdc);
117 return ret;
118}
static INT CALLBACK is_font_installed_proc(const LOGFONTW *elf, const TEXTMETRICW *ntm, DWORD type, LPARAM lParam)
Definition: font.c:632
int WINAPI EnumFontFamiliesA(_In_ HDC, _In_opt_ LPCSTR, _In_ FONTENUMPROCA, _In_ LPARAM)

Referenced by test_EnumFonts_subst(), test_font_charset(), test_GdiGetCodePage(), test_GetCharacterPlacement_kerning(), test_GetGlyphIndices(), test_GetKerningPairs(), test_GetOutlineTextMetrics(), test_GetOutlineTextMetrics_subst(), test_GetTextFace(), test_nonexistent_font(), and test_SetTextJustification().

◆ is_font_installed_fullname()

static BOOL is_font_installed_fullname ( const char family,
const char fullname 
)
static

Definition at line 5570 of file font.c.

5571{
5572 HDC hdc = GetDC(0);
5573 BOOL ret = FALSE;
5574
5576 ret = TRUE;
5577
5578 ReleaseDC(0, hdc);
5579 return ret;
5580}
LONG_PTR LPARAM
Definition: minwindef.h:175
const char * fullname
Definition: shader.c:1766
static INT CALLBACK is_font_installed_fullname_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
Definition: font.c:5560

Referenced by test_fullname().

◆ is_font_installed_fullname_proc()

static INT CALLBACK is_font_installed_fullname_proc ( const LOGFONTA lf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 5560 of file font.c.

5561{
5562 const ENUMLOGFONTA *elf = (const ENUMLOGFONTA *)lf;
5563 const char *fullname = (const char *)lParam;
5564
5565 if (!strcmp((const char *)elf->elfFullName, fullname)) return 0;
5566
5567 return 1;
5568}
BYTE elfFullName[LF_FULLFACESIZE]
Definition: wingdi.h:3133

Referenced by is_font_installed_fullname().

◆ is_font_installed_proc()

static INT CALLBACK is_font_installed_proc ( const LOGFONTA elf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 103 of file font.c.

104{
105 return 0;
106}

◆ is_truetype_font_installed()

◆ is_truetype_font_installed_proc()

static INT CALLBACK is_truetype_font_installed_proc ( const LOGFONTA elf,
const TEXTMETRICA ntm,
DWORD  type,
LPARAM  lParam 
)
static

Definition at line 84 of file font.c.

85{
86 if (type != TRUETYPE_FONTTYPE) return 1;
87
88 return 0;
89}

Referenced by is_truetype_font_installed().

◆ load_font()

static void * load_font ( const char font_name,
DWORD font_size 
)
static

Definition at line 1544 of file font.c.

1545{
1546 char file_name[MAX_PATH];
1548 void *font;
1549
1550 if (font_name[1] == ':')
1551 strcpy(file_name, font_name);
1552 else
1553 {
1554 if (!GetWindowsDirectoryA(file_name, sizeof(file_name))) return NULL;
1555 strcat(file_name, "\\fonts\\");
1556 strcat(file_name, font_name);
1557 }
1558
1560 if (file == INVALID_HANDLE_VALUE) return NULL;
1561
1562 *font_size = GetFileSize(file, NULL);
1563
1565 if (!mapping)
1566 {
1568 return NULL;
1569 }
1570
1572
1575 return font;
1576}
#define CloseHandle
Definition: compat.h:739
#define PAGE_READONLY
Definition: compat.h:138
#define OPEN_EXISTING
Definition: compat.h:775
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define FILE_MAP_READ
Definition: compat.h:776
#define MapViewOfFile
Definition: compat.h:745
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
UINT WINAPI GetWindowsDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2256
HANDLE NTAPI CreateFileMappingA(IN HANDLE hFile, IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes, IN DWORD flProtect, IN DWORD dwMaximumSizeHigh, IN DWORD dwMaximumSizeLow, IN LPCSTR lpName)
Definition: filemap.c:23
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
static LPCWSTR file_name
Definition: protocol.c:147
Definition: fci.c:127

Referenced by test_AddFontMemResource(), and test_GetGlyphIndices().

◆ LONG()

static LONG ( WINAPI pGdiGetCharDimensions)
static

◆ long_enum_proc()

static INT CALLBACK long_enum_proc ( const LOGFONTA lf,
const TEXTMETRICA tm,
DWORD  type,
LPARAM  lparam 
)
static

Definition at line 7000 of file font.c.

7001{
7002 BOOL *found_font = (BOOL *)lparam;
7003 *found_font = TRUE;
7004 return 1;
7005}

Referenced by test_long_names().

◆ match_name_table_language()

static int match_name_table_language ( const sfnt_name name,
LANGID  lang 
)
static

Definition at line 3724 of file font.c.

3725{
3726 LANGID name_lang;
3727 int res = 0;
3728
3729 switch (GET_BE_WORD(name->platform_id))
3730 {
3732 res += 5; /* prefer the Microsoft name */
3733 switch (GET_BE_WORD(name->encoding_id))
3734 {
3736 case TT_MS_ID_SYMBOL_CS:
3737 name_lang = GET_BE_WORD(name->language_id);
3738 break;
3739 default:
3740 return 0;
3741 }
3742 break;
3744 if (!IsValidCodePage( get_mac_code_page( name ))) return 0;
3745 if (GET_BE_WORD(name->language_id) >= ARRAY_SIZE(mac_langid_table)) return 0;
3746 name_lang = mac_langid_table[GET_BE_WORD(name->language_id)];
3747 break;
3749 res += 2; /* prefer Unicode encodings */
3750 switch (GET_BE_WORD(name->encoding_id))
3751 {
3755 if (GET_BE_WORD(name->language_id) >= ARRAY_SIZE(mac_langid_table)) return 0;
3756 name_lang = mac_langid_table[GET_BE_WORD(name->language_id)];
3757 break;
3758 default:
3759 return 0;
3760 }
3761 break;
3762 default:
3763 return 0;
3764 }
3765 if (name_lang == lang) res += 30;
3766 else if (PRIMARYLANGID( name_lang ) == PRIMARYLANGID( lang )) res += 20;
3767 else if (name_lang == MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT )) res += 10;
3768 return res;
3769}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define TT_APPLE_ID_ISO_10646
Definition: font.c:1177
static WORD get_mac_code_page(const tt_name_record *name)
Definition: font.c:1344
#define TT_MS_ID_UNICODE_CS
Definition: font.c:1181
#define TT_PLATFORM_MICROSOFT
Definition: font.c:1174
#define TT_APPLE_ID_DEFAULT
Definition: font.c:1176
#define TT_APPLE_ID_UNICODE_2_0
Definition: font.c:1178
#define TT_PLATFORM_MACINTOSH
Definition: font.c:1173
#define TT_MS_ID_SYMBOL_CS
Definition: font.c:1180
#define TT_PLATFORM_APPLE_UNICODE
Definition: font.c:1172
static const LANGID mac_langid_table[]
Definition: font.c:1220
BOOL WINAPI IsValidCodePage(UINT codepage)
Definition: locale.c:2081
USHORT LANGID
Definition: mui.h:9
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_DEFAULT
Definition: nls.h:168
static const WCHAR lang[]
Definition: wbemdisp.c:287

◆ match_off_by_n()

static BOOL match_off_by_n ( int  a,
int  b,
unsigned int  n 
)
inlinestatic

Definition at line 34 of file font.c.

35{
36 return abs(a - b) <= n;
37}
#define abs(i)
Definition: fconv.c:206
GLdouble n
Definition: glext.h:7729
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204

◆ prepend_at()

static WCHAR * prepend_at ( WCHAR family)
static

Definition at line 5630 of file font.c.

5631{
5632 if (!family)
5633 return NULL;
5634
5635 memmove(family + 1, family, (lstrlenW(family) + 1) * sizeof(WCHAR));
5636 family[0] = '@';
5637 return family;
5638}
#define lstrlenW
Definition: compat.h:750
#define memmove(s1, s2, n)
Definition: mkisofs.h:881

Referenced by test_fullname2_helper().

◆ START_TEST()

START_TEST ( font  )

Definition at line 7848 of file font.c.

7849{
7850 static const char *test_names[] =
7851 {
7852 "AddFontMemResource",
7853 };
7854 char path_name[MAX_PATH];
7856 char **argv;
7857 int argc, i;
7858
7859 init();
7860
7862 if (argc >= 3)
7863 {
7864 if (!strcmp(argv[2], "AddFontMemResource"))
7866 return;
7867 }
7868
7870 test_logfont();
7873#ifdef __REACTOS__
7874 if (is_reactos())
7875 skip("FIXME: ReactOS does not support bitmap (raster) fonts at this time\n");
7876 else
7878#else
7880#endif
7898
7899 /* On Windows Arial has a lot of default charset aliases such as Arial Cyr,
7900 * I'd like to avoid them in this test.
7901 */
7902 test_EnumFontFamilies("Arial Black", ANSI_CHARSET);
7904 if (is_truetype_font_installed("Arial Black") &&
7905 (is_truetype_font_installed("Symbol") || is_truetype_font_installed("Wingdings")))
7906 {
7910 }
7911 else
7912 skip("Arial Black or Symbol/Wingdings is not installed\n");
7918 test_GetTextMetrics2("Tahoma", -11);
7919 test_GetTextMetrics2("Tahoma", -55);
7920 test_GetTextMetrics2("Tahoma", -110);
7921 test_GetTextMetrics2("Arial", -11);
7922 test_GetTextMetrics2("Arial", -55);
7923 test_GetTextMetrics2("Arial", -110);
7930 test_fullname();
7945
7946 /* These tests should be last test until RemoveFontResource
7947 * is properly implemented.
7948 */
7951
7953 for (i = 0; i < ARRAY_SIZE(test_names); ++i)
7954 {
7956
7957 memset(&startup, 0, sizeof(startup));
7958 startup.cb = sizeof(startup);
7959 sprintf(path_name, "%s font %s", argv[0], test_names[i]);
7961 "CreateProcess failed.\n");
7962 wait_child_process(info.hProcess);
7963 CloseHandle(info.hProcess);
7964 CloseHandle(info.hThread);
7965 }
7966}
static void startup(void)
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(const char *app_name, char *cmd_line, SECURITY_ATTRIBUTES *process_attr, SECURITY_ATTRIBUTES *thread_attr, BOOL inherit, DWORD flags, void *env, const char *cur_dir, STARTUPINFOA *startup_info, PROCESS_INFORMATION *info)
Definition: process.c:686
MonoAssembly int argc
Definition: metahost.c:107
static char * path_name(DOS_FILE *file)
Definition: check.c:208
#define sprintf
Definition: sprintf.c:45
static void test_GetGlyphOutline(void)
Definition: font.c:4684
static void test_GetCharacterPlacement_kerning(void)
Definition: font.c:7607
static void test_lang_names(void)
Definition: font.c:7120
static void test_nonexistent_font(void)
Definition: font.c:4133
static void test_GetTextFace(void)
Definition: font.c:4484
static void test_east_asian_font_selection(void)
Definition: font.c:6312
static void init(void)
Definition: font.c:69
static void test_GdiGetCharDimensions(void)
Definition: font.c:1021
static void test_GetTextMetrics(void)
Definition: font.c:4102
static void test_font_weight(void)
Definition: font.c:7793
static void test_GetGlyphIndices(void)
Definition: font.c:1578
static void test_GetCharWidthInfo(void)
Definition: font.c:7389
static void test_GetCharacterPlacement(void)
Definition: font.c:4994
static void test_font_charset(void)
Definition: font.c:2663
static void test_EnumFontFamilies(const char *font_name, INT font_charset)
Definition: font.c:2959
static void test_logfont(void)
Definition: font.c:201
static void test_select_object(void)
Definition: font.c:7707
static void test_orientation(void)
Definition: font.c:4575
static void test_GetOutlineTextMetrics_subst(void)
Definition: font.c:7733
static void test_max_height(void)
Definition: font.c:6503
static void test_fake_bold_font(void)
Definition: font.c:6700
static void test_CreateFontIndirect(void)
Definition: font.c:5049
static void test_GdiGetCodePage(void)
Definition: font.c:2709
static void test_GetFontUnicodeRanges(void)
Definition: font.c:2803
static void test_EnumFonts_subst(void)
Definition: font.c:5498
static void test_ttf_names(void)
Definition: font.c:7053
static void test_RealizationInfo(void)
Definition: font.c:4338
static void test_EnumFonts(void)
Definition: font.c:5388
static void test_TranslateCharsetInfo(void)
Definition: font.c:2571
static void test_AddFontMemResource(void)
Definition: font.c:5214
static void test_outline_font(void)
Definition: font.c:448
static void test_height_selection(void)
Definition: font.c:2129
static void test_CreateFontIndirectEx(void)
Definition: font.c:5080
static void test_GetCharWidthI(void)
Definition: font.c:6947
static void test_oemcharset(void)
Definition: font.c:4604
static void test_fullname2(void)
Definition: font.c:5752
static void test_GetOutlineTextMetrics(void)
Definition: font.c:2182
static void test_bitmap_font_metrics(void)
Definition: font.c:708
static void test_SetTextJustification(void)
Definition: font.c:2366
static void test_text_extents(void)
Definition: font.c:1399
static void test_stock_fonts(void)
Definition: font.c:6382
static void test_long_names(void)
Definition: font.c:7007
static void test_bitmap_font(void)
Definition: font.c:358
static void test_GetTextMetrics2(const char *fontname, int font_height)
Definition: font.c:4943
static void test_EnumFontFamiliesEx_default_charset(void)
Definition: font.c:3221
static void test_GetCharABCWidths(void)
Definition: font.c:1109
static void test_bitmap_font_glyph_index(void)
Definition: font.c:6819
static void test_vertical_order(void)
Definition: font.c:6566
static void test_fullname(void)
Definition: font.c:5582
static void test_CreateScalableFontResource(void)
Definition: font.c:5969
static void test_char_width(void)
Definition: font.c:7596
static void test_GetCharWidth32(void)
Definition: font.c:6602
static void test_vertical_font(void)
Definition: font.c:6250
static void test_GetKerningPairs(void)
Definition: font.c:1704
#define argv
Definition: mplay32.c:18
int winetest_get_mainargs(char ***pargv)
#define wait_child_process
Definition: test.h:159

◆ test_AddFontMemResource()

static void test_AddFontMemResource ( void  )
static

Definition at line 5214 of file font.c.

5215{
5216 char ttf_name[MAX_PATH];
5217 void *font;
5218 DWORD font_size, num_fonts;
5219 HANDLE ret;
5220 BOOL bRet;
5221
5222 SetLastError(0xdeadbeef);
5224 ok(!ret, "AddFontMemResourceEx should fail\n");
5226 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %lu\n",
5227 GetLastError());
5228
5229 SetLastError(0xdeadbeef);
5231 ok(!ret, "AddFontMemResourceEx should fail\n");
5233 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %lu\n",
5234 GetLastError());
5235
5236 SetLastError(0xdeadbeef);
5237 ret = AddFontMemResourceEx(NULL, 0, NULL, &num_fonts);
5238 ok(!ret, "AddFontMemResourceEx should fail\n");
5240 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %lu\n",
5241 GetLastError());
5242
5243 SetLastError(0xdeadbeef);
5244 ret = AddFontMemResourceEx(NULL, 10, NULL, &num_fonts);
5245 ok(!ret, "AddFontMemResourceEx should fail\n");
5247 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %lu\n",
5248 GetLastError());
5249
5250 /* Now with scalable font */
5251 bRet = write_ttf_file("wine_test.ttf", ttf_name);
5252 ok(bRet, "Failed to create test font file.\n");
5253
5254 font = load_font(ttf_name, &font_size);
5255 ok(font != NULL, "Failed to map font file.\n");
5256
5257 bRet = is_truetype_font_installed("wine_test");
5258 ok(!bRet, "Font wine_test should not be enumerated.\n");
5259
5260 num_fonts = 0;
5261 ret = AddFontMemResourceEx(font, font_size, NULL, &num_fonts);
5262 ok(ret != 0, "Failed to add resource, %ld.\n", GetLastError());
5263 ok(num_fonts == 1, "Unexpected number of fonts %lu.\n", num_fonts);
5264
5265 bRet = is_truetype_font_installed("wine_test");
5266 todo_wine
5267 ok(!bRet, "Font wine_test should not be enumerated.\n");
5268
5269 test_realization_info("wine_test", font_size, TRUE);
5270
5272 ok(bRet, "RemoveFontMemResourceEx error %ld\n", GetLastError());
5273
5274 free_font(font);
5275
5276 bRet = DeleteFileA(ttf_name);
5277 ok(bRet, "Failed to delete font file, %ld.\n", GetLastError());
5278
5279 font = load_font("sserife.fon", &font_size);
5280 if (!font)
5281 {
5282 skip("Unable to locate and load font sserife.fon\n");
5283 return;
5284 }
5285
5286 SetLastError(0xdeadbeef);
5288 ok(!ret, "AddFontMemResourceEx should fail\n");
5290 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %lu\n",
5291 GetLastError());
5292
5293 SetLastError(0xdeadbeef);
5295 ok(!ret, "AddFontMemResourceEx should fail\n");
5297 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %lu\n",
5298 GetLastError());
5299
5300 num_fonts = 0xdeadbeef;
5301 SetLastError(0xdeadbeef);
5302 ret = AddFontMemResourceEx(font, 0, NULL, &num_fonts);
5303 ok(!ret, "AddFontMemResourceEx should fail\n");
5305 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %lu\n",
5306 GetLastError());
5307 ok(num_fonts == 0xdeadbeef, "number of loaded fonts should be 0xdeadbeef\n");
5308
5309 num_fonts = 0xdeadbeef;
5310 SetLastError(0xdeadbeef);
5311 ret = AddFontMemResourceEx(font, 10, NULL, &num_fonts);
5312 ok(!ret, "AddFontMemResourceEx should fail\n");
5313 ok(GetLastError() == 0xdeadbeef,
5314 "Expected GetLastError() to return 0xdeadbeef, got %lu\n",
5315 GetLastError());
5316 ok(num_fonts == 0xdeadbeef, "number of loaded fonts should be 0xdeadbeef\n");
5317
5318 num_fonts = 0xdeadbeef;
5319 SetLastError(0xdeadbeef);
5320 ret = AddFontMemResourceEx(font, font_size, NULL, &num_fonts);
5321 ok(ret != 0, "AddFontMemResourceEx error %ld\n", GetLastError());
5322 ok(num_fonts != 0xdeadbeef, "number of loaded fonts should not be 0xdeadbeef\n");
5323 ok(num_fonts != 0, "number of loaded fonts should not be 0\n");
5324
5325 free_font(font);
5326
5327 SetLastError(0xdeadbeef);
5329 ok(bRet, "RemoveFontMemResourceEx error %ld\n", GetLastError());
5330
5331 /* test invalid pointer to number of loaded fonts */
5332 font = load_font("sserife.fon", &font_size);
5333 ok(font != NULL, "Unable to locate and load font sserife.fon\n");
5334
5335 SetLastError(0xdeadbeef);
5336 ret = AddFontMemResourceEx(font, font_size, NULL, (void *)0xdeadbeef);
5337 ok(!ret, "AddFontMemResourceEx should fail\n");
5338 ok(GetLastError() == 0xdeadbeef,
5339 "Expected GetLastError() to return 0xdeadbeef, got %lu\n",
5340 GetLastError());
5341
5342 SetLastError(0xdeadbeef);
5343 ret = AddFontMemResourceEx(font, font_size, NULL, NULL);
5344 ok(!ret, "AddFontMemResourceEx should fail\n");
5346 "Expected GetLastError() to return ERROR_INVALID_PARAMETER, got %lu\n",
5347 GetLastError());
5348
5349 free_font(font);
5350}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
#define todo_wine
Definition: minitest.h:80
static void * load_font(const char *font_name, DWORD *font_size)
Definition: font.c:1544
static BOOL write_ttf_file(const char *fontname, char *tmp_name)
Definition: font.c:155
static void free_font(void *font)
Definition: font.c:1539
static void test_realization_info(const char *name, DWORD size, BOOL is_memory_resource)
Definition: font.c:5105
BOOL WINAPI RemoveFontMemResourceEx(HANDLE fh)
Definition: font.c:2622
HANDLE WINAPI AddFontMemResourceEx(_In_reads_bytes_(cjSize) PVOID pvFileView, _In_ DWORD cjSize, _Reserved_ PVOID pvResrved, _In_ DWORD *pNumFonts)

Referenced by START_TEST().

◆ test_bitmap_font()

static void test_bitmap_font ( void  )
static

Definition at line 358 of file font.c.

359{
360 static const char test_str[11] = "Test String";
361 HDC hdc;
362 LOGFONTA bitmap_lf;
363 HFONT hfont, old_hfont;
364 TEXTMETRICA tm_orig;
365 SIZE size_orig;
366 INT ret, i, width_orig, height_orig, scale, lfWidth;
367
369
370 /* "System" has only 1 pixel size defined, otherwise the test breaks */
371 ret = EnumFontFamiliesA(hdc, "System", font_enum_proc, (LPARAM)&bitmap_lf);
372 if (ret)
373 {
374 ReleaseDC(0, hdc);
375 skip("no bitmap fonts were found, skipping the test\n");
376 return;
377 }
378
379 trace("found bitmap font %s, height %ld\n", bitmap_lf.lfFaceName, bitmap_lf.lfHeight);
380
381 height_orig = bitmap_lf.lfHeight;
382 lfWidth = bitmap_lf.lfWidth;
383
384 hfont = create_font("bitmap", &bitmap_lf);
385 old_hfont = SelectObject(hdc, hfont);
386 ok(GetTextMetricsA(hdc, &tm_orig), "GetTextMetricsA failed\n");
387 ok(GetTextExtentPoint32A(hdc, test_str, sizeof(test_str), &size_orig), "GetTextExtentPoint32A failed\n");
388 ok(GetCharWidthA(hdc, 'A', 'A', &width_orig), "GetCharWidthA failed\n");
389 SelectObject(hdc, old_hfont);
391
392 bitmap_lf.lfHeight = 0;
393 bitmap_lf.lfWidth = 4;
394 hfont = create_font("bitmap", &bitmap_lf);
395 old_hfont = SelectObject(hdc, hfont);
396 test_font_metrics("bitmap", hdc, hfont, 0, 4, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 1, 1);
397 SelectObject(hdc, old_hfont);
399
400 bitmap_lf.lfHeight = height_orig;
401 bitmap_lf.lfWidth = lfWidth;
402
403 /* test fractional scaling */
404 for (i = 1; i <= height_orig * 6; i++)
405 {
406 INT nearest_height;
407
408 bitmap_lf.lfHeight = i;
409 hfont = create_font("fractional", &bitmap_lf);
410 scale = (i + height_orig - 1) / height_orig;
411 nearest_height = scale * height_orig;
412 /* Only jump to the next height if the difference <= 25% original height */
413 if (scale > 2 && nearest_height - i > height_orig / 4) scale--;
414 /* The jump between unscaled and doubled is delayed by 1 in winnt+ but not in win9x,
415 so we'll not test this particular height. */
416 else if(scale == 2 && nearest_height - i == (height_orig / 4)) continue;
417 else if(scale == 2 && nearest_height - i > (height_orig / 4 - 1)) scale--;
418 old_hfont = SelectObject(hdc, hfont);
419 winetest_push_context("height %i", i);
420 test_font_metrics(NULL, hdc, hfont, bitmap_lf.lfHeight, 0, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 1, scale);
422 SelectObject(hdc, old_hfont);
424 }
425
426 /* test integer scaling 3x2 */
427 bitmap_lf.lfHeight = height_orig * 2;
428 bitmap_lf.lfWidth *= 3;
429 hfont = create_font("3x2", &bitmap_lf);
430 old_hfont = SelectObject(hdc, hfont);
431 test_font_metrics("bitmap 3x2", hdc, hfont, bitmap_lf.lfHeight, 0, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 2);
432 SelectObject(hdc, old_hfont);
434
435 /* test integer scaling 3x3 */
436 bitmap_lf.lfHeight = height_orig * 3;
437 bitmap_lf.lfWidth = 0;
438 hfont = create_font("3x3", &bitmap_lf);
439 old_hfont = SelectObject(hdc, hfont);
440 test_font_metrics("bitmap 3x3", hdc, hfont, bitmap_lf.lfHeight, 0, test_str, sizeof(test_str), &tm_orig, &size_orig, width_orig, 3, 3);
441 SelectObject(hdc, old_hfont);
443
444 DeleteDC(hdc);
445}
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
static HFONT create_font(const char *test, const LOGFONTA *lf)
Definition: font.c:192
static INT CALLBACK font_enum_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
Definition: font.c:228
static void test_font_metrics(void)
Definition: font.c:667
BOOL WINAPI GetTextExtentPoint32A(_In_ HDC hdc, _In_reads_(c) LPCSTR lpString, _In_ int c, _Out_ LPSIZE psizl)

Referenced by START_TEST().

◆ test_bitmap_font_glyph_index()

static void test_bitmap_font_glyph_index ( void  )
static

Definition at line 6819 of file font.c.

6820{
6821 const WCHAR text[] = L"#!/bin/sh";
6822 const struct {
6823 LPCSTR face;
6824 BYTE charset;
6825 } bitmap_font_list[] = {
6826 { "Courier", ANSI_CHARSET },
6827 { "Small Fonts", ANSI_CHARSET },
6828 { "Fixedsys", DEFAULT_CHARSET },
6829 { "System", DEFAULT_CHARSET }
6830 };
6831 HDC hdc;
6832 LOGFONTA lf;
6833 HFONT hFont;
6834 CHAR facename[LF_FACESIZE];
6835 BITMAPINFO bmi;
6836 HBITMAP hBmp[2];
6837 void *pixels[2];
6838 int i, j;
6839 DWORD ret;
6840 BITMAP bmp;
6842 CHARSETINFO ci;
6843 BYTE chr = '\xA9';
6844
6846 ok(hdc != NULL, "CreateCompatibleDC failed\n");
6847
6848 memset(&bmi, 0, sizeof(bmi));
6849 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
6850 bmi.bmiHeader.biBitCount = 32;
6851 bmi.bmiHeader.biPlanes = 1;
6852 bmi.bmiHeader.biWidth = 128;
6853 bmi.bmiHeader.biHeight = 32;
6855
6856 for (i = 0; i < ARRAY_SIZE(bitmap_font_list); i++) {
6857 memset(&lf, 0, sizeof(lf));
6858 lf.lfCharSet = bitmap_font_list[i].charset;
6859 strcpy(lf.lfFaceName, bitmap_font_list[i].face);
6861 ok(hFont != NULL, "Can't create font (%s:%d)\n", lf.lfFaceName, lf.lfCharSet);
6864 ok(ret, "GetTextMetric failed\n");
6865 ret = GetTextFaceA(hdc, sizeof(facename), facename);
6866 ok(ret, "GetTextFace failed\n");
6867 if (tm.tmPitchAndFamily & TMPF_TRUETYPE) {
6868 skip("TrueType font (%s) was selected for \"%s\"\n", facename, bitmap_font_list[i].face);
6869 continue;
6870 }
6871 if (lstrcmpiA(facename, lf.lfFaceName) != 0) {
6872 skip("expected %s, got %s\n", lf.lfFaceName, facename);
6873 continue;
6874 }
6875
6876 for (j = 0; j < 2; j++) {
6877 HBITMAP hBmpPrev;
6878 hBmp[j] = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &pixels[j], NULL, 0);
6879 ok(hBmp[j] != NULL, "Can't create DIB\n");
6880 hBmpPrev = SelectObject(hdc, hBmp[j]);
6881 switch (j) {
6882 case 0:
6883 ret = ExtTextOutW(hdc, 0, 0, 0, NULL, text, lstrlenW(text), NULL);
6884 break;
6885 case 1:
6886 {
6887 int len = lstrlenW(text);
6888 WORD *indices = malloc(len * sizeof(WORD));
6890 ok(ret, "GetGlyphIndices failed\n");
6891 ok(memcmp(indices, text, sizeof(WORD) * len) == 0,
6892 "Glyph indices and text are different for %s:%d\n", lf.lfFaceName, tm.tmCharSet);
6893 ret = ExtTextOutW(hdc, 0, 0, ETO_GLYPH_INDEX, NULL, indices, len, NULL);
6894 free(indices);
6895 break;
6896 }
6897 }
6898 ok(ret, "ExtTextOutW failed\n");
6899 SelectObject(hdc, hBmpPrev);
6900 }
6901
6902 GetObjectA(hBmp[0], sizeof(bmp), &bmp);
6904 "Images are different (%s:%d)\n", lf.lfFaceName, tm.tmCharSet);
6905
6907 if (!ret) {
6908 skip("Can't get charset info for (%s:%d)\n", lf.lfFaceName, tm.tmCharSet);
6909 goto next;
6910 }
6911 if (IsDBCSLeadByteEx(ci.ciACP, chr)) {
6912 skip("High-ascii character is not defined in codepage %d\n", ci.ciACP);
6913 goto next;
6914 }
6915
6916 for (j = 0; j < 2; j++) {
6917 HBITMAP hBmpPrev;
6918 WORD code;
6919 hBmpPrev = SelectObject(hdc, hBmp[j]);
6920 switch (j) {
6921 case 0:
6922 ret = ExtTextOutA(hdc, 100, 0, 0, NULL, (LPCSTR)&chr, 1, NULL);
6923 break;
6924 case 1:
6925 ret = GetGlyphIndicesA(hdc, (LPCSTR)&chr, 1, &code, 0);
6926 ok(ret, "GetGlyphIndices failed\n");
6927 ok(code == chr, "expected %02x, got %02x (%s:%d)\n", chr, code, lf.lfFaceName, tm.tmCharSet);
6928 ret = ExtTextOutA(hdc, 100, 0, ETO_GLYPH_INDEX, NULL, (LPCSTR)&code, 1, NULL);
6929 break;
6930 }
6931 ok(ret, "ExtTextOutA failed\n");
6932 SelectObject(hdc, hBmpPrev);
6933 }
6934
6936 "Images are different (%s:%d)\n", lf.lfFaceName, tm.tmCharSet);
6937 next:
6938 for (j = 0; j < 2; j++)
6939 DeleteObject(hBmp[j]);
6942 }
6943
6944 DeleteDC(hdc);
6945}
HFONT hFont
Definition: main.c:53
#define LF_FACESIZE
Definition: dimm.idl:39
WORD face[3]
Definition: mesh.c:4747
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4133
BOOL WINAPI IsDBCSLeadByteEx(UINT codepage, BYTE testchar)
Definition: locale.c:2106
const WCHAR * text
Definition: package.c:1794
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
#define L(x)
Definition: resources.c:13
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl.h:1546
GLuint GLuint GLsizei GLenum const GLvoid * indices
Definition: gl.h:1545
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
BITMAP bmp
Definition: alphablend.c:62
static HBITMAP
Definition: button.c:44
char CHAR
Definition: pedump.c:57
static unsigned __int64 next
Definition: rand_nt.c:6
USHORT biBitCount
Definition: precomp.h:34
ULONG biCompression
Definition: precomp.h:35
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1922
LONG bmHeight
Definition: wingdi.h:1869
LONG bmWidthBytes
Definition: wingdi.h:1870
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint32_t * LPDWORD
Definition: typedefs.h:59
#define BI_RGB
Definition: uefivid.c:46
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:245
#define DIB_RGB_COLORS
Definition: wingdi.h:367
#define TMPF_TRUETYPE
Definition: wingdi.h:1313
BOOL WINAPI ExtTextOutA(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
BOOL WINAPI ExtTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCWSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)

Referenced by START_TEST().

◆ test_bitmap_font_metrics()

static void test_bitmap_font_metrics ( void  )
static

Definition at line 708 of file font.c.

709{
710 static const WORD skip_rtl[] = {LANG_ARABIC, LANG_HEBREW, 0};
711 static const struct font_data
712 {
713 const char face_name[LF_FACESIZE];
715 int ave_char_width, max_char_width, dpi;
716 BYTE first_char, last_char, def_char, break_char;
717 DWORD ansi_bitfield;
718 const WORD *skip_lang_id;
719 int scaled_height;
720 } fd[] =
721 {
722 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 6, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, skip_rtl, 13 },
723 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 6, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 13 },
724 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 8, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, skip_rtl, 13 },
725 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 8, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 13 },
726 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 10, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, skip_rtl, 13 },
727 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 10, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 13 },
728 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 14, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, skip_rtl, 13 },
729 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 14, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 13 },
730 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 18, 13, 3, 3, 0, 7, 14, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, skip_rtl, 16 },
731 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 18, 13, 3, 3, 0, 7, 14, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 16 },
732
733 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 6, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, 0, 16 },
734 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 6, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 16 },
735 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 8, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, 0, 16 },
736 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 8, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 16 },
737 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 10, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, 0, 16 },
738 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 10, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 16 },
739 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 14, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, 0, 16 },
740 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 14, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 16 },
741 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 18, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, 0, 16 },
742 { "MS Sans Serif", FW_NORMAL, FH_SCALE | 18, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 16 },
743
744 { "MS Sans Serif", FW_NORMAL, 13, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2 },
745 { "MS Sans Serif", FW_NORMAL, 13, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC },
746 { "MS Sans Serif", FW_NORMAL, 16, 13, 3, 3, 0, 7, 14, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2 },
747 { "MS Sans Serif", FW_NORMAL, 16, 13, 3, 3, 0, 7, 14, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC },
748 { "MS Sans Serif", FW_NORMAL, 20, 16, 4, 4, 0, 8, 16, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 },
749 { "MS Sans Serif", FW_NORMAL, 20, 16, 4, 4, 0, 8, 18, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN2 },
750 { "MS Sans Serif", FW_NORMAL, 20, 16, 4, 4, 0, 8, 16, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC },
751 { "MS Sans Serif", FW_NORMAL, 24, 19, 5, 6, 0, 9, 19, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 },
752 { "MS Sans Serif", FW_NORMAL, 24, 19, 5, 6, 0, 9, 24, 96, 0x20, 0xff, 0x81, 0x40, FS_LATIN2 },
753 { "MS Sans Serif", FW_NORMAL, 24, 19, 5, 6, 0, 9, 20, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC },
754 { "MS Sans Serif", FW_NORMAL, 29, 23, 6, 5, 0, 12, 24, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 },
755 { "MS Sans Serif", FW_NORMAL, 29, 23, 6, 6, 0, 12, 24, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN2 },
756 { "MS Sans Serif", FW_NORMAL, 29, 23, 6, 5, 0, 12, 25, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC },
757 { "MS Sans Serif", FW_NORMAL, 37, 29, 8, 5, 0, 16, 32, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 },
758 { "MS Sans Serif", FW_NORMAL, 37, 29, 8, 5, 0, 16, 32, 96, 0x20, 0xff, 0x81, 0x40, FS_LATIN2 },
759 { "MS Sans Serif", FW_NORMAL, 37, 29, 8, 5, 0, 16, 32, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC },
760
761 { "MS Sans Serif", FW_NORMAL, 16, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2 },
762 { "MS Sans Serif", FW_NORMAL, 16, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC },
763 { "MS Sans Serif", FW_NORMAL, 20, 16, 4, 4, 0, 8, 18, 120, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2 },
764 { "MS Sans Serif", FW_NORMAL, 20, 16, 4, 4, 0, 8, 17, 120, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC },
765 { "MS Sans Serif", FW_NORMAL, 25, 20, 5, 5, 0, 10, 21, 120, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2 },
766 { "MS Sans Serif", FW_NORMAL, 25, 20, 5, 5, 0, 10, 21, 120, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC },
767 { "MS Sans Serif", FW_NORMAL, 29, 23, 6, 6, 0, 12, 24, 120, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2 },
768 { "MS Sans Serif", FW_NORMAL, 29, 23, 6, 5, 0, 12, 24, 120, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC },
769 { "MS Sans Serif", FW_NORMAL, 36, 29, 7, 6, 0, 15, 30, 120, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2 },
770 { "MS Sans Serif", FW_NORMAL, 36, 29, 7, 6, 0, 15, 30, 120, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC },
771 { "MS Sans Serif", FW_NORMAL, 46, 37, 9, 6, 0, 20, 40, 120, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2 },
772 { "MS Sans Serif", FW_NORMAL, 46, 37, 9, 6, 0, 20, 40, 120, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC },
773
774 { "MS Serif", FW_NORMAL, 10, 8, 2, 2, 0, 4, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 },
775 { "MS Serif", FW_NORMAL, 10, 8, 2, 2, 0, 5, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
776 { "MS Serif", FW_NORMAL, 11, 9, 2, 2, 0, 5, 9, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_CYRILLIC },
777 { "MS Serif", FW_NORMAL, 13, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 },
778 { "MS Serif", FW_NORMAL, 13, 11, 2, 2, 0, 5, 12, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC },
779 { "MS Serif", FW_NORMAL, 16, 13, 3, 3, 0, 6, 14, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 },
780 { "MS Serif", FW_NORMAL, 16, 13, 3, 3, 0, 6, 16, 96, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
781 { "MS Serif", FW_NORMAL, 19, 15, 4, 3, 0, 8, 18, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 },
782 { "MS Serif", FW_NORMAL, 19, 15, 4, 3, 0, 8, 19, 96, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
783 { "MS Serif", FW_NORMAL, 21, 16, 5, 3, 0, 9, 17, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 },
784 { "MS Serif", FW_NORMAL, 21, 16, 5, 3, 0, 9, 22, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 },
785 { "MS Serif", FW_NORMAL, 21, 16, 5, 3, 0, 9, 23, 96, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
786 { "MS Serif", FW_NORMAL, 27, 21, 6, 3, 0, 12, 23, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 },
787 { "MS Serif", FW_NORMAL, 27, 21, 6, 3, 0, 12, 26, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 },
788 { "MS Serif", FW_NORMAL, 27, 21, 6, 3, 0, 12, 27, 96, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
789 { "MS Serif", FW_NORMAL, 35, 27, 8, 3, 0, 16, 33, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 },
790 { "MS Serif", FW_NORMAL, 35, 27, 8, 3, 0, 16, 34, 96, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
791
792 { "MS Serif", FW_NORMAL, 16, 13, 3, 3, 0, 6, 14, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_CYRILLIC },
793 { "MS Serif", FW_NORMAL, 16, 13, 3, 3, 0, 6, 13, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 },
794 { "MS Serif", FW_NORMAL, 20, 16, 4, 4, 0, 8, 18, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_CYRILLIC },
795 { "MS Serif", FW_NORMAL, 20, 16, 4, 4, 0, 8, 15, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 },
796 { "MS Serif", FW_NORMAL, 23, 18, 5, 3, 0, 10, 21, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_CYRILLIC },
797 { "MS Serif", FW_NORMAL, 23, 18, 5, 3, 0, 10, 19, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 },
798 { "MS Serif", FW_NORMAL, 27, 21, 6, 4, 0, 12, 23, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 },
799 { "MS Serif", FW_MEDIUM, 27, 22, 5, 2, 0, 12, 30, 120, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
800 { "MS Serif", FW_NORMAL, 33, 26, 7, 3, 0, 14, 30, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 },
801 { "MS Serif", FW_MEDIUM, 32, 25, 7, 2, 0, 14, 32, 120, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
802 { "MS Serif", FW_NORMAL, 43, 34, 9, 3, 0, 19, 39, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_CYRILLIC },
803
804 { "Courier", FW_NORMAL, 13, 11, 2, 0, 0, 8, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_CYRILLIC },
805 { "Courier", FW_NORMAL, 16, 13, 3, 0, 0, 9, 9, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_CYRILLIC },
806 { "Courier", FW_NORMAL, 20, 16, 4, 0, 0, 12, 12, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_CYRILLIC },
807
808 { "Courier", FW_NORMAL, 16, 13, 3, 0, 0, 9, 9, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_CYRILLIC },
809 { "Courier", FW_NORMAL, 20, 16, 4, 0, 0, 12, 12, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_CYRILLIC },
810 { "Courier", FW_NORMAL, 25, 20, 5, 0, 0, 15, 15, 120, 0x20, 0xff, 0x40, 0x20, FS_LATIN1 | FS_LATIN2 | FS_CYRILLIC },
811
812 { "System", FW_BOLD, 16, 13, 3, 3, 0, 7, 14, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 },
813 { "System", FW_BOLD, 16, 13, 3, 3, 0, 7, 15, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC },
814 { "System", FW_NORMAL, 18, 16, 2, 0, 2, 8, 16, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN },
815
816 { "System", FW_BOLD, 20, 16, 4, 4, 0, 9, 14, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 },
817 { "System", FW_BOLD, 20, 16, 4, 4, 0, 9, 17, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC },
818
819 { "Small Fonts", FW_NORMAL, 3, 2, 1, 0, 0, 1, 2, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 },
820 { "Small Fonts", FW_NORMAL, 3, 2, 1, 0, 0, 1, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC },
821 { "Small Fonts", FW_NORMAL, 3, 2, 1, 0, 0, 2, 4, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN },
822 { "Small Fonts", FW_NORMAL, 5, 4, 1, 1, 0, 3, 4, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1, skip_rtl},
823 { "Small Fonts", FW_NORMAL, 5, 4, 1, 1, 0, 2, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC },
824 { "Small Fonts", FW_NORMAL, 5, 4, 1, 0, 0, 3, 6, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN },
825 { "Small Fonts", FW_NORMAL, 6, 5, 1, 1, 0, 3, 13, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1, skip_rtl},
826 { "Small Fonts", FW_NORMAL, 6, 5, 1, 1, 0, 3, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC },
827 { "Small Fonts", FW_NORMAL, 6, 5, 1, 1, 0, 3, 8, 96, 0x00, 0xff, 0x60, 0x00, FS_ARABIC },
828 { "Small Fonts", FW_NORMAL, 6, 5, 1, 0, 0, 4, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN },
829 { "Small Fonts", FW_NORMAL, 8, 7, 1, 1, 0, 4, 7, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1, skip_rtl},
830 { "Small Fonts", FW_NORMAL, 8, 7, 1, 1, 0, 4, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC },
831 { "Small Fonts", FW_NORMAL, 8, 7, 1, 1, 0, 4, 8, 96, 0x00, 0xff, 0x60, 0x00, FS_ARABIC },
832 { "Small Fonts", FW_NORMAL, 8, 7, 1, 0, 0, 5, 10, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN },
833 { "Small Fonts", FW_NORMAL, 10, 8, 2, 2, 0, 4, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2, skip_rtl},
834 { "Small Fonts", FW_NORMAL, 10, 8, 2, 2, 0, 5, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
835 { "Small Fonts", FW_NORMAL, 10, 8, 2, 2, 0, 4, 9, 96, 0x00, 0xff, 0x60, 0x00, FS_ARABIC },
836 { "Small Fonts", FW_NORMAL, 10, 8, 2, 0, 0, 6, 12, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN },
837 { "Small Fonts", FW_NORMAL, 11, 9, 2, 2, 0, 5, 9, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_CYRILLIC, skip_rtl},
838 { "Small Fonts", FW_NORMAL, 11, 9, 2, 2, 0, 4, 10, 96, 0x00, 0xff, 0x60, 0x00, FS_ARABIC },
839 { "Small Fonts", FW_NORMAL, 11, 9, 2, 0, 0, 7, 14, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN },
840
841 { "Small Fonts", FW_NORMAL, 3, 2, 1, 0, 0, 1, 2, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_JISJAPAN },
842 { "Small Fonts", FW_NORMAL, 3, 2, 1, 0, 0, 1, 8, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC },
843 { "Small Fonts", FW_NORMAL, 6, 5, 1, 1, 0, 3, 5, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_JISJAPAN },
844 { "Small Fonts", FW_NORMAL, 6, 5, 1, 1, 0, 3, 8, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC },
845 { "Small Fonts", FW_NORMAL, 8, 7, 1, 1, 0, 4, 7, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_JISJAPAN },
846 { "Small Fonts", FW_NORMAL, 8, 7, 1, 1, 0, 4, 8, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC },
847 { "Small Fonts", FW_NORMAL, 10, 8, 2, 2, 0, 5, 9, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_JISJAPAN },
848 { "Small Fonts", FW_NORMAL, 10, 8, 2, 2, 0, 5, 8, 120, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
849 { "Small Fonts", FW_NORMAL, 12, 10, 2, 2, 0, 5, 10, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_JISJAPAN },
850 { "Small Fonts", FW_NORMAL, 12, 10, 2, 2, 0, 6, 10, 120, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
851 { "Small Fonts", FW_NORMAL, 13, 11, 2, 2, 0, 6, 12, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_JISJAPAN },
852 { "Small Fonts", FW_NORMAL, 13, 11, 2, 2, 0, 6, 11, 120, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
853
854 { "Fixedsys", FW_NORMAL, 15, 12, 3, 3, 0, 8, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 },
855 { "Fixedsys", FW_NORMAL, 16, 12, 4, 3, 0, 8, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC },
856 { "FixedSys", FW_NORMAL, 18, 16, 2, 0, 0, 8, 16, 96, 0x20, 0xff, 0xa0, 0x20, FS_JISJAPAN },
857
858 { "Fixedsys", FW_NORMAL, 20, 16, 4, 2, 0, 10, 10, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_CYRILLIC }
859
860 /* FIXME: add "Terminal" */
861 };
862 static const int font_log_pixels[] = { 96, 120 };
863 HDC hdc;
864 LOGFONTA lf;
865 HFONT hfont, old_hfont;
867 INT ret, i, expected_cs, screen_log_pixels, diff, font_res;
868 char face_name[LF_FACESIZE];
869 CHARSETINFO csi;
870
871 trace("system language id %04x\n", system_lang_id);
872
873 expected_cs = GetACP();
874 if (!TranslateCharsetInfo(ULongToPtr(expected_cs), &csi, TCI_SRCCODEPAGE))
875 {
876 skip("TranslateCharsetInfo failed for code page %d\n", expected_cs);
877 return;
878 }
879 expected_cs = csi.ciCharset;
880 trace("ACP %d -> charset %d\n", GetACP(), expected_cs);
881
883 ok(hdc != NULL, "failed to create hdc\n");
884
885 trace("logpixelsX %d, logpixelsY %d\n", GetDeviceCaps(hdc, LOGPIXELSX),
887
888 screen_log_pixels = GetDeviceCaps(hdc, LOGPIXELSY);
889 diff = 32768;
890 font_res = 0;
891 for (i = 0; i < ARRAY_SIZE(font_log_pixels); i++)
892 {
893 int new_diff = abs(font_log_pixels[i] - screen_log_pixels);
894 if (new_diff < diff)
895 {
896 diff = new_diff;
897 font_res = font_log_pixels[i];
898 }
899 }
900 trace("best font resolution is %d\n", font_res);
901
902 for (i = 0; i < ARRAY_SIZE(fd); i++)
903 {
904 int bit, height;
905
906 memset(&lf, 0, sizeof(lf));
907
908 height = fd[i].height & ~FH_SCALE;
909 lf.lfHeight = height;
910 strcpy(lf.lfFaceName, fd[i].face_name);
911
912 for(bit = 0; bit < 32; bit++)
913 {
914 GLYPHMETRICS gm;
915 DWORD fs[2];
916 BOOL bRet;
917
918 fs[0] = 1L << bit;
919 fs[1] = 0;
920 if((fd[i].ansi_bitfield & fs[0]) == 0) continue;
921 if(!TranslateCharsetInfo( fs, &csi, TCI_SRCFONTSIG )) continue;
922
923 lf.lfCharSet = csi.ciCharset;
925 if (fd[i].height & FH_SCALE)
926 ok(ret, "scaled font height %d should not be enumerated\n", height);
927 else
928 {
929 if (font_res == fd[i].dpi && lf.lfCharSet == expected_cs)
930 {
931 todo_wine_if (ret) /* FIXME: Remove once Wine is fixed */
932 ok(!ret, "%s height %ld charset %d dpi %d should be enumerated\n", lf.lfFaceName, lf.lfHeight, lf.lfCharSet, fd[i].dpi);
933 }
934 }
935 if (ret && !(fd[i].height & FH_SCALE))
936 continue;
937
938 hfont = create_font(lf.lfFaceName, &lf);
939 old_hfont = SelectObject(hdc, hfont);
940
941 SetLastError(0xdeadbeef);
942 ret = GetTextFaceA(hdc, sizeof(face_name), face_name);
943 ok(ret, "GetTextFace error %lu\n", GetLastError());
944
945 if (strcmp(face_name, fd[i].face_name) != 0)
946 {
947 ok(ret != ANSI_CHARSET, "font charset should not be ANSI_CHARSET\n");
948 ok(ret != expected_cs, "font charset %d should not be %d\n", ret, expected_cs);
949 SelectObject(hdc, old_hfont);
951 continue;
952 }
953
954 memset(&gm, 0, sizeof(gm));
955 SetLastError(0xdeadbeef);
956 ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
958 ok(ret == GDI_ERROR, "GetGlyphOutline should fail for a bitmap font\n");
959 ret = GetLastError();
960 ok(ret == ERROR_CAN_NOT_COMPLETE || ret == 0xdeadbeef /* Win10 */, "Unexpected error %d.\n", ret);
961
962 bRet = GetTextMetricsA(hdc, &tm);
963 ok(bRet, "GetTextMetrics error %ld\n", GetLastError());
964
965 SetLastError(0xdeadbeef);
967 if ((is_CJK() || expected_cs == 254) && lf.lfCharSet == ANSI_CHARSET)
968 ok(ret == ANSI_CHARSET, "got charset %d, expected ANSI_CHARSETd\n", ret);
969 else
970 ok(ret == expected_cs, "got charset %d, expected %d\n", ret, expected_cs);
971
972 if(fd[i].dpi == tm.tmDigitizedAspectX)
973 {
974 int skipme = 0;
975 if (fd[i].skip_lang_id)
976 {
977 int si = 0;
978 skipme = 0;
979 while(!skipme && fd[i].skip_lang_id[si])
980 if (fd[i].skip_lang_id[si++] == system_lang_id)
981 skipme = 1;
982 }
983 if (!skipme)
984 {
985 ok(tm.tmWeight == fd[i].weight, "%s(%d): tm.tmWeight %ld != %d\n", fd[i].face_name, height, tm.tmWeight, fd[i].weight);
986 if (fd[i].height & FH_SCALE)
987 ok(tm.tmHeight == fd[i].scaled_height, "%s(%d): tm.tmHeight %ld != %d\n", fd[i].face_name, height, tm.tmHeight, fd[i].scaled_height);
988 else
989 ok(tm.tmHeight == fd[i].height, "%s(%d): tm.tmHeight %ld != %d\n", fd[i].face_name, fd[i].height, tm.tmHeight, fd[i].height);
990 ok(tm.tmAscent == fd[i].ascent, "%s(%d): tm.tmAscent %ld != %d\n", fd[i].face_name, height, tm.tmAscent, fd[i].ascent);
991 ok(tm.tmDescent == fd[i].descent, "%s(%d): tm.tmDescent %ld != %d\n", fd[i].face_name, height, tm.tmDescent, fd[i].descent);
992 ok(tm.tmInternalLeading == fd[i].int_leading, "%s(%d): tm.tmInternalLeading %ld != %d\n", fd[i].face_name, height, tm.tmInternalLeading, fd[i].int_leading);
993 ok(tm.tmExternalLeading == fd[i].ext_leading, "%s(%d): tm.tmExternalLeading %ld != %d\n", fd[i].face_name, height, tm.tmExternalLeading, fd[i].ext_leading);
994 ok(tm.tmAveCharWidth == fd[i].ave_char_width, "%s(%d): tm.tmAveCharWidth %ld != %d\n", fd[i].face_name, height, tm.tmAveCharWidth, fd[i].ave_char_width);
995 ok(tm.tmFirstChar == fd[i].first_char, "%s(%d): tm.tmFirstChar = %02x\n", fd[i].face_name, height, tm.tmFirstChar);
996 ok(tm.tmLastChar == fd[i].last_char, "%s(%d): tm.tmLastChar = %02x\n", fd[i].face_name, height, tm.tmLastChar);
997 /* Substitutions like MS Sans Serif,0=MS Sans Serif,204
998 make default char test fail */
999 if (tm.tmCharSet == lf.lfCharSet)
1000 ok(tm.tmDefaultChar == fd[i].def_char, "%s(%d): tm.tmDefaultChar = %02x\n", fd[i].face_name, height, tm.tmDefaultChar);
1001 ok(tm.tmBreakChar == fd[i].break_char, "%s(%d): tm.tmBreakChar = %02x\n", fd[i].face_name, height, tm.tmBreakChar);
1002 ok(tm.tmCharSet == expected_cs || tm.tmCharSet == ANSI_CHARSET, "%s(%d): tm.tmCharSet %d != %d\n", fd[i].face_name, height, tm.tmCharSet, expected_cs);
1003
1004 /* Don't run the max char width test on System/ANSI_CHARSET. We have extra characters in our font
1005 that make the max width bigger */
1006 if ((strcmp(lf.lfFaceName, "System") || lf.lfCharSet != ANSI_CHARSET) && tm.tmDigitizedAspectX == 96)
1007 ok(tm.tmMaxCharWidth == fd[i].max_char_width, "%s(%d): tm.tmMaxCharWidth %ld != %d\n", fd[i].face_name, height, tm.tmMaxCharWidth, fd[i].max_char_width);
1008 }
1009 else
1010 skip("Skipping font metrics test for system langid 0x%x\n",
1012 }
1013 SelectObject(hdc, old_hfont);
1015 }
1016 }
1017
1018 DeleteDC(hdc);
1019}
UINT WINAPI GetACP(void)
Definition: locale.c:2023
#define todo_wine_if(is_todo)
Definition: minitest.h:81
static INT CALLBACK find_font_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
Definition: font.c:690
#define FH_SCALE
Definition: font.c:707
static BOOL is_CJK(void)
Definition: font.c:702
static SYSTEM_INFO si
Definition: virtual.c:39
#define LANG_HEBREW
Definition: nls.h:67
#define LANG_ARABIC
Definition: nls.h:29
static int fd
Definition: io.c:51
int weight
Definition: font.c:1901
int dpi
Definition: font.c:1901
int descent
Definition: font.c:1901
int int_leading
Definition: font.c:1901
int height
Definition: font.c:1901
int ext_leading
Definition: font.c:1901
const char face_name[LF_FACESIZE]
Definition: font.c:1899
int ascent
Definition: font.c:1901
UINT ciCharset
Definition: wingdi.h:1992
#define dpi
Definition: sysparams.c:23
#define ERROR_CAN_NOT_COMPLETE
Definition: winerror.h:906
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
#define FS_ARABIC
Definition: wingdi.h:566
#define FW_BOLD
Definition: wingdi.h:378
#define LOGPIXELSY
Definition: wingdi.h:719
#define FS_LATIN2
Definition: wingdi.h:561
int WINAPI EnumFontFamiliesExA(_In_ HDC, _In_ PLOGFONTA, _In_ FONTENUMPROCA, _In_ LPARAM, _In_ DWORD)
int WINAPI GetTextCharset(_In_ HDC)
Definition: text.c:187
#define FS_JISJAPAN
Definition: wingdi.h:570
#define FW_NORMAL
Definition: wingdi.h:373
#define LOGPIXELSX
Definition: wingdi.h:718
#define TCI_SRCFONTSIG
Definition: wingdi.h:963
#define FS_CYRILLIC
Definition: wingdi.h:562
DWORD WINAPI GetGlyphOutlineA(_In_ HDC hdc, _In_ UINT uChar, _In_ UINT fuFormat, _Out_ LPGLYPHMETRICS lpgm, _In_ DWORD cjBuffer, _Out_writes_bytes_opt_(cjBuffer) LPVOID pvBuffer, _In_ CONST MAT2 *lpmat2)
#define FW_MEDIUM
Definition: wingdi.h:375
#define TCI_SRCCODEPAGE
Definition: wingdi.h:962

Referenced by START_TEST().

◆ test_char_width()

static void test_char_width ( void  )
static

Definition at line 7596 of file font.c.

7597{
7598 HDC dc = GetDC(NULL);
7599 LOGFONTA lf = {0};
7600
7603
7604 ReleaseDC(NULL, dc);
7605}
static int CALLBACK get_char_width_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM ctx)
Definition: font.c:7553

Referenced by START_TEST().

◆ test_CreateFontIndirect()

static void test_CreateFontIndirect ( void  )
static

Definition at line 5049 of file font.c.

5050{
5051 LOGFONTA lf, getobj_lf;
5052 int ret, i;
5053 HFONT hfont;
5054 char TestName[][16] = {"Arial", "Arial Bold", "Arial Italic", "Arial Baltic"};
5055
5056 memset(&lf, 0, sizeof(lf));
5059 lf.lfHeight = 16;
5060 lf.lfWidth = 16;
5062 lf.lfItalic = FALSE;
5063 lf.lfWeight = FW_DONTCARE;
5064
5065 for (i = 0; i < ARRAY_SIZE(TestName); i++)
5066 {
5069 ok(hfont != 0, "CreateFontIndirectA failed\n");
5070 SetLastError(0xdeadbeef);
5071 ret = GetObjectA(hfont, sizeof(getobj_lf), &getobj_lf);
5072 ok(ret, "GetObject failed: %ld\n", GetLastError());
5073 ok(lf.lfItalic == getobj_lf.lfItalic, "lfItalic: expect %02x got %02x\n", lf.lfItalic, getobj_lf.lfItalic);
5074 ok(lf.lfWeight == getobj_lf.lfWeight, "lfWeight: expect %08lx got %08lx\n", lf.lfWeight, getobj_lf.lfWeight);
5075 ok(!lstrcmpA(lf.lfFaceName, getobj_lf.lfFaceName), "font names don't match: %s != %s\n", lf.lfFaceName, getobj_lf.lfFaceName);
5077 }
5078}
WCHAR TestName[MAX_PATH]
Definition: main.cpp:13

Referenced by START_TEST().

◆ test_CreateFontIndirectEx()

static void test_CreateFontIndirectEx ( void  )
static

Definition at line 5080 of file font.c.

5081{
5082 ENUMLOGFONTEXDVA lfex;
5083 HFONT hfont;
5084
5085 if (!is_truetype_font_installed("Arial"))
5086 {
5087 skip("Arial is not installed\n");
5088 return;
5089 }
5090
5091 SetLastError(0xdeadbeef);
5093 ok(hfont == NULL, "got %p\n", hfont);
5094 ok(GetLastError() == 0xdeadbeef, "got error %ld\n", GetLastError());
5095
5096 memset(&lfex, 0, sizeof(lfex));
5099 ok(hfont != 0, "CreateFontIndirectEx failed\n");
5100 if (hfont)
5103}
LOGFONTA elfLogFont
Definition: wingdi.h:3142
ENUMLOGFONTEXA elfEnumLogfontEx
Definition: wingdi.h:3220
CHAR lfFaceName[LF_FACESIZE]
Definition: wingdi.h:2340
HFONT WINAPI CreateFontIndirectExA(const ENUMLOGFONTEXDVA *)
Definition: font.c:1680

Referenced by START_TEST().

◆ test_CreateScalableFontResource()

static void test_CreateScalableFontResource ( void  )
static

Definition at line 5969 of file font.c.

5970{
5971 char ttf_name[MAX_PATH];
5972 char tmp_path[MAX_PATH];
5973 char fot_name[MAX_PATH];
5974 char *file_part;
5975 DWORD ret;
5976 int i;
5977
5978 if (!write_ttf_file("wine_test.ttf", ttf_name))
5979 {
5980 skip("Failed to create ttf file for testing\n");
5981 return;
5982 }
5983
5984 trace("created %s\n", ttf_name);
5985
5986 ret = is_truetype_font_installed("wine_test");
5987 ok(!ret, "font wine_test should not be enumerated\n");
5988
5989 ret = GetTempPathA(MAX_PATH, tmp_path);
5990 ok(ret, "GetTempPath() error %ld\n", GetLastError());
5991 ret = GetTempFileNameA(tmp_path, "fot", 0, fot_name);
5992 ok(ret, "GetTempFileName() error %ld\n", GetLastError());
5993
5994 ret = GetFileAttributesA(fot_name);
5995 ok(ret != INVALID_FILE_ATTRIBUTES, "file %s does not exist\n", fot_name);
5996
5997 SetLastError(0xdeadbeef);
5998 ret = CreateScalableFontResourceA(0, fot_name, ttf_name, NULL);
5999 ok(!ret, "CreateScalableFontResource() should fail\n");
6000 ok(GetLastError() == ERROR_FILE_EXISTS, "not expected error %ld\n", GetLastError());
6001
6002 SetLastError(0xdeadbeef);
6003 ret = CreateScalableFontResourceA(0, fot_name, ttf_name, "");
6004 ok(!ret, "CreateScalableFontResource() should fail\n");
6005 ok(GetLastError() == ERROR_FILE_EXISTS, "not expected error %ld\n", GetLastError());
6006
6007 file_part = strrchr(ttf_name, '\\');
6008 SetLastError(0xdeadbeef);
6009 ret = CreateScalableFontResourceA(0, fot_name, file_part, tmp_path);
6010 ok(!ret, "CreateScalableFontResource() should fail\n");
6011 ok(GetLastError() == ERROR_FILE_EXISTS, "not expected error %ld\n", GetLastError());
6012
6013 SetLastError(0xdeadbeef);
6014 ret = CreateScalableFontResourceA(0, fot_name, "random file name", tmp_path);
6015 ok(!ret, "CreateScalableFontResource() should fail\n");
6016 ok(GetLastError() == ERROR_INVALID_PARAMETER, "not expected error %ld\n", GetLastError());
6017
6018 SetLastError(0xdeadbeef);
6019 ret = CreateScalableFontResourceA(0, fot_name, NULL, ttf_name);
6020 ok(!ret, "CreateScalableFontResource() should fail\n");
6021 ok(GetLastError() == ERROR_INVALID_PARAMETER, "not expected error %ld\n", GetLastError());
6022
6023 ret = DeleteFileA(fot_name);
6024 ok(ret, "DeleteFile() error %ld\n", GetLastError());
6025
6026 ret = RemoveFontResourceExA(fot_name, 0, 0);
6027 ok(!ret, "RemoveFontResourceEx() should fail\n");
6028
6029 /* test public font resource */
6030 SetLastError(0xdeadbeef);
6031 ret = CreateScalableFontResourceA(0, fot_name, ttf_name, NULL);
6032 ok(ret, "CreateScalableFontResource() error %ld\n", GetLastError());
6033
6034 ret = is_truetype_font_installed("wine_test");
6035 ok(!ret, "font wine_test should not be enumerated\n");
6036
6037 SetLastError(0xdeadbeef);
6038 ret = AddFontResourceExA(fot_name, 0, 0);
6039 ok(ret, "AddFontResourceEx() error %ld\n", GetLastError());
6040
6041 ret = is_truetype_font_installed("wine_test");
6042 ok(ret, "font wine_test should be enumerated\n");
6043
6048
6049 ret = RemoveFontResourceExA(fot_name, FR_PRIVATE, 0);
6050 ok(!ret, "RemoveFontResourceEx() with not matching flags should fail\n");
6051
6052 SetLastError(0xdeadbeef);
6053 ret = RemoveFontResourceExA(fot_name, 0, 0);
6054 ok(ret, "RemoveFontResourceEx() error %ld\n", GetLastError());
6055
6056 ret = is_truetype_font_installed("wine_test");
6057 ok(!ret, "font wine_test should not be enumerated\n");
6058
6059 ret = RemoveFontResourceExA(fot_name, 0, 0);
6060 ok(!ret, "RemoveFontResourceEx() should fail\n");
6061
6062 /* test refcounting */
6063 for (i = 0; i < 5; i++)
6064 {
6065 SetLastError(0xdeadbeef);
6066 ret = AddFontResourceExA(fot_name, 0, 0);
6067 ok(ret, "AddFontResourceEx() error %ld\n", GetLastError());
6068 }
6069 for (i = 0; i < 5; i++)
6070 {
6071 SetLastError(0xdeadbeef);
6072 ret = RemoveFontResourceExA(fot_name, 0, 0);
6073 ok(ret, "RemoveFontResourceEx() error %ld\n", GetLastError());
6074 }
6075 ret = RemoveFontResourceExA(fot_name, 0, 0);
6076 ok(!ret, "RemoveFontResourceEx() should fail\n");
6077
6078 DeleteFileA(fot_name);
6079
6080 /* test hidden font resource */
6081 SetLastError(0xdeadbeef);
6082 ret = CreateScalableFontResourceA(1, fot_name, ttf_name, NULL);
6083 ok(ret, "CreateScalableFontResource() error %ld\n", GetLastError());
6084
6085 ret = is_truetype_font_installed("wine_test");
6086 ok(!ret, "font wine_test should not be enumerated\n");
6087
6088 SetLastError(0xdeadbeef);
6089 ret = AddFontResourceExA(fot_name, 0, 0);
6090 ok(ret, "AddFontResourceEx() error %ld\n", GetLastError());
6091
6092 ret = is_truetype_font_installed("wine_test");
6093 todo_wine
6094 ok(!ret, "font wine_test should not be enumerated\n");
6095
6096 /* XP allows removing a private font added with 0 flags */
6097 SetLastError(0xdeadbeef);
6098 ret = RemoveFontResourceExA(fot_name, FR_PRIVATE, 0);
6099 ok(ret, "RemoveFontResourceEx() error %ld\n", GetLastError());
6100
6101 ret = is_truetype_font_installed("wine_test");
6102 ok(!ret, "font wine_test should not be enumerated\n");
6103
6104 ret = RemoveFontResourceExA(fot_name, 0, 0);
6105 ok(!ret, "RemoveFontResourceEx() should fail\n");
6106
6107 DeleteFileA(fot_name);
6108 DeleteFileA(ttf_name);
6109}
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:620
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:1973
_ACRTIMP char *__cdecl strrchr(const char *, int)
Definition: string.c:3298
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
static void test_GetGlyphOutline_character(void)
Definition: font.c:5879
static void test_GetGlyphOutline_empty_contour(void)
Definition: font.c:5793
static void test_fstype_fixup(void)
Definition: font.c:5930
static void test_GetGlyphOutline_metric_clipping(void)
Definition: font.c:5833
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
BOOL WINAPI RemoveFontResourceExA(_In_ LPCSTR lpFileName, _In_ DWORD fl, _In_opt_ PVOID pdv)
Definition: font.c:2212
#define ERROR_FILE_EXISTS
Definition: winerror.h:287
BOOL WINAPI CreateScalableFontResourceA(_In_ DWORD, _In_ LPCSTR, _In_ LPCSTR, _In_opt_ LPCSTR)
INT WINAPI AddFontResourceExA(_In_ LPCSTR pszFilename, _In_ DWORD fl, _Reserved_ PVOID pvReserved)

Referenced by START_TEST().

◆ test_east_asian_font_selection()

static void test_east_asian_font_selection ( void  )
static

Definition at line 6312 of file font.c.

6313{
6314 HDC hdc;
6317 size_t i;
6318
6319 hdc = GetDC(NULL);
6320
6321 for (i = 0; i < ARRAY_SIZE(charset); i++)
6322 {
6323 LOGFONTA lf;
6324 HFONT hfont;
6325 char face_name[LF_FACESIZE];
6326 int ret;
6327
6328 memset(&lf, 0, sizeof lf);
6329 lf.lfFaceName[0] = '\0';
6330 lf.lfCharSet = charset[i];
6331
6333 {
6334 skip("Vertical font for charset %u is not installed\n", charset[i]);
6335 continue;
6336 }
6337
6340 memset(face_name, 0, sizeof face_name);
6341 ret = GetTextFaceA(hdc, sizeof face_name, face_name);
6342 ok(ret && face_name[0] != '@',
6343 "expected non-vertical face for charset %u, got %s\n", charset[i], face_name);
6345
6346 memset(&lf, 0, sizeof lf);
6347 strcpy(lf.lfFaceName, "@");
6348 lf.lfCharSet = charset[i];
6351 memset(face_name, 0, sizeof face_name);
6352 ret = GetTextFaceA(hdc, sizeof face_name, face_name);
6353 ok(ret && face_name[0] == '@',
6354 "expected vertical face for charset %u, got %s\n", charset[i], face_name);
6356 }
6357 ReleaseDC(NULL, hdc);
6358}
static INT CALLBACK has_vertical_font_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
Definition: font.c:6303
#define JOHAB_CHARSET
Definition: wingdi.h:401

Referenced by START_TEST().

◆ test_EnumFontFamilies()

static void test_EnumFontFamilies ( const char font_name,
INT  font_charset 
)
static

Definition at line 2959 of file font.c.

2960{
2961 struct enum_font_data efd;
2962 struct enum_font_dataW efdw;
2963 LOGFONTA lf;
2964 HDC hdc;
2965 int i, ret, ansi_charset, symbol_charset, russian_charset;
2966
2967 if (*font_name && !is_truetype_font_installed(font_name))
2968 {
2969 skip("%s is not installed\n", font_name);
2970 return;
2971 }
2972 memset( &efd, 0, sizeof(efd) );
2973 memset( &efdw, 0, sizeof(efdw) );
2974
2975 hdc = GetDC(0);
2976
2977 /* Observed behaviour: EnumFontFamilies enumerates aliases like "Arial Cyr"
2978 * while EnumFontFamiliesEx doesn't.
2979 */
2980 if (!*font_name && font_charset == DEFAULT_CHARSET) /* do it only once */
2981 {
2982 /*
2983 * Use EnumFontFamiliesW since win98 crashes when the
2984 * second parameter is NULL using EnumFontFamilies
2985 */
2986 efdw.total = 0;
2987 SetLastError(0xdeadbeef);
2989 ok(ret || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, "EnumFontFamiliesW error %lu\n", GetLastError());
2990 if(ret)
2991 {
2992 get_charset_statsW(&efdw, &ansi_charset, &symbol_charset, &russian_charset);
2993 ok(efdw.total > 0, "fonts enumerated: NULL\n");
2994 ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n");
2995 ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n");
2996 ok(russian_charset > 0, "NULL family should enumerate RUSSIAN_CHARSET\n");
2997 }
2998
2999 efdw.total = 0;
3000 SetLastError(0xdeadbeef);
3002 ok(ret || GetLastError() == ERROR_CALL_NOT_IMPLEMENTED, "EnumFontFamiliesExW error %lu\n", GetLastError());
3003 if(ret)
3004 {
3005 get_charset_statsW(&efdw, &ansi_charset, &symbol_charset, &russian_charset);
3006 ok(efdw.total > 0, "fonts enumerated: NULL\n");
3007 ok(ansi_charset > 0, "NULL family should enumerate ANSI_CHARSET\n");
3008 ok(symbol_charset > 0, "NULL family should enumerate SYMBOL_CHARSET\n");
3009 ok(russian_charset > 0, "NULL family should enumerate RUSSIAN_CHARSET\n");
3010 }
3011 }
3012
3013 efd.total = 0;
3014 SetLastError(0xdeadbeef);
3015 ret = EnumFontFamiliesA(hdc, font_name, arial_enum_proc, (LPARAM)&efd);
3016 ok(ret, "EnumFontFamilies error %lu\n", GetLastError());
3017 get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
3018 if (*font_name)
3019 ok(efd.total > 0, "no fonts enumerated: %s\n", font_name);
3020 else
3021 ok(!efd.total, "no fonts should be enumerated for empty font_name\n");
3022 for (i = 0; i < efd.total; i++)
3023 {
3024 /* FIXME: remove completely once Wine is fixed */
3025 todo_wine_if(efd.lf[i].lfCharSet != font_charset)
3026 ok(efd.lf[i].lfCharSet == font_charset, "%d: got charset %d\n", i, efd.lf[i].lfCharSet);
3027 ok(!strcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
3028 font_name, efd.lf[i].lfFaceName);
3029 }
3030
3031 memset(&lf, 0, sizeof(lf));
3033 strcpy(lf.lfFaceName, font_name);
3034 efd.total = 0;
3035 SetLastError(0xdeadbeef);
3037 ok(ret, "EnumFontFamiliesEx error %lu\n", GetLastError());
3038 get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
3039 if (font_charset == SYMBOL_CHARSET)
3040 {
3041 if (*font_name)
3042 ok(efd.total == 0, "no fonts should be enumerated: %s ANSI_CHARSET\n", font_name);
3043 else
3044 ok(efd.total > 0, "no fonts enumerated: %s\n", font_name);
3045 }
3046 else
3047 {
3048 ok(efd.total > 0, "no fonts enumerated: %s ANSI_CHARSET\n", font_name);
3049 for (i = 0; i < efd.total; i++)
3050 {
3051 ok(efd.lf[i].lfCharSet == ANSI_CHARSET, "%d: got charset %d\n", i, efd.lf[i].lfCharSet);
3052 if (*font_name)
3053 ok(!strcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
3054 font_name, efd.lf[i].lfFaceName);
3055 }
3056 }
3057
3058 /* DEFAULT_CHARSET should enumerate all available charsets */
3059 memset(&lf, 0, sizeof(lf));
3061 strcpy(lf.lfFaceName, font_name);
3062 efd.total = 0;
3063 SetLastError(0xdeadbeef);
3065 ok(ret, "EnumFontFamiliesEx error %lu\n", GetLastError());
3066 get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
3067 ok(efd.total > 0, "no fonts enumerated: %s DEFAULT_CHARSET\n", font_name);
3068 for (i = 0; i < efd.total; i++)
3069 {
3070 if (*font_name)
3071 ok(!strcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
3072 font_name, efd.lf[i].lfFaceName);
3073 }
3074 if (*font_name)
3075 {
3076 switch (font_charset)
3077 {
3078 case ANSI_CHARSET:
3079 ok(ansi_charset > 0,
3080 "ANSI_CHARSET should enumerate ANSI_CHARSET for %s\n", font_name);
3081 ok(!symbol_charset,
3082 "ANSI_CHARSET should NOT enumerate SYMBOL_CHARSET for %s\n", font_name);
3083 ok(russian_charset > 0,
3084 "ANSI_CHARSET should enumerate RUSSIAN_CHARSET for %s\n", font_name);
3085 break;
3086 case SYMBOL_CHARSET:
3087 ok(!ansi_charset,
3088 "SYMBOL_CHARSET should NOT enumerate ANSI_CHARSET for %s\n", font_name);
3089 ok(symbol_charset,
3090 "SYMBOL_CHARSET should enumerate SYMBOL_CHARSET for %s\n", font_name);
3091 ok(!russian_charset,
3092 "SYMBOL_CHARSET should NOT enumerate RUSSIAN_CHARSET for %s\n", font_name);
3093 break;
3094 case DEFAULT_CHARSET:
3095 ok(ansi_charset > 0,
3096 "DEFAULT_CHARSET should enumerate ANSI_CHARSET for %s\n", font_name);
3097 ok(symbol_charset > 0,
3098 "DEFAULT_CHARSET should enumerate SYMBOL_CHARSET for %s\n", font_name);
3099 ok(russian_charset > 0,
3100 "DEFAULT_CHARSET should enumerate RUSSIAN_CHARSET for %s\n", font_name);
3101 break;
3102 }
3103 }
3104 else
3105 {
3106 ok(ansi_charset > 0,
3107 "DEFAULT_CHARSET should enumerate ANSI_CHARSET for %s\n", *font_name ? font_name : "<empty>");
3108 ok(symbol_charset > 0,
3109 "DEFAULT_CHARSET should enumerate SYMBOL_CHARSET for %s\n", *font_name ? font_name : "<empty>");
3110 ok(russian_charset > 0,
3111 "DEFAULT_CHARSET should enumerate RUSSIAN_CHARSET for %s\n", *font_name ? font_name : "<empty>");
3112 }
3113
3114 memset(&lf, 0, sizeof(lf));
3116 strcpy(lf.lfFaceName, font_name);
3117 efd.total = 0;
3118 SetLastError(0xdeadbeef);
3120 ok(ret, "EnumFontFamiliesEx error %lu\n", GetLastError());
3121 get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
3122 if (*font_name && font_charset == ANSI_CHARSET)
3123 ok(efd.total == 0, "no fonts should be enumerated: %s SYMBOL_CHARSET\n", font_name);
3124 else
3125 {
3126 ok(efd.total > 0, "no fonts enumerated: %s SYMBOL_CHARSET\n", font_name);
3127 for (i = 0; i < efd.total; i++)
3128 {
3129 ok(efd.lf[i].lfCharSet == SYMBOL_CHARSET, "%d: got charset %d\n", i, efd.lf[i].lfCharSet);
3130 if (*font_name)
3131 ok(!strcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
3132 font_name, efd.lf[i].lfFaceName);
3133 }
3134
3135 ok(!ansi_charset,
3136 "SYMBOL_CHARSET should NOT enumerate ANSI_CHARSET for %s\n", *font_name ? font_name : "<empty>");
3137 ok(symbol_charset > 0,
3138 "SYMBOL_CHARSET should enumerate SYMBOL_CHARSET for %s\n", *font_name ? font_name : "<empty>");
3139 ok(!russian_charset,
3140 "SYMBOL_CHARSET should NOT enumerate RUSSIAN_CHARSET for %s\n", *font_name ? font_name : "<empty>");
3141 }
3142
3143 ReleaseDC(0, hdc);
3144
3145 free(efd.lf);
3146 free(efdw.lf);
3147}
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
static void get_charset_stats(struct enum_font_data *efd, int *ansi_charset, int *symbol_charset, int *russian_charset)
Definition: font.c:2905
static INT CALLBACK arial_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
Definition: font.c:2861
static void get_charset_statsW(struct enum_font_dataW *efd, int *ansi_charset, int *symbol_charset, int *russian_charset)
Definition: font.c:2932
static INT CALLBACK arial_enum_procw(const LOGFONTW *lf, const TEXTMETRICW *tm, DWORD type, LPARAM lParam)
Definition: font.c:2883
WCHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:72
int WINAPI EnumFontFamiliesExW(_In_ HDC, _In_ PLOGFONTW, _In_ FONTENUMPROCW, _In_ LPARAM, _In_ DWORD)
int WINAPI EnumFontFamiliesW(_In_ HDC, _In_opt_ LPCWSTR, _In_ FONTENUMPROCW, _In_ LPARAM)

Referenced by START_TEST().

◆ test_EnumFontFamiliesEx_default_charset()

static void test_EnumFontFamiliesEx_default_charset ( void  )
static

Definition at line 3221 of file font.c.

3222{
3223 struct enum_font_data efd;
3224 LOGFONTA target, enum_font;
3225 UINT acp;
3226 HDC hdc;
3227 CHARSETINFO csi;
3228
3229 acp = GetACP();
3231 skip("TranslateCharsetInfo failed for code page %u.\n", acp);
3232 return;
3233 }
3234
3235 hdc = GetDC(0);
3236 memset(&enum_font, 0, sizeof(enum_font));
3237 enum_font.lfCharSet = csi.ciCharset;
3238 target.lfFaceName[0] = '\0';
3239 target.lfCharSet = csi.ciCharset;
3241 if (target.lfFaceName[0] == '\0') {
3242 skip("suitable font isn't found for charset %d.\n", enum_font.lfCharSet);
3243 return;
3244 }
3245 if (acp == 874 || acp == 1255 || acp == 1256) {
3246 /* these codepage use complex script, expecting ANSI_CHARSET here. */
3247 target.lfCharSet = ANSI_CHARSET;
3248 }
3249
3250 memset(&efd, 0, sizeof(efd));
3251 memset(&enum_font, 0, sizeof(enum_font));
3252 strcpy(enum_font.lfFaceName, target.lfFaceName);
3253 enum_font.lfCharSet = DEFAULT_CHARSET;
3254 EnumFontFamiliesExA(hdc, &enum_font, enum_font_data_proc, (LPARAM)&efd, 0);
3255 ReleaseDC(0, hdc);
3256
3257 if (efd.total < 2)
3258 ok(0, "EnumFontFamilies is broken. Expected >= 2, got %d.\n", efd.total);
3259 else
3260 ok(efd.lf[0].lfCharSet == target.lfCharSet,
3261 "(%s) got charset %d expected %d\n",
3262 efd.lf[0].lfFaceName, efd.lf[0].lfCharSet, target.lfCharSet);
3263
3264 free(efd.lf);
3265 return;
3266}
static INT CALLBACK enum_font_data_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
Definition: font.c:3170
static INT CALLBACK enum_multi_charset_font_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
Definition: font.c:3149

Referenced by START_TEST().

◆ test_EnumFonts()

static void test_EnumFonts ( void  )
static

Definition at line 5388 of file font.c.

5389{
5390 int ret;
5391 LOGFONTA lf;
5392 HDC hdc;
5393
5394 if (!is_truetype_font_installed("Arial"))
5395 {
5396 skip("Arial is not installed\n");
5397 return;
5398 }
5399
5400 /* Windows uses localized font face names, so Arial Bold won't be found */
5402 {
5403 skip("User locale is not English, skipping the test\n");
5404 return;
5405 }
5406
5408
5409 /* check that the enumproc's retval is returned */
5411 ok(ret == 0xcafe, "got %08x\n", ret);
5412
5413 ret = EnumFontFamiliesA(hdc, "Arial", enum_fonts_proc, (LPARAM)&lf);
5414 ok(!ret, "font Arial is not enumerated\n");
5415 ret = strcmp(lf.lfFaceName, "Arial");
5416 ok(!ret, "expected Arial got %s\n", lf.lfFaceName);
5417 ok(lf.lfWeight == FW_NORMAL, "expected FW_NORMAL got %ld\n", lf.lfWeight);
5418
5419 strcpy(lf.lfFaceName, "Arial");
5421 ok(!ret, "font Arial is not enumerated\n");
5422 ret = strcmp(lf.lfFaceName, "Arial");
5423 ok(!ret, "expected Arial got %s\n", lf.lfFaceName);
5424 ok(lf.lfWeight == FW_NORMAL, "expected FW_NORMAL got %ld\n", lf.lfWeight);
5425
5426 ret = EnumFontFamiliesA(hdc, "Arial Bold", enum_fonts_proc, (LPARAM)&lf);
5427 ok(!ret, "font Arial Bold is not enumerated\n");
5428 ret = strcmp(lf.lfFaceName, "Arial");
5429 ok(!ret, "expected Arial got %s\n", lf.lfFaceName);
5430 ok(lf.lfWeight == FW_BOLD, "expected FW_BOLD got %ld\n", lf.lfWeight);
5431
5432 strcpy(lf.lfFaceName, "Arial Bold");
5434 ok(ret, "font Arial Bold should not be enumerated\n");
5435
5436 ret = EnumFontFamiliesA(hdc, "Arial Bold Italic", enum_fonts_proc, (LPARAM)&lf);
5437 ok(!ret, "font Arial Bold Italic is not enumerated\n");
5438 ret = strcmp(lf.lfFaceName, "Arial");
5439 ok(!ret, "expected Arial got %s\n", lf.lfFaceName);
5440 ok(lf.lfWeight == FW_BOLD, "expected FW_BOLD got %ld\n", lf.lfWeight);
5441
5442 strcpy(lf.lfFaceName, "Arial Bold Italic");
5444 ok(ret, "font Arial Bold Italic should not be enumerated\n");
5445
5446 ret = EnumFontFamiliesA(hdc, "Arial Italic Bold", enum_fonts_proc, (LPARAM)&lf);
5447 ok(ret, "font Arial Italic Bold should not be enumerated\n");
5448
5449 strcpy(lf.lfFaceName, "Arial Italic Bold");
5451 ok(ret, "font Arial Italic Bold should not be enumerated\n");
5452
5453 DeleteDC(hdc);
5454}
LANGID WINAPI GetUserDefaultLangID(void)
Definition: locale.c:1182
static INT CALLBACK enum_with_magic_retval_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
Definition: font.c:5383
static INT CALLBACK enum_fonts_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
Definition: font.c:5352
static INT CALLBACK enum_all_fonts_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
Definition: font.c:5365

Referenced by START_TEST().

◆ test_EnumFonts_subst()

static void test_EnumFonts_subst ( void  )
static

Definition at line 5498 of file font.c.

5499{
5500 int ret;
5501 LOGFONTA lf;
5502 HDC hdc;
5503 struct enum_fullname_data efnd;
5504
5505 ret = is_font_installed("MS Shell Dlg");
5506 ok(ret, "MS Shell Dlg should be enumerated\n");
5507 ret = is_truetype_font_installed("MS Shell Dlg");
5508 ok(ret, "MS Shell Dlg should be enumerated as a TrueType font\n");
5509
5510 ret = is_font_installed("MS Shell Dlg 2");
5511 ok(ret, "MS Shell Dlg 2 should be enumerated\n");
5512 ret = is_truetype_font_installed("MS Shell Dlg 2");
5513 ok(ret, "MS Shell Dlg 2 should be enumerated as a TrueType font\n");
5514
5516
5517 memset(&efnd, 0, sizeof(efnd));
5519 ok(ret, "MS Shell Dlg should not be enumerated\n");
5520 ok(!efnd.total, "MS Shell Dlg should not be enumerated\n");
5521
5522 memset(&lf, 0, sizeof(lf));
5524
5525 efnd.total = 0;
5526 strcpy(lf.lfFaceName, "MS Shell Dlg");
5528 ok(!ret, "MS Shell Dlg should be enumerated\n");
5529 ok(efnd.total > 0, "MS Shell Dlg should be enumerated\n");
5530 if (efnd.total)
5531 {
5532 ret = strcmp((const char *)efnd.elf[0].elfLogFont.lfFaceName, "MS Shell Dlg");
5533 ok(!ret, "expected MS Shell Dlg, got %s\n", efnd.elf[0].elfLogFont.lfFaceName);
5534 ret = strcmp((const char *)efnd.elf[0].elfFullName, "MS Shell Dlg");
5535 ok(ret, "did not expect MS Shell Dlg\n");
5536 }
5537
5538 efnd.total = 0;
5540 ok(ret, "MS Shell Dlg 2 should not be enumerated\n");
5541 ok(!efnd.total, "MS Shell Dlg 2 should not be enumerated\n");
5542
5543 efnd.total = 0;
5544 strcpy(lf.lfFaceName, "MS Shell Dlg 2");
5546 ok(!ret, "MS Shell Dlg 2 should be enumerated\n");
5547 ok(efnd.total > 0, "MS Shell Dlg 2 should be enumerated\n");
5548 if (efnd.total)
5549 {
5550 ret = strcmp((const char *)efnd.elf[0].elfLogFont.lfFaceName, "MS Shell Dlg 2");
5551 ok(!ret, "expected MS Shell Dlg 2, got %s\n", efnd.elf[0].elfLogFont.lfFaceName);
5552 ret = strcmp((const char *)efnd.elf[0].elfFullName, "MS Shell Dlg 2");
5553 ok(ret, "did not expect MS Shell Dlg 2\n");
5554 }
5555
5556 free(efnd.elf);
5557 DeleteDC(hdc);
5558}
static INT CALLBACK enum_ms_shell_dlg_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
Definition: font.c:5456
static INT CALLBACK enum_ms_shell_dlg2_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
Definition: font.c:5477
static BOOL is_font_installed(const char *name)
Definition: font.c:108

Referenced by START_TEST().

◆ test_fake_bold_font()

static void test_fake_bold_font ( void  )
static

Definition at line 6700 of file font.c.

6701{
6702 static const MAT2 x2_mat = { {0,2}, {0,0}, {0,0}, {0,2} };
6703 HDC hdc;
6704 LOGFONTA lf;
6705 BOOL ret;
6706 struct glyph_data {
6708 ABC abc;
6709 INT w;
6710 GLYPHMETRICS gm;
6711 } data[4];
6712 int i;
6713 DWORD r;
6714
6715 /* Test outline font */
6716 memset(&lf, 0, sizeof(lf));
6717 strcpy(lf.lfFaceName, "Wingdings");
6719
6720 hdc = GetDC(NULL);
6721
6722 for (i = 0; i <= 1; i++)
6723 {
6724 HFONT hfont, hfont_old;
6725
6726 lf.lfWeight = i ? FW_BOLD : FW_NORMAL;
6728 hfont_old = SelectObject(hdc, hfont);
6729
6731 ok(ret, "got %d\n", ret);
6732 ret = GetCharABCWidthsA(hdc, 0x76, 0x76, &data[i].abc);
6733 ok(ret, "got %d\n", ret);
6734 data[i].w = data[i].abc.abcA + data[i].abc.abcB + data[i].abc.abcC;
6735 r = GetGlyphOutlineA(hdc, 0x76, GGO_METRICS, &data[i].gm, 0, NULL, &x2_mat);
6736 ok(r != GDI_ERROR, "got %d\n", ret);
6737
6738 SelectObject(hdc, hfont_old);
6740 }
6741 ReleaseDC(NULL, hdc);
6742
6743 /* compare results (outline) */
6744 ok(data[0].tm.tmHeight == data[1].tm.tmHeight,
6745 "expected %ld, got %ld\n", data[0].tm.tmHeight, data[1].tm.tmHeight);
6746 ok(data[0].tm.tmAscent == data[1].tm.tmAscent,
6747 "expected %ld, got %ld\n", data[0].tm.tmAscent, data[1].tm.tmAscent);
6748 ok(data[0].tm.tmDescent == data[1].tm.tmDescent,
6749 "expected %ld, got %ld\n", data[0].tm.tmDescent, data[1].tm.tmDescent);
6750 ok(data[0].tm.tmAveCharWidth + 1 == data[1].tm.tmAveCharWidth,
6751 "expected %ld, got %ld\n", data[0].tm.tmAveCharWidth + 1, data[1].tm.tmAveCharWidth);
6752 ok(data[0].tm.tmMaxCharWidth + 1 == data[1].tm.tmMaxCharWidth,
6753 "expected %ld, got %ld\n", data[0].tm.tmMaxCharWidth + 1, data[1].tm.tmMaxCharWidth);
6754 ok(data[0].tm.tmOverhang == data[1].tm.tmOverhang,
6755 "expected %ld, got %ld\n", data[0].tm.tmOverhang, data[1].tm.tmOverhang);
6756 ok(data[0].w + 1 == data[1].w,
6757 "expected %d, got %d\n", data[0].w + 1, data[1].w);
6758
6759 ok(data[0].gm.gmCellIncX + 1 == data[1].gm.gmCellIncX,
6760 "expected %d, got %d\n", data[0].gm.gmCellIncX + 1, data[1].gm.gmCellIncX);
6761 ok(data[0].gm.gmCellIncY == data[1].gm.gmCellIncY,
6762 "expected %d, got %d\n", data[0].gm.gmCellIncY, data[1].gm.gmCellIncY);
6763
6764 /* Test bitmap font */
6765 memset(&data, 0xaa, sizeof(data));
6766 memset(&lf, 0, sizeof(lf));
6767 strcpy(lf.lfFaceName, "Courier");
6769
6770 hdc = GetDC(NULL);
6771
6772 for (i = 0; i < 4; i++)
6773 {
6774 HFONT hfont, hfont_old;
6775
6776 lf.lfWeight = (i % 2) ? FW_BOLD : FW_NORMAL;
6777 lf.lfHeight = (i > 1) ? data[0].tm.tmHeight * x2_mat.eM11.value : 0;
6779 hfont_old = SelectObject(hdc, hfont);
6780
6782 ok(ret, "got %d\n", ret);
6783 ret = GetCharWidth32A(hdc, 0x76, 0x76, &data[i].w);
6784 ok(ret, "got %d\n", ret);
6785
6786 SelectObject(hdc, hfont_old);
6788 }
6789 ReleaseDC(NULL, hdc);
6790
6791 /* compare results (bitmap) */
6792 for (i = 0; i < 4; i+=2)
6793 {
6794 int diff = (i > 1) ? x2_mat.eM11.value : 1;
6795 if (data[i].tm.tmPitchAndFamily & TMPF_TRUETYPE)
6796 {
6797 skip("TrueType font is selected (expected a bitmap one)\n");
6798 continue;
6799 }
6800 ok(data[i].tm.tmHeight == data[i+1].tm.tmHeight,
6801 "expected %ld, got %ld\n", data[i].tm.tmHeight, data[i+1].tm.tmHeight);
6802 ok(data[i].tm.tmAscent == data[i+1].tm.tmAscent,
6803 "expected %ld, got %ld\n", data[i].tm.tmAscent, data[i+1].tm.tmAscent);
6804 ok(data[i].tm.tmDescent == data[i+1].tm.tmDescent,
6805 "expected %ld, got %ld\n", data[i].tm.tmDescent, data[i+1].tm.tmDescent);
6806 ok(data[i+1].tm.tmAveCharWidth - data[i].tm.tmAveCharWidth == diff,
6807 "expected %d, got %ld\n", diff, data[i+1].tm.tmAveCharWidth - data[i].tm.tmAveCharWidth);
6808 ok(data[i+1].tm.tmMaxCharWidth - data[i].tm.tmMaxCharWidth == diff,
6809 "expected %d, got %ld\n", diff, data[i+1].tm.tmMaxCharWidth - data[i].tm.tmMaxCharWidth);
6810 ok(data[i].tm.tmOverhang == 0,
6811 "expected 0, got %ld\n", data[i].tm.tmOverhang);
6812 ok(data[i+1].tm.tmOverhang == 1,
6813 "expected 1, got %ld\n", data[i+1].tm.tmOverhang);
6814 ok(data[i].w + 1 == data[i+1].w,
6815 "expected %d, got %d\n", data[i].w + 1, data[i+1].w);
6816 }
6817}
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
if(dx< 0)
Definition: linetemp.h:194
short value
Definition: wingdi.h:2916
Definition: wingdi.h:2918
FIXED eM11
Definition: wingdi.h:2919

Referenced by START_TEST().

◆ test_font_charset()

static void test_font_charset ( void  )
static

Definition at line 2663 of file font.c.

2664{
2665 static struct charset_data
2666 {
2667 INT charset;
2669 WORD font_idxA[128], font_idxW[128];
2670 } cd[] =
2671 {
2672 { ANSI_CHARSET, 1252 },
2673 { RUSSIAN_CHARSET, 1251 },
2674 { SYMBOL_CHARSET, CP_SYMBOL } /* keep it as the last one */
2675 };
2676 int i;
2677
2678 if (!is_font_installed("Arial"))
2679 {
2680 skip("Arial is not installed\n");
2681 return;
2682 }
2683
2684 for (i = 0; i < ARRAY_SIZE(cd); i++)
2685 {
2686 if (cd[i].charset == SYMBOL_CHARSET)
2687 {
2688 if (!is_font_installed("Symbol") && !is_font_installed("Wingdings"))
2689 {
2690 skip("Symbol or Wingdings is not installed\n");
2691 break;
2692 }
2693 }
2694 if (get_glyph_indices(cd[i].charset, cd[i].code_page, cd[i].font_idxA, 128, FALSE) &&
2695 get_glyph_indices(cd[i].charset, cd[i].code_page, cd[i].font_idxW, 128, TRUE))
2696 ok(!memcmp(cd[i].font_idxA, cd[i].font_idxW, 128*sizeof(WORD)), "%d: indices don't match\n", i);
2697 }
2698
2699 ok(memcmp(cd[0].font_idxW, cd[1].font_idxW, 128*sizeof(WORD)), "0 vs 1: indices shouldn't match\n");
2700 if (i > 2)
2701 {
2702 ok(memcmp(cd[0].font_idxW, cd[2].font_idxW, 128*sizeof(WORD)), "0 vs 2: indices shouldn't match\n");
2703 ok(memcmp(cd[1].font_idxW, cd[2].font_idxW, 128*sizeof(WORD)), "1 vs 2: indices shouldn't match\n");
2704 }
2705 else
2706 skip("Symbol or Wingdings is not installed\n");
2707}
InitDirComponents & cd
static BOOL get_glyph_indices(INT charset, UINT code_page, WORD *idx, UINT count, BOOL unicode)
Definition: font.c:2478
#define CP_SYMBOL
Definition: winnls.h:252

Referenced by START_TEST().

◆ test_font_metrics()

static void test_font_metrics ( const char context,
HDC  hdc,
HFONT  hfont,
LONG  lfHeight,
LONG  lfWidth,
const char test_str,
INT  test_str_len,
const TEXTMETRICA tm_orig,
const SIZE size_orig,
INT  width_of_A_orig,
INT  scale_x,
INT  scale_y 
)
static

Definition at line 264 of file font.c.

270{
271 LOGFONTA lf;
274 SIZE size;
275 INT width_of_A, cx, cy;
276 UINT ret;
277
278 if (!hfont)
279 return;
280
282 ok(GetCurrentObject(hdc, OBJ_FONT) == hfont, "hfont should be selected\n");
283
284 GetObjectA(hfont, sizeof(lf), &lf);
285
287 {
288 otm.otmSize = sizeof(otm) / 2;
290 ok(ret == sizeof(otm)/2, "expected sizeof(otm)/2, got %u\n", ret);
291
292 memset(&otm, 0x1, sizeof(otm));
293 otm.otmSize = sizeof(otm);
295 ok(ret == sizeof(otm), "expected sizeof(otm), got %u\n", ret);
296
297 memset(&tm, 0x2, sizeof(tm));
299 ok(ret, "GetTextMetricsA failed\n");
300 /* the structure size is aligned */
301 if (memcmp(&tm, &otm.otmTextMetrics, FIELD_OFFSET(TEXTMETRICA, tmCharSet) + 1))
302 {
303 ok(0, "tm != otm\n");
305 }
306
307 tm = otm.otmTextMetrics;
308if (0) /* these metrics are scaled too, but with rounding errors */
309{
310 ok(otm.otmAscent == tm.tmAscent, "ascent %d != %ld\n", otm.otmAscent, tm.tmAscent);
311 ok(otm.otmDescent == -tm.tmDescent, "descent %d != %ld\n", otm.otmDescent, -tm.tmDescent);
312}
313 ok(otm.otmMacAscent == tm.tmAscent, "ascent %d != %ld\n", otm.otmMacAscent, tm.tmAscent);
314 ok(otm.otmDescent < 0, "otm.otmDescent should be < 0\n");
315 ok(otm.otmMacDescent < 0, "otm.otmMacDescent should be < 0\n");
316 ok(tm.tmDescent > 0, "tm.tmDescent should be > 0\n");
317 ok(otm.otmMacDescent == -tm.tmDescent, "descent %d != %ld\n", otm.otmMacDescent, -tm.tmDescent);
319 ok(otm.otmEMSquare == 2048, "expected 2048, got %d\n", otm.otmEMSquare);
320 }
321 else
322 {
324 ok(ret, "GetTextMetricsA failed\n");
325 }
326
327 cx = tm.tmAveCharWidth / tm_orig->tmAveCharWidth;
328 cy = tm.tmHeight / tm_orig->tmHeight;
329 ok(cx == scale_x && cy == scale_y, "height %ld: expected scale_x %d, scale_y %d, got cx %d, cy %d\n",
330 lfHeight, scale_x, scale_y, cx, cy);
331 ok(tm.tmHeight == tm_orig->tmHeight * scale_y, "height %ld != %ld\n", tm.tmHeight, tm_orig->tmHeight * scale_y);
332 ok(tm.tmAscent == tm_orig->tmAscent * scale_y, "ascent %ld != %ld\n", tm.tmAscent, tm_orig->tmAscent * scale_y);
333 ok(tm.tmDescent == tm_orig->tmDescent * scale_y, "descent %ld != %ld\n", tm.tmDescent, tm_orig->tmDescent * scale_y);
334 ok(near_match(tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x), "ave width %ld != %ld\n", tm.tmAveCharWidth, tm_orig->tmAveCharWidth * scale_x);
335 ok(near_match(tm.tmMaxCharWidth, tm_orig->tmMaxCharWidth * scale_x), "max width %ld != %ld\n", tm.tmMaxCharWidth, tm_orig->tmMaxCharWidth * scale_x);
336
337 ok(lf.lfHeight == lfHeight, "lfHeight %ld != %ld\n", lf.lfHeight, lfHeight);
338 if (lf.lfHeight)
339 {
340 if (lf.lfWidth)
341 ok(lf.lfWidth == tm.tmAveCharWidth, "lfWidth %ld != tm %ld\n", lf.lfWidth, tm.tmAveCharWidth);
342 }
343 else
344 ok(lf.lfWidth == lfWidth, "lfWidth %ld != %ld\n", lf.lfWidth, lfWidth);
345
346 GetTextExtentPoint32A(hdc, test_str, test_str_len, &size);
347
348 ok(near_match(size.cx, size_orig->cx * scale_x), "cx %ld != %ld\n", size.cx, size_orig->cx * scale_x);
349 ok(size.cy == size_orig->cy * scale_y, "cy %ld != %ld\n", size.cy, size_orig->cy * scale_y);
350
351 GetCharWidthA(hdc, 'A', 'A', &width_of_A);
352
353 ok(near_match(width_of_A, width_of_A_orig * scale_x), "width A %d != %d\n", width_of_A, width_of_A_orig * scale_x);
355}
#define near_match(a, b)
Definition: font.c:39
static void compare_tm(const TEXTMETRICA *tm, const TEXTMETRICA *otm)
Definition: font.c:240
#define OBJ_FONT
Definition: objidl.idl:1019
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
_Out_opt_ int * cx
Definition: commctrl.h:585
TEXTMETRICA otmTextMetrics
Definition: wingdi.h:2926
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
Definition: http.c:7252
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:428

◆ test_font_weight()

static void test_font_weight ( void  )
static

Definition at line 7793 of file font.c.

7794{
7795 HFONT hfont1, hfont2, old;
7796 char ttf_name[MAX_PATH];
7797 TEXTMETRICW tm1, tm2;
7798 int enum_called;
7799 LOGFONTW lf;
7800 DWORD count;
7801 BOOL bret;
7802 HDC hdc;
7803
7804 bret = write_ttf_file("wine_heavy.ttf", ttf_name);
7805 ok(bret, "Failed to create test font file.\n");
7806
7807 count = AddFontResourceExA(ttf_name, 0, NULL);
7808 ok(count == 1, "got %lu.\n", count);
7809
7810 hdc = GetDC(NULL);
7811
7812 memset(&lf, 0, sizeof(lf));
7813 wcscpy(lf.lfFaceName, L"wine_heavy");
7814 lf.lfHeight = 90;
7815 lf.lfWeight = FW_BOLD;
7817
7818 enum_called = 0;
7819 EnumFontFamiliesExW(hdc, &lf, test_font_weight_enum, (LPARAM)&enum_called, 0);
7820 ok(enum_called, "font not found.\n");
7821
7822 enum_called = 0;
7823 lf.lfWeight = FW_REGULAR;
7824 EnumFontFamiliesExW(hdc, &lf, test_font_weight_enum, (LPARAM)&enum_called, 0);
7825 ok(enum_called, "font not found.\n");
7826
7827 lf.lfWeight = FW_REGULAR;
7828 hfont1 = CreateFontIndirectW(&lf);
7829 lf.lfWeight = FW_BOLD;
7830 hfont2 = CreateFontIndirectW(&lf);
7831
7832 old = SelectObject(hdc, hfont1);
7833 memset(&tm1, 0, sizeof(tm1));
7834 GetTextMetricsW(hdc, &tm1);
7835 SelectObject(hdc, hfont2);
7836 memset(&tm2, 0, sizeof(tm2));
7837 GetTextMetricsW(hdc, &tm2);
7838 ok(tm1.tmMaxCharWidth == tm2.tmMaxCharWidth, "got %ld, %ld.\n", tm1.tmMaxCharWidth, tm2.tmMaxCharWidth);
7839
7840 SelectObject(hdc, old);
7841 ReleaseDC(NULL, hdc);
7842 DeleteObject(hfont1);
7843 DeleteObject(hfont2);
7844 bret = RemoveFontResourceExA(ttf_name, 0, NULL);
7845 ok(bret, "got error %ld\n", GetLastError());
7846}
static INT CALLBACK test_font_weight_enum(const LOGFONTW *lf, const TEXTMETRICW *tm, DWORD type, LPARAM lparam)
Definition: font.c:7778
wcscpy
LONG lfWeight
Definition: dimm.idl:63
LONG tmMaxCharWidth
Definition: wingdi.h:2835
#define FW_REGULAR
Definition: wingdi.h:374
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
HFONT WINAPI CreateFontIndirectW(_In_ const LOGFONTW *)

Referenced by START_TEST().

◆ test_font_weight_enum()

static INT CALLBACK test_font_weight_enum ( const LOGFONTW lf,
const TEXTMETRICW tm,
DWORD  type,
LPARAM  lparam 
)
static

Definition at line 7778 of file font.c.

7780{
7781 const NEWTEXTMETRICW *ntm = (const NEWTEXTMETRICW *)tm;
7782 int *called = (int *)lparam;
7783
7784 if (type != TRUETYPE_FONTTYPE) return 1;
7785 ok(!wcscmp(lf->lfFaceName, L"wine_heavy"), "got %s.\n", debugstr_w(lf->lfFaceName));
7786 ok((ntm->ntmFlags & (NTM_REGULAR | NTM_BOLD)) == NTM_REGULAR, "got %#lx.\n", ntm->ntmFlags);
7787 ok(ntm->tmWeight == 700, "got %ld.\n", ntm->tmWeight);
7788 *called = 1;
7789
7790 return 1;
7791}
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1972
#define debugstr_w
Definition: kernel32.h:32
#define NTM_REGULAR
Definition: wingdi.h:1317
#define NTM_BOLD
Definition: wingdi.h:1316

Referenced by test_font_weight().

◆ test_fstype_fixup()

static void test_fstype_fixup ( void  )
static

Definition at line 5930 of file font.c.

5931{
5932 HDC hdc;
5933 LOGFONTA lf;
5934 HFONT hfont, hfont_prev;
5935 DWORD ret;
5936 OUTLINETEXTMETRICA *otm;
5937 DWORD otm_size;
5938
5939 memset(&lf, 0, sizeof(lf));
5940 lf.lfHeight = 72;
5941 lstrcpyA(lf.lfFaceName, "wine_test");
5942
5943 SetLastError(0xdeadbeef);
5945 ok(hfont != 0, "CreateFontIndirectA error %lu\n", GetLastError());
5946
5947 hdc = GetDC(NULL);
5948
5949 hfont_prev = SelectObject(hdc, hfont);
5950 ok(hfont_prev != NULL, "SelectObject failed\n");
5951
5952 otm_size = GetOutlineTextMetricsA(hdc, 0, NULL);
5953 otm = malloc(otm_size);
5954 otm->otmSize = sizeof(*otm);
5955 ret = GetOutlineTextMetricsA(hdc, otm->otmSize, otm);
5956 ok(ret == otm->otmSize, "expected %u, got %lu, error %ld\n", otm->otmSize, ret, GetLastError());
5957
5958 /* Test font has fsType set to 0x7fff, test that reserved bits are filtered out,
5959 valid bits are 1, 2, 3, 8, 9. */
5960 ok((otm->otmfsType & ~0x30e) == 0, "fsType %#x\n", otm->otmfsType);
5961
5962 free(otm);
5963
5964 SelectObject(hdc, hfont_prev);
5966 ReleaseDC(NULL, hdc);
5967}

Referenced by test_CreateScalableFontResource().

◆ test_fullname()

static void test_fullname ( void  )
static

Definition at line 5582 of file font.c.

5583{
5584 static const char *TestName[] = {"Lucida Sans Demibold Roman", "Lucida Sans Italic", "Lucida Sans Regular"};
5585 WCHAR bufW[LF_FULLFACESIZE];
5586 char bufA[LF_FULLFACESIZE];
5587 HFONT hfont, of;
5588 LOGFONTA lf;
5589 HDC hdc;
5590 int i;
5591 DWORD ret;
5592
5594 ok(hdc != NULL, "CreateCompatibleDC failed\n");
5595
5596 memset(&lf, 0, sizeof(lf));
5599 lf.lfHeight = 16;
5600 lf.lfWidth = 16;
5602 lf.lfItalic = FALSE;
5603 lf.lfWeight = FW_DONTCARE;
5604
5605 for (i = 0; i < ARRAY_SIZE(TestName); i++)
5606 {
5607 if (!is_font_installed_fullname("Lucida Sans", TestName[i]))
5608 {
5609 skip("%s is not installed\n", TestName[i]);
5610 continue;
5611 }
5612
5615 ok(hfont != 0, "CreateFontIndirectA failed\n");
5616
5617 of = SelectObject(hdc, hfont);
5618 bufW[0] = 0;
5619 bufA[0] = 0;
5621 ok(ret, "face full name could not be read\n");
5622 WideCharToMultiByte(CP_ACP, 0, bufW, -1, bufA, sizeof(bufA), NULL, FALSE);
5623 ok(!lstrcmpA(bufA, TestName[i]), "font full names don't match: %s != %s\n", TestName[i], bufA);
5624 SelectObject(hdc, of);
5626 }
5627 DeleteDC(hdc);
5628}
#define CP_ACP
Definition: compat.h:109
#define WideCharToMultiByte
Definition: compat.h:111
#define TT_NAME_ID_FULL_NAME
Definition: font.c:3581
#define TT_MS_LANGID_ENGLISH_UNITED_STATES
Definition: font.c:3577
static BOOL is_font_installed_fullname(const char *family, const char *fullname)
Definition: font.c:5570
static BOOL get_ttf_nametable_entry(HDC hdc, WORD name_id, WCHAR *out_buf, SIZE_T out_size, LCID language_id)
Definition: font.c:3771
#define LF_FULLFACESIZE
Definition: wingdi.h:41

Referenced by START_TEST().

◆ test_fullname2()

static void test_fullname2 ( void  )
static

Definition at line 5752 of file font.c.

5753{
5754 test_fullname2_helper("Arial");
5755 test_fullname2_helper("DejaVu Sans");
5756 test_fullname2_helper("Lucida Sans");
5757 test_fullname2_helper("Tahoma");
5758 test_fullname2_helper("Webdings");
5759 test_fullname2_helper("Wingdings");
5760 test_fullname2_helper("SimSun");
5761 test_fullname2_helper("NSimSun");
5762 test_fullname2_helper("MingLiu");
5763 test_fullname2_helper("PMingLiu");
5764 test_fullname2_helper("WenQuanYi Micro Hei");
5765 test_fullname2_helper("MS UI Gothic");
5766 test_fullname2_helper("Ume UI Gothic");
5767 test_fullname2_helper("MS Gothic");
5768 test_fullname2_helper("Ume Gothic");
5769 test_fullname2_helper("MS PGothic");
5770 test_fullname2_helper("Ume P Gothic");
5771 test_fullname2_helper("Gulim");
5772 test_fullname2_helper("Batang");
5773 test_fullname2_helper("UnBatang");
5774 test_fullname2_helper("UnDotum");
5775 test_fullname2_helper("@SimSun");
5776 test_fullname2_helper("@NSimSun");
5777 test_fullname2_helper("@MingLiu");
5778 test_fullname2_helper("@PMingLiu");
5779 test_fullname2_helper("@WenQuanYi Micro Hei");
5780 test_fullname2_helper("@MS UI Gothic");
5781 test_fullname2_helper("@Ume UI Gothic");
5782 test_fullname2_helper("@MS Gothic");
5783 test_fullname2_helper("@Ume Gothic");
5784 test_fullname2_helper("@MS PGothic");
5785 test_fullname2_helper("@Ume P Gothic");
5786 test_fullname2_helper("@Gulim");
5787 test_fullname2_helper("@Batang");
5788 test_fullname2_helper("@UnBatang");
5789 test_fullname2_helper("@UnDotum");
5790
5791}
static void test_fullname2_helper(const char *Family)
Definition: font.c:5640

Referenced by START_TEST().

◆ test_fullname2_helper()

static void test_fullname2_helper ( const char Family)
static

Definition at line 5640 of file font.c.

5641{
5642 char *FamilyName, *FaceName, *StyleName, *otmStr;
5643 struct enum_fullname_data efnd;
5644 WCHAR *bufW;
5645 char *bufA;
5646 HFONT hfont, of;
5647 LOGFONTA lf;
5648 HDC hdc;
5649 int i;
5650 DWORD otm_size, ret, buf_size;
5651 OUTLINETEXTMETRICA *otm;
5652 BOOL want_vertical, get_vertical;
5653 want_vertical = ( Family[0] == '@' );
5654
5656 ok(hdc != NULL, "CreateCompatibleDC failed\n");
5657
5658 memset(&lf, 0, sizeof(lf));
5661 lf.lfHeight = 16;
5662 lf.lfWidth = 16;
5664 lf.lfItalic = FALSE;
5665 lf.lfWeight = FW_DONTCARE;
5667 memset(&efnd, 0, sizeof(efnd));
5669 if (efnd.total == 0)
5670 skip("%s is not installed\n", lf.lfFaceName);
5671
5672 for (i = 0; i < efnd.total; i++)
5673 {
5674 FamilyName = (char *)efnd.elf[i].elfLogFont.lfFaceName;
5675 FaceName = (char *)efnd.elf[i].elfFullName;
5676 StyleName = (char *)efnd.elf[i].elfStyle;
5677
5678 get_vertical = ( FamilyName[0] == '@' );
5679 ok(get_vertical == want_vertical, "Vertical flags don't match: %s %s\n", Family, FamilyName);
5680
5681 lstrcpyA(lf.lfFaceName, FaceName);
5683 ok(hfont != 0, "CreateFontIndirectA failed\n");
5684
5685 of = SelectObject(hdc, hfont);
5686 buf_size = GetFontData(hdc, MS_NAME_TAG, 0, NULL, 0);
5687 ok(buf_size != GDI_ERROR, "no name table found\n");
5688 if (buf_size == GDI_ERROR) continue;
5689
5690 bufW = malloc(buf_size);
5691 bufA = malloc(buf_size);
5692
5693 otm_size = GetOutlineTextMetricsA(hdc, 0, NULL);
5694 otm = malloc(otm_size);
5695 memset(otm, 0, otm_size);
5696 ret = GetOutlineTextMetricsA(hdc, otm_size, otm);
5697 ok(ret != 0, "GetOutlineTextMetrics fails!\n");
5698 if (ret == 0) continue;
5699
5700 bufW[0] = 0;
5701 bufA[0] = 0;
5704 ok(ret, "%s: FAMILY (family name) could not be read\n", FamilyName);
5705 if (want_vertical) bufW = prepend_at(bufW);
5706 WideCharToMultiByte(CP_ACP, 0, bufW, -1, bufA, buf_size, NULL, FALSE);
5707 ok(!lstrcmpA(FamilyName, bufA), "font family names don't match: returned %s, expect %s\n", FamilyName, bufA);
5708 otmStr = (LPSTR)otm + (UINT_PTR)otm->otmpFamilyName;
5709 ok(!lstrcmpA(FamilyName, otmStr), "FamilyName %s doesn't match otmpFamilyName %s\n", FamilyName, otmStr);
5710
5711 bufW[0] = 0;
5712 bufA[0] = 0;
5715 ok(ret, "FULL_NAME (face name) could not be read\n");
5716 if (want_vertical) bufW = prepend_at(bufW);
5717 WideCharToMultiByte(CP_ACP, 0, bufW, -1, bufA, buf_size, NULL, FALSE);
5718 ok(!lstrcmpA(FaceName, bufA), "%s: font face names don't match: returned %s, expect %s\n", FamilyName, FaceName, bufA);
5719 otmStr = (LPSTR)otm + (UINT_PTR)otm->otmpFaceName;
5720 ok(!lstrcmpA(FaceName, otmStr), "%s: FaceName %s doesn't match otmpFaceName %s\n", FamilyName, FaceName, otmStr);
5721
5722 bufW[0] = 0;
5723 bufA[0] = 0;
5726 ok(ret, "%s: SUBFAMILY (style name) could not be read\n", FamilyName);
5727 WideCharToMultiByte(CP_ACP, 0, bufW, -1, bufA, buf_size, NULL, FALSE);
5728 ok(!lstrcmpA(StyleName, bufA), "%s: style names don't match: returned %s, expect %s\n", FamilyName, StyleName, bufA);
5729 otmStr = (LPSTR)otm + (UINT_PTR)otm->otmpStyleName;
5730 ok(!lstrcmpA(StyleName, otmStr), "%s: StyleName %s doesn't match otmpStyleName %s\n", FamilyName, StyleName, otmStr);
5731
5732 bufW[0] = 0;
5733 bufA[0] = 0;
5736 ok(ret, "%s: UNIQUE_ID (full name) could not be read\n", FamilyName);
5737 WideCharToMultiByte(CP_ACP, 0, bufW, -1, bufA, buf_size, NULL, FALSE);
5738 otmStr = (LPSTR)otm + (UINT_PTR)otm->otmpFullName;
5739 ok(!lstrcmpA(otmStr, bufA), "%s: UNIQUE ID (full name) doesn't match: returned %s, expect %s\n", FamilyName, otmStr, bufA);
5740
5741 SelectObject(hdc, of);
5743
5744 free(otm);
5745 free(bufW);
5746 free(bufA);
5747 }
5748 free(efnd.elf);
5749 DeleteDC(hdc);
5750}
static WCHAR * prepend_at(WCHAR *family)
Definition: font.c:5630
static INT CALLBACK enum_fullname_data_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
Definition: font.c:3187
#define TT_NAME_ID_UNIQUE_ID
Definition: font.c:3580
#define TT_NAME_ID_FONT_FAMILY
Definition: font.c:3578
#define TT_NAME_ID_FONT_SUBFAMILY
Definition: font.c:3579
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
static int Family
Definition: ping.c:62
char * LPSTR
Definition: typedefs.h:51

Referenced by test_fullname2().

◆ test_GdiGetCharDimensions()

static void test_GdiGetCharDimensions ( void  )
static

Definition at line 1021 of file font.c.

1022{
1023 HDC hdc;
1025 LONG ret;
1026 SIZE size;
1027 LONG avgwidth, height;
1028 static const char szAlphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1029
1030 if (!pGdiGetCharDimensions)
1031 {
1032 win_skip("GdiGetCharDimensions not available on this platform\n");
1033 return;
1034 }
1035
1037
1038 GetTextExtentPointA(hdc, szAlphabet, strlen(szAlphabet), &size);
1039 avgwidth = ((size.cx / 26) + 1) / 2;
1040
1041 ret = pGdiGetCharDimensions(hdc, &tm, &height);
1042 ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret);
1043 ok(height == tm.tmHeight, "GdiGetCharDimensions should have set height to %ld instead of %ld\n", tm.tmHeight, height);
1044
1045 ret = pGdiGetCharDimensions(hdc, &tm, NULL);
1046 ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret);
1047
1048 ret = pGdiGetCharDimensions(hdc, NULL, NULL);
1049 ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret);
1050
1051 height = 0;
1052 ret = pGdiGetCharDimensions(hdc, NULL, &height);
1053 ok(ret == avgwidth, "GdiGetCharDimensions should have returned width of %ld instead of %ld\n", avgwidth, ret);
1054 ok(height == size.cy, "GdiGetCharDimensions should have set height to %ld instead of %ld\n", size.cy, height);
1055
1056 DeleteDC(hdc);
1057}
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1592
BOOL WINAPI GetTextExtentPointA(_In_ HDC hdc, _In_reads_(c) LPCSTR lpString, _In_ int c, _Out_ LPSIZE lpsz)

Referenced by START_TEST().

◆ test_GdiGetCodePage()

static void test_GdiGetCodePage ( void  )
static

Definition at line 2709 of file font.c.

2710{
2711 static const struct _matching_data
2712 {
2713 UINT current_codepage;
2714 LPCSTR lfFaceName;
2715 UCHAR lfCharSet;
2716 UINT expected_codepage;
2717 } matching_data[] = {
2718 {1251, "Arial", ANSI_CHARSET, 1252},
2719 {1251, "Tahoma", ANSI_CHARSET, 1252},
2720
2721 {1252, "Arial", ANSI_CHARSET, 1252},
2722 {1252, "Tahoma", ANSI_CHARSET, 1252},
2723
2724 {1253, "Arial", ANSI_CHARSET, 1252},
2725 {1253, "Tahoma", ANSI_CHARSET, 1252},
2726
2727 { 932, "Arial", ANSI_CHARSET, 1252}, /* Japanese Windows returns 1252, not 932 */
2728 { 932, "Tahoma", ANSI_CHARSET, 1252},
2729 { 932, "MS UI Gothic", ANSI_CHARSET, 1252},
2730
2731 { 936, "Arial", ANSI_CHARSET, 936},
2732 { 936, "Tahoma", ANSI_CHARSET, 936},
2733 { 936, "Simsun", ANSI_CHARSET, 936},
2734
2735 { 949, "Arial", ANSI_CHARSET, 949},
2736 { 949, "Tahoma", ANSI_CHARSET, 949},
2737 { 949, "Gulim", ANSI_CHARSET, 949},
2738
2739 { 950, "Arial", ANSI_CHARSET, 950},
2740 { 950, "Tahoma", ANSI_CHARSET, 950},
2741 { 950, "PMingLiU", ANSI_CHARSET, 950},
2742 };
2743 HDC hdc;
2744 LOGFONTA lf;
2745 HFONT hfont;
2746 UINT acp;
2748 int i;
2749
2750 if (!pGdiGetCodePage)
2751 {
2752 win_skip("GdiGetCodePage not available on this platform\n");
2753 return;
2754 }
2755
2756 acp = GetACP();
2757
2758 for (i = 0; i < ARRAY_SIZE(matching_data); i++)
2759 {
2760 /* only test data matched current locale codepage */
2761 if (matching_data[i].current_codepage != acp)
2762 continue;
2763
2764 if (!is_font_installed(matching_data[i].lfFaceName))
2765 {
2766 skip("%s is not installed\n", matching_data[i].lfFaceName);
2767 continue;
2768 }
2769
2770 hdc = GetDC(0);
2771
2772 memset(&lf, 0, sizeof(lf));
2773 lf.lfHeight = -16;
2774 lf.lfCharSet = matching_data[i].lfCharSet;
2775 lstrcpyA(lf.lfFaceName, matching_data[i].lfFaceName);
2777 ok(hfont != 0, "CreateFontIndirectA error %lu\n", GetLastError());
2778
2780 codepage = pGdiGetCodePage(hdc);
2781 ok(codepage == matching_data[i].expected_codepage,
2782 "GdiGetCodePage should have returned %d, got %ld\n", matching_data[i].expected_codepage, codepage);
2783
2786
2787 /* CLIP_DFA_DISABLE turns off the font association */
2790 ok(hfont != 0, "CreateFontIndirectA error %lu\n", GetLastError());
2791
2793 codepage = pGdiGetCodePage(hdc);
2794 ok(codepage == 1252, "GdiGetCodePage returned %ld\n", codepage);
2795
2798
2799 ReleaseDC(NULL, hdc);
2800 }
2801}
unsigned char UCHAR
Definition: typedefs.h:53
int codepage
Definition: win_iconv.c:156
#define CLIP_DFA_DISABLE
Definition: wingdi.h:433

Referenced by START_TEST().

◆ test_GetCharABCWidths()

static void test_GetCharABCWidths ( void  )
static

Definition at line 1109 of file font.c.

1110{
1111 BOOL ret;
1112 HDC hdc;
1113 LOGFONTA lf;
1114 HFONT hfont;
1115 ABC abc[1];
1116 ABC abcw[1];
1117 ABCFLOAT abcf[1];
1118 WORD glyphs[1];
1119 DWORD nb;
1120 HWND hwnd;
1121 static const struct
1122 {
1123 UINT first;
1124 UINT last;
1125 } range[] =
1126 {
1127 {0xff, 0xff},
1128 {0x100, 0x100},
1129 {0xff, 0x100},
1130 {0x1ff, 0xff00},
1131 {0xffff, 0xffff},
1132 {0x10000, 0x10000},
1133 {0xffff, 0x10000},
1134 {0xffffff, 0xffffff},
1135 {0x1000000, 0x1000000},
1136 {0xffffff, 0x1000000},
1137 {0xffffffff, 0xffffffff},
1138 {0x00, 0xff}
1139 };
1140 static const struct
1141 {
1142 UINT cs;
1143 UINT a;
1144 UINT w;
1146 } c[] =
1147 {
1148 {ANSI_CHARSET, 0x30, 0x30,
1150 {SHIFTJIS_CHARSET, 0x82a0, 0x3042,
1152 {HANGEUL_CHARSET, 0x8141, 0xac02,
1154 {GB2312_CHARSET, 0x8141, 0x4e04,
1156 {CHINESEBIG5_CHARSET, 0xa142, 0x3001,
1158 };
1159 UINT i;
1160
1161 memset(&lf, 0, sizeof(lf));
1162 strcpy(lf.lfFaceName, "System");
1163 lf.lfHeight = 20;
1164
1166 hdc = GetDC(0);
1168
1169 nb = GetGlyphIndicesW(hdc, L"i", 1, glyphs, 0);
1170 ok(nb == 1, "GetGlyphIndicesW should have returned 1\n");
1171
1172 ret = GetCharABCWidthsI(NULL, 0, 1, glyphs, abc);
1173 ok(!ret, "GetCharABCWidthsI should have failed\n");
1174
1175 ret = GetCharABCWidthsI(hdc, 0, 1, glyphs, NULL);
1176 ok(!ret, "GetCharABCWidthsI should have failed\n");
1177
1178 ret = GetCharABCWidthsI(hdc, 0, 1, glyphs, abc);
1179 ok(ret, "GetCharABCWidthsI should have succeeded\n");
1180
1181 ret = GetCharABCWidthsW(NULL, 'a', 'a', abc);
1182 ok(!ret, "GetCharABCWidthsW should have failed\n");
1183
1184 ret = GetCharABCWidthsW(hdc, 'a', 'a', NULL);
1185 ok(!ret, "GetCharABCWidthsW should have failed\n");
1186
1187 ret = GetCharABCWidthsW(hdc, 'a', 'a', abc);
1188 ok(ret || broken(!ret) /* < win10 */, "GetCharABCWidthsW should have succeeded\n");
1189
1190 ret = GetCharABCWidthsFloatW(NULL, 'a', 'a', abcf);
1191 ok(!ret, "GetCharABCWidthsFloatW should have failed\n");
1192
1193 ret = GetCharABCWidthsFloatW(hdc, 'a', 'a', NULL);
1194 ok(!ret, "GetCharABCWidthsFloatW should have failed\n");
1195
1196 ret = GetCharABCWidthsFloatW(hdc, 'a', 'a', abcf);
1197 ok(ret, "GetCharABCWidthsFloatW should have succeeded\n");
1198
1201
1202 for (i = 0; i < ARRAY_SIZE(c); ++i)
1203 {
1204 ABC a[2], w[2];
1205 ABC full[256];
1206 UINT code = 0x41, j;
1207
1208 lf.lfFaceName[0] = '\0';
1209 lf.lfCharSet = c[i].cs;
1210 lf.lfPitchAndFamily = 0;
1212 {
1213 skip("TrueType font for charset %u is not installed\n", c[i].cs);
1214 continue;
1215 }
1216
1217 memset(a, 0, sizeof a);
1218 memset(w, 0, sizeof w);
1220 ok(GetCharABCWidthsA(hdc, c[i].a, c[i].a + 1, a) && GetCharABCWidthsW(hdc, c[i].w, c[i].w + 1, w)
1221 && !memcmp(a, w, sizeof(a)),
1222 "GetCharABCWidthsA and GetCharABCWidthsW should return same widths. charset = %u\n", c[i].cs);
1223
1224 memset(a, 0xbb, sizeof a);
1226 ok(ret, "GetCharABCWidthsA should have succeeded\n");
1227 memset(full, 0xcc, sizeof full);
1228 ret = GetCharABCWidthsA(hdc, 0x00, code, full);
1229 ok(ret, "GetCharABCWidthsA should have succeeded\n");
1230 ok(memcmp(&a[0], &full[code], sizeof(ABC)) == 0,
1231 "GetCharABCWidthsA info should match. codepage = %u\n", c[i].cs);
1232
1233 for (j = 0; j < ARRAY_SIZE(range); ++j)
1234 {
1235 memset(full, 0xdd, sizeof full);
1237 ok(ret == c[i].r[j], "GetCharABCWidthsA %x - %x should have %s\n",
1238 range[j].first, range[j].last, c[i].r[j] ? "succeeded" : "failed");
1239 if (ret)
1240 {
1241 UINT last = range[j].last - range[j].first;
1243 ok(ret && memcmp(&full[last], &a[0], sizeof(ABC)) == 0,
1244 "GetCharABCWidthsA %x should match. codepage = %u\n",
1245 range[j].last, c[i].cs);
1246 }
1247 }
1248
1251 }
1252
1253 memset(&lf, 0, sizeof(lf));
1254 strcpy(lf.lfFaceName, "Tahoma");
1255 lf.lfHeight = 200;
1257
1258 /* test empty glyph's metrics */
1260 ret = GetCharABCWidthsFloatW(hdc, ' ', ' ', abcf);
1261 ok(ret, "GetCharABCWidthsFloatW should have succeeded\n");
1262 ok(abcf[0].abcfB == 1.0, "got %f\n", abcf[0].abcfB);
1263 ret = GetCharABCWidthsW(hdc, ' ', ' ', abcw);
1264 ok(ret, "GetCharABCWidthsW should have succeeded\n");
1265 ok(abcw[0].abcB == 1, "got %u\n", abcw[0].abcB);
1266
1267 /* 1) prepare unrotated font metrics */
1268 ret = GetCharABCWidthsW(hdc, 'a', 'a', abcw);
1269 ok(ret, "GetCharABCWidthsW should have succeeded\n");
1271
1272 /* 2) get rotated font metrics */
1273 lf.lfEscapement = lf.lfOrientation = 900;
1276 ret = GetCharABCWidthsW(hdc, 'a', 'a', abc);
1277 ok(ret, "GetCharABCWidthsW should have succeeded\n");
1278
1279 /* 3) compare ABC results */
1280 ok(match_off_by_1(abcw[0].abcA, abc[0].abcA, FALSE),
1281 "got %d, expected %d (A)\n", abc[0].abcA, abcw[0].abcA);
1282 ok(match_off_by_1(abcw[0].abcB, abc[0].abcB, FALSE),
1283 "got %d, expected %d (B)\n", abc[0].abcB, abcw[0].abcB);
1284 ok(match_off_by_1(abcw[0].abcC, abc[0].abcC, FALSE),
1285 "got %d, expected %d (C)\n", abc[0].abcC, abcw[0].abcC);
1286
1288
1289 /* test abcA == gmptGlyphOrigin.x && abcB == gmBlackBoxX
1290 in various widths. */
1291 for (i = 1; i <= 2; i++)
1292 {
1293 UINT j;
1294 UINT code;
1295
1296 memset(&lf, 0, sizeof(lf));
1297 lf.lfHeight = 20;
1298 if (i == 1)
1299 {
1300 strcpy(lf.lfFaceName, "Tahoma");
1301 code = 'a';
1302 }
1303 else
1304 {
1305 strcpy(lf.lfFaceName, "Times New Roman");
1306 lf.lfItalic = TRUE;
1307 code = 'f';
1308 }
1310 {
1311 skip("%s is not installed\n", lf.lfFaceName);
1312 continue;
1313 }
1314 for (j = 1; j <= 80; j++)
1315 {
1316 GLYPHMETRICS gm;
1317
1318 lf.lfWidth = j;
1321
1322 nb = GetGlyphOutlineA(hdc, code, GGO_METRICS, &gm, 0, NULL, &mat);
1323 ok(nb, "GetGlyphOutlineA should have succeeded at width %d\n", i);
1324
1325 ret = GetCharABCWidthsA(hdc, code, code, abc);
1326 ok(ret, "GetCharABCWidthsA should have succeeded at width %d\n", i);
1327
1328 ok(abc[0].abcA == gm.gmptGlyphOrigin.x,
1329 "abcA(%d) and gmptGlyphOrigin.x(%ld) values are different at width %d\n",
1330 abc[0].abcA, gm.gmptGlyphOrigin.x, i);
1331 ok(abc[0].abcB == gm.gmBlackBoxX,
1332 "abcB(%d) and gmBlackBoxX(%d) values are different at width %d\n",
1333 abc[0].abcB, gm.gmBlackBoxX, i);
1335 }
1336 }
1337 ReleaseDC(NULL, hdc);
1338
1339 /* ABC sign test for a variety of transforms */
1340 memset(&lf, 0, sizeof(lf));
1341 strcpy(lf.lfFaceName, "Tahoma");
1342 lf.lfHeight = 20;
1344 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
1345 0, 0, 0, NULL);
1346 hdc = GetDC(hwnd);
1349
1350 nb = GetGlyphIndicesW(hdc, L"i", 1, glyphs, 0);
1351 ok(nb == 1, "GetGlyphIndicesW should have returned 1\n");
1352
1353 ret = GetCharABCWidthsI(hdc, 0, 1, glyphs, abc);
1354 ok(ret, "GetCharABCWidthsI should have succeeded\n");
1355 ret = GetCharABCWidthsW(hdc, 'i', 'i', abcw);
1356 ok(ret, "GetCharABCWidthsW should have succeeded\n");
1357 ret = GetCharABCWidthsFloatW(hdc, 'i', 'i', abcf);
1358 ok(ret, "GetCharABCWidthsFloatW should have succeeded\n");
1359
1360 ABCWidths_helper("LTR", hdc, glyphs, abc, abcw, abcf);
1361 SetWindowExtEx(hdc, -1, -1, NULL);
1363 ABCWidths_helper("LTR -1 compatible", hdc, glyphs, abc, abcw, abcf);
1365 ABCWidths_helper("LTR -1 advanced", hdc, glyphs, abc, abcw, abcf);
1366 SetWindowExtEx(hdc, 1, 1, NULL);
1368 ABCWidths_helper("LTR 1 compatible", hdc, glyphs, abc, abcw, abcf);
1370 ABCWidths_helper("LTR 1 advanced", hdc, glyphs, abc, abcw, abcf);
1371
1372 ReleaseDC(hwnd, hdc);
1374
1375 /* RTL layout */
1376 hwnd = CreateWindowExA(WS_EX_LAYOUTRTL, "static", "", WS_POPUP, 0,0,100,100,
1377 0, 0, 0, NULL);
1378 hdc = GetDC(hwnd);
1381
1382 ABCWidths_helper("RTL", hdc, glyphs, abc, abcw, abcf);
1383 SetWindowExtEx(hdc, -1, -1, NULL);
1385 ABCWidths_helper("RTL -1 compatible", hdc, glyphs, abc, abcw, abcf);
1387 ABCWidths_helper("RTL -1 advanced", hdc, glyphs, abc, abcw, abcf);
1388 SetWindowExtEx(hdc, 1, 1, NULL);
1390 ABCWidths_helper("RTL 1 compatible", hdc, glyphs, abc, abcw, abcf);
1392 ABCWidths_helper("RTL 1 advanced", hdc, glyphs, abc, abcw, abcf);
1393
1394 ReleaseDC(hwnd, hdc);
1397}
GLenum GLint * range
Definition: glext.h:7539
#define a
Definition: ke_i.h:78
static int CALLBACK create_font_proc(const LOGFONTA *lpelfe, const TEXTMETRICA *lpntme, DWORD FontType, LPARAM lParam)
Definition: font.c:1059
static void ABCWidths_helper(const char *description, HDC hdc, WORD *glyphs, const ABC *base_abci, const ABC *base_abcw, const ABCFLOAT *base_abcf)
Definition: font.c:1078
#define WS_POPUP
Definition: pedump.c:616
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
int WINAPI SetMapMode(_In_ HDC, _In_ int)
#define GM_COMPATIBLE
Definition: wingdi.h:864
int WINAPI SetGraphicsMode(_In_ HDC, _In_ int)
Definition: dc.c:1233
#define GM_ADVANCED
Definition: wingdi.h:865
#define MM_ANISOTROPIC
Definition: wingdi.h:867
BOOL WINAPI SetWindowExtEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPSIZE)
#define WS_EX_LAYOUTRTL
Definition: winuser.h:390
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
BOOL WINAPI DestroyWindow(_In_ HWND)

Referenced by START_TEST().

◆ test_GetCharacterPlacement()

static void test_GetCharacterPlacement ( void  )
static

Definition at line 4994 of file font.c.

4995{
4997 DWORD size, size2;
4998 WCHAR glyphs[20];
4999 int pos[20];
5000 HDC hdc;
5001
5003 ok(!!hdc, "CreateCompatibleDC failed\n");
5004
5005 memset(&result, 0, sizeof(result));
5006 result.lStructSize = sizeof(result);
5007 result.lpCaretPos = pos;
5008 result.lpGlyphs = glyphs;
5009 result.nGlyphs = 20;
5010
5011 pos[0] = -1;
5012 glyphs[0] = '!';
5013 size = GetCharacterPlacementA(hdc, "Wine Test", 9, 0, &result, 0);
5014 ok(size, "GetCharacterPlacementA failed!\n");
5015 ok(result.nGlyphs == 9, "Unexpected number of glyphs %u\n", result.nGlyphs);
5016 ok(glyphs[0] == 'W', "Unexpected first glyph %s\n", wine_dbgstr_wn(glyphs, 1));
5017 ok(pos[0] == 0, "Unexpected caret position %d\n", pos[0]);
5018
5019 pos[0] = -1;
5020 glyphs[0] = '!';
5021 result.nGlyphs = 20;
5022 size2 = GetCharacterPlacementA(hdc, "Wine Test", 0, 0, &result, 0);
5023 ok(!size2, "Expected GetCharacterPlacementA to fail\n");
5024 ok(result.nGlyphs == 20, "Unexpected number of glyphs %u\n", result.nGlyphs);
5025 ok(glyphs[0] == '!', "Unexpected first glyph %s\n", wine_dbgstr_wn(glyphs, 1));
5026 ok(pos[0] == -1, "Unexpected caret position %d\n", pos[0]);
5027
5028 size2 = GetCharacterPlacementA(hdc, "Wine Test", 9, 0, NULL, 0);
5029 ok(size2, "GetCharacterPlacementA failed!\n");
5030 ok(size == size2, "GetCharacterPlacementA returned different result: %lu vs %lu\n", size2, size);
5031
5032 size2 = GetCharacterPlacementA(hdc, "Wine Test", 9, 1024, NULL, GCP_REORDER);
5033 ok(size2, "GetCharacterPlacementA failed!\n");
5034 ok(size == size2, "GetCharacterPlacementA returned different result: %lu vs %lu\n", size2, size);
5035
5036 pos[0] = -1;
5037 glyphs[0] = '!';
5038 result.nGlyphs = 20;
5039 size = GetCharacterPlacementA(hdc, "Wine Test", 9, 1024, &result, GCP_REORDER);
5040 ok(size, "GetCharacterPlacementA failed!\n");
5041 ok(size == size2, "GetCharacterPlacementA returned different result: %lu vs %lu\n", size2, size);
5042 ok(result.nGlyphs == 9, "Unexpected number of glyphs %u\n", result.nGlyphs);
5043 ok(glyphs[0] == 'W', "Unexpected first glyph %s\n", wine_dbgstr_wn(glyphs, 1));
5044 todo_wine ok(pos[0] == 0, "Unexpected caret position %d\n", pos[0]);
5045
5046 DeleteDC(hdc);
5047}
GLuint64EXT * result
Definition: glext.h:11304
#define wine_dbgstr_wn
Definition: testlist.c:2
#define GCP_REORDER
Definition: wingdi.h:843
DWORD WINAPI GetCharacterPlacementA(_In_ HDC hdc, _In_reads_(nCount) LPCSTR lpString, _In_ int nCount, _In_ int nMexExtent, _Inout_ LPGCP_RESULTSA lpResults, _In_ DWORD dwFlags)

Referenced by START_TEST().

◆ test_GetCharacterPlacement_kerning()

static void test_GetCharacterPlacement_kerning ( void  )
static

Definition at line 7607 of file font.c.

7608{
7609 LOGFONTA lf;
7610 HFONT hfont, hfont_old;
7611 KERNINGPAIR *kp;
7612 HDC hdc;
7613 DWORD count, ret, i, size, width, width_kern, idx;
7614 WCHAR str[30];
7616 int kern[30], pos[30], pos_kern[30], dx[30], dx_kern[30], kern_amount;
7617
7618 if (!is_font_installed("Arial"))
7619 {
7620 skip("Arial is not installed, skipping the test\n");
7621 return;
7622 }
7623
7624 hdc = GetDC(0);
7625
7626 memset(&lf, 0, sizeof(lf));
7627 strcpy(lf.lfFaceName, "Arial");
7628 lf.lfHeight = 120;
7630 ok(hfont != NULL, "CreateFontIndirect failed\n");
7631
7632 hfont_old = SelectObject(hdc, hfont);
7633
7635 kp = malloc(count * sizeof(*kp));
7636
7637 ret = GetKerningPairsW(hdc, count, kp);
7638 ok(ret == count, "got %lu, expected %lu\n", ret, count);
7639
7640 size = kern_amount = idx = 0;
7641 for (i = 0; i < count; i++)
7642 {
7643 if (kp[i].wFirst >= 'A' && kp[i].wFirst <= 'z' &&
7644 kp[i].wSecond >= 'A' && kp[i].wSecond <= 'z')
7645 {
7646 str[size++] = kp[i].wFirst;
7647 str[size++] = kp[i].wSecond;
7648 str[size++] = 0;
7649 kern[idx] = kp[i].iKernAmount;
7650 idx++;
7651 kern_amount += kp[i].iKernAmount;
7652 if (size >= ARRAY_SIZE(str)) break;
7653 }
7654 }
7655
7656 free(kp);
7657
7658 count = size;
7659
7660 memset(&result, 0, sizeof(result));
7661 result.lStructSize = sizeof(result);
7662 result.lpCaretPos = pos;
7663 result.lpDx = dx;
7664 result.nGlyphs = count;
7666 ok(ret, "GetCharacterPlacement failed\n");
7667 ok(result.nGlyphs == count, "got %u\n", result.nGlyphs);
7668 width = LOWORD(ret);
7669
7670 memset(&result, 0, sizeof(result));
7671 result.lStructSize = sizeof(result);
7672 result.lpCaretPos = pos_kern;
7673 result.lpDx = dx_kern;
7674 result.nGlyphs = count;
7676 ok(ret, "GetCharacterPlacement failed\n");
7677 ok(result.nGlyphs == count, "got %u\n", result.nGlyphs);
7678 width_kern = LOWORD(ret);
7679
7680 if (width == width_kern)
7681 {
7682 win_skip("GCP_USEKERNING is broken on this platform\n");
7683 goto done;
7684 }
7685
7686 ok(width + kern_amount == width_kern, "%ld + %d != %ld\n", width, kern_amount, width_kern);
7687
7688 kern_amount = idx = 0;
7689 for (i = 0; i < count; i += 3, idx++)
7690 {
7691 ok(pos[i] + kern_amount == pos_kern[i], "%ld: %d + %d != %d\n", i, pos[i], kern_amount, pos_kern[i]);
7692 kern_amount += kern[idx];
7693 ok(pos[i+1] + kern_amount == pos_kern[i+1], "%ld: %d + %d != %d\n", i, pos[i+1], kern_amount, pos_kern[i+1]);
7694 ok(pos[i+2] + kern_amount == pos_kern[i+2], "%ld: %d + %d != %d\n", i, pos[i+2], kern_amount, pos_kern[i+2]);
7695
7696 ok(dx[i] + kern[idx] == dx_kern[i], "%ld: %d + %d != %d\n", i, dx[i], kern[idx], dx_kern[i]);
7697 ok(dx[i+1] == dx_kern[i+1], "%ld: %d != %d\n", i, dx[i+1], dx_kern[i+1]);
7698 ok(dx[i+2] == dx_kern[i+2], "%ld: %d != %d\n", i, dx[i+2], dx_kern[i+2]);
7699 }
7700
7701done:
7702 SelectObject(hdc, hfont_old);
7704 ReleaseDC(0, hdc);
7705}
GLint GLint GLsizei width
Definition: gl.h:1546
GLint dx
Definition: linetemp.h:97
#define LOWORD(l)
Definition: pedump.c:82
WORD wSecond
Definition: wingdi.h:2911
int iKernAmount
Definition: wingdi.h:2912
DWORD WINAPI GetCharacterPlacementW(_In_ HDC hdc, _In_reads_(nCount) LPCWSTR lpString, _In_ int nCount, _In_ int nMexExtent, _Inout_ LPGCP_RESULTSW lpResults, _In_ DWORD dwFlags)
#define GCP_USEKERNING
Definition: wingdi.h:845
DWORD WINAPI GetKerningPairsW(_In_ HDC hdc, _In_ DWORD nPairs, _Out_writes_to_opt_(nPairs, return) LPKERNINGPAIR lpKernPair)

Referenced by START_TEST().

◆ test_GetCharWidth32()

static void test_GetCharWidth32 ( void  )
static

Definition at line 6602 of file font.c.

6603{
6604 BOOL ret;
6605 HDC hdc;
6606 LOGFONTA lf;
6607 HFONT hfont;
6608 INT bufferA;
6609 INT bufferW;
6610 HWND hwnd;
6611
6612 memset(&lf, 0, sizeof(lf));
6613 strcpy(lf.lfFaceName, "System");
6614 lf.lfHeight = 20;
6615
6617 hdc = GetDC(0);
6619
6620 ret = GetCharWidth32W(hdc, 'a', 'a', &bufferW);
6621 ok(ret, "GetCharWidth32W should have succeeded\n");
6622 ret = GetCharWidth32A(hdc, 'a', 'a', &bufferA);
6623 ok(ret, "GetCharWidth32A should have succeeded\n");
6624 ok (bufferA == bufferW, "Widths should be the same\n");
6625 ok (bufferA > 0," Width should be greater than zero\n");
6626
6629 ReleaseDC(NULL, hdc);
6630
6631 memset(&lf, 0, sizeof(lf));
6632 strcpy(lf.lfFaceName, "Tahoma");
6633 lf.lfHeight = 20;
6634
6636 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
6637 0, 0, 0, NULL);
6638 hdc = GetDC(hwnd);
6641
6642 ret = GetCharWidth32W(hdc, 'a', 'a', &bufferW);
6643 ok(ret, "GetCharWidth32W should have succeeded\n");
6644 ok (bufferW > 0," Width should be greater than zero\n");
6645 SetWindowExtEx(hdc, -1,-1,NULL);
6647 ret = GetCharWidth32W(hdc, 'a', 'a', &bufferW);
6648 ok(ret, "GetCharWidth32W should have succeeded\n");
6649 ok (bufferW > 0," Width should be greater than zero\n");
6651 ret = GetCharWidth32W(hdc, 'a', 'a', &bufferW);
6652 ok(ret, "GetCharWidth32W should have succeeded\n");
6653 ok (bufferW > 0," Width should be greater than zero\n");
6654 SetWindowExtEx(hdc, 1,1,NULL);
6656 ret = GetCharWidth32W(hdc, 'a', 'a', &bufferW);
6657 ok(ret, "GetCharWidth32W should have succeeded\n");
6658 ok (bufferW > 0," Width should be greater than zero\n");
6660 ret = GetCharWidth32W(hdc, 'a', 'a', &bufferW);
6661 ok(ret, "GetCharWidth32W should have succeeded\n");
6662 ok (bufferW > 0," Width should be greater than zero\n");
6663
6664 ReleaseDC(hwnd, hdc);
6666
6667 hwnd = CreateWindowExA(WS_EX_LAYOUTRTL, "static", "", WS_POPUP, 0,0,100,100,
6668 0, 0, 0, NULL);
6669 hdc = GetDC(hwnd);
6672
6673 ret = GetCharWidth32W(hdc, 'a', 'a', &bufferW);
6674 ok(ret, "GetCharWidth32W should have succeeded\n");
6675 ok (bufferW > 0," Width should be greater than zero\n");
6676 SetWindowExtEx(hdc, -1,-1,NULL);
6678 ret = GetCharWidth32W(hdc, 'a', 'a', &bufferW);
6679 ok(ret, "GetCharWidth32W should have succeeded\n");
6680 ok (bufferW > 0," Width should be greater than zero\n");
6682 ret = GetCharWidth32W(hdc, 'a', 'a', &bufferW);
6683 ok(ret, "GetCharWidth32W should have succeeded\n");
6684 ok (bufferW > 0," Width should be greater than zero\n");
6685 SetWindowExtEx(hdc, 1,1,NULL);
6687 ret = GetCharWidth32W(hdc, 'a', 'a', &bufferW);
6688 ok(ret, "GetCharWidth32W should have succeeded\n");
6689 ok (bufferW > 0," Width should be greater than zero\n");
6691 ret = GetCharWidth32W(hdc, 'a', 'a', &bufferW);
6692 ok(ret, "GetCharWidth32W should have succeeded\n");
6693 ok (bufferW > 0," Width should be greater than zero\n");
6694
6695 ReleaseDC(hwnd, hdc);
6698}
BOOL WINAPI GetCharWidth32W(_In_ HDC hdc, _In_ UINT iFirst, _In_ UINT iLast, _Out_writes_(iLast+1 - iFirst) LPINT lpBuffer)

Referenced by START_TEST().

◆ test_GetCharWidthI()

static void test_GetCharWidthI ( void  )
static

Definition at line 6947 of file font.c.

6948{
6949 static const char *teststr = "wine ";
6950 HFONT hfont, prev_hfont;
6951 WORD glyphs[5];
6952 INT widths[5];
6953 INT width;
6954 LOGFONTA lf;
6955 ABC abc[5], abc1;
6956 int len, i;
6957 DWORD nb;
6958 BOOL ret;
6959 HDC hdc;
6960
6961 memset(&lf, 0, sizeof(lf));
6962 strcpy(lf.lfFaceName, "Tahoma");
6963 lf.lfHeight = -20;
6964
6965 hdc = GetDC(0);
6966
6968 prev_hfont = SelectObject(hdc, hfont);
6969
6970 len = strlen(teststr);
6971 nb = GetGlyphIndicesA(hdc, teststr, len, glyphs, 0);
6972 ok(nb == len, "\n");
6973
6974 memset(abc, 0xcc, sizeof(abc));
6975 ret = GetCharABCWidthsI(hdc, 0, len, glyphs, abc);
6976 ok(ret, "GetCharABCWidthsI failed\n");
6977
6978 memset(&abc1, 0xcc, sizeof(abc1));
6979 ret = GetCharABCWidthsI(hdc, glyphs[0], 1, NULL, &abc1);
6980 ok(ret, "GetCharABCWidthsI failed\n");
6981 ok(!memcmp(&abc1, abc, sizeof(abc1)), "unexpected abc1\n");
6982
6983 memset(widths, 0xcc, sizeof(widths));
6984 ret = GetCharWidthI(hdc, 0, len, glyphs, widths);
6985 ok(ret, "GetCharWidthI failed\n");
6986
6987 width = 0xdeadbeef;
6988 ret = GetCharWidthI(hdc, glyphs[0], 1, NULL, &width);
6989 ok(ret, "GetCharWidthI failed\n");
6990 ok(width == widths[0], "unexpected width %u\n", width);
6991
6992 for (i = 0; i < len; i++)
6993 ok(widths[i] == abc[i].abcA + abc[i].abcB + abc[i].abcC, "%u, glyph %u, got width %d\n",
6994 i, glyphs[i], widths[i]);
6995
6996 DeleteObject(SelectObject(hdc, prev_hfont));
6997 ReleaseDC(0, hdc);
6998}
BOOL WINAPI GetCharWidthI(_In_ HDC hdc, _In_ UINT giFirst, _In_ UINT cgi, _In_reads_opt_(cgi) LPWORD pgi, _Out_writes_(cgi) LPINT piWidths)

Referenced by START_TEST().

◆ test_GetCharWidthInfo()

static void test_GetCharWidthInfo ( void  )
static

Definition at line 7389 of file font.c.

7390{
7391 HDC hdc;
7392 HFONT hfont, hfont_prev;
7393 LOGFONTA lf;
7394 BOOL r;
7395 DWORD ret, i;
7397 TT_Hori_Header hhea;
7398 struct char_width_info
7399 {
7400 INT lsb, rsb, unk;
7401 } info, info2;
7402 SHORT minLeftSideBearing, minRightSideBearing;
7403 POINT pt[2];
7404 const char* face_list[] = { "Symbol", "Ume Gothic", "MS Gothic" };
7405
7406 if (!pGetCharWidthInfo)
7407 {
7408 win_skip("GetCharWidthInfo is unavailable\n");
7409 return;
7410 }
7411
7412 hdc = GetDC(NULL);
7413
7414 /* test default (System) font */
7415 memset(&info, 0xaa, sizeof(info));
7416 r = pGetCharWidthInfo(hdc, &info);
7417 if (r) /* win10 1803 succeeds */
7418 {
7419 ok(info.lsb == 0, "expected 0, got %d\n", info.lsb);
7420 ok(info.rsb == 0, "expected 0, got %d\n", info.rsb);
7421 ok(info.unk == 0, "expected 0, got %d\n", info.unk);
7422 }
7423
7424 memset(&lf, 0, sizeof(lf));
7425 lf.lfWeight = FW_NORMAL;
7427 strcpy(lf.lfFaceName, "Tahoma");
7429 hfont_prev = SelectObject(hdc, hfont);
7430 ok(hfont_prev != NULL, "SelectObject failed\n");
7431
7432 ret = GetOutlineTextMetricsA(hdc, sizeof(otm), &otm);
7433 ok(ret != 0, "GetOutlineTextMetricsA failed\n");
7434 DeleteObject(SelectObject(hdc, hfont_prev));
7435
7436 /* test Tahoma at the em square size */
7437 lf.lfHeight = -(int)otm.otmEMSquare;
7439 hfont_prev = SelectObject(hdc, hfont);
7440 ok(hfont_prev != NULL, "SelectObject failed\n");
7441
7442 ret = GetFontData(hdc, MS_MAKE_TAG('h','h','e','a'), 0, &hhea, sizeof(hhea));
7443 ok(ret == sizeof(hhea), "got %lu\n", ret);
7444 minLeftSideBearing = GET_BE_WORD(hhea.minLeftSideBearing);
7445 minRightSideBearing = GET_BE_WORD(hhea.minRightSideBearing);
7446
7447 memset(&info, 0xaa, sizeof(info));
7448 r = pGetCharWidthInfo(hdc, &info);
7449 ok(r, "GetCharWidthInfo failed\n");
7450 ok(info.lsb == minLeftSideBearing, "expected %d, got %d\n", minLeftSideBearing, info.lsb);
7451 ok(info.rsb == minRightSideBearing, "expected %d, got %d\n", minRightSideBearing, info.rsb);
7452
7453 DeleteObject(SelectObject(hdc, hfont_prev));
7454
7455 /* these values are scaled, try with smaller size */
7456 lf.lfHeight /= 3;
7458 hfont_prev = SelectObject(hdc, hfont);
7459 ok(hfont_prev != NULL, "SelectObject failed\n");
7460
7461 memset(&info2, 0xaa, sizeof(info2));
7462 r = pGetCharWidthInfo(hdc, &info2);
7463 ok(r, "pGetCharWidthInfo failed\n");
7464 ok(info2.lsb == info.lsb/3, "expected %d, got %d\n", info.lsb/3, info2.lsb);
7465 ok(info2.rsb == info.rsb/3, "expected %d, got %d\n", info.rsb/3, info2.rsb);
7466
7467 DeleteObject(SelectObject(hdc, hfont_prev));
7468 ReleaseDC(NULL, hdc);
7469
7470 /* test with another mapping mode */
7471 hdc = GetDC(NULL);
7473 SetWindowExtEx(hdc, 2, 2, NULL);
7474 SetViewportExtEx(hdc, 1, 1, NULL);
7475
7476 memset(pt, 0, sizeof(pt));
7477 pt[0].y = otm.otmEMSquare;
7478 DPtoLP(hdc, pt, 1);
7479
7480 memset(&lf, 0, sizeof(lf));
7481 lf.lfWeight = FW_NORMAL;
7483 lf.lfHeight = -abs(pt[0].y);
7484 strcpy(lf.lfFaceName, "Tahoma");
7486 hfont_prev = SelectObject(hdc, hfont);
7487 ok(hfont_prev != NULL, "SelectObject failed\n");
7488
7489 memset(&info2, 0xaa, sizeof(info2));
7490 r = pGetCharWidthInfo(hdc, &info2);
7491 ok(r, "GetCharWidthInfo failed\n");
7492 pt[0].x = info.lsb; pt[0].y = 0;
7493 pt[1].x = info.rsb; pt[1].y = 0;
7494 DPtoLP(hdc, pt, 2);
7495 ok(pt[0].x == info2.lsb, "expected %ld, got %d\n", pt[0].x, info2.lsb);
7496 ok(pt[1].x == info2.rsb, "expected %ld, got %d\n", pt[1].x, info2.rsb);
7497
7498 DeleteObject(SelectObject(hdc, hfont_prev));
7499 ReleaseDC(NULL, hdc);
7500
7501 /* test with synthetic fonts */
7502 hdc = GetDC(NULL);
7503 for (i = 0; i < ARRAY_SIZE(face_list); i++)
7504 {
7505 const char* face = face_list[i];
7507 {
7508 skip("%s is not installed\n", face);
7509 continue;
7510 }
7511 memset(&lf, 0, sizeof(lf));
7512 lf.lfWeight = FW_NORMAL;
7513 lf.lfItalic = FALSE;
7515 lf.lfHeight = -256;
7516 strcpy(lf.lfFaceName, face);
7518 hfont_prev = SelectObject(hdc, hfont);
7519
7520 memset(&info, 0xaa, sizeof(info));
7521 r = pGetCharWidthInfo(hdc, &info);
7522 ok(r, "%s: GetCharWidthInfo failed\n", face);
7523
7524 /* test with synthetic bold */
7525 lf.lfWeight = FW_BOLD;
7526 lf.lfItalic = FALSE;
7529
7530 memset(&info2, 0xaa, sizeof(info2));
7531 r = pGetCharWidthInfo(hdc, &info2);
7532 ok(r, "%s: GetCharWidthInfo failed\n", face);
7533 ok(info.lsb == info2.lsb, "%s: expected %d, got %d\n", face, info.lsb, info2.lsb);
7534 ok(info.rsb == info2.rsb, "%s: expected %d, got %d\n", face, info.rsb, info2.rsb);
7535
7536 /* test with synthetic italic */
7537 lf.lfWeight = FW_NORMAL;
7538 lf.lfItalic = TRUE;
7541
7542 memset(&info2, 0xaa, sizeof(info2));
7543 r = pGetCharWidthInfo(hdc, &info2);
7544 ok(r, "%s: GetCharWidthInfo failed\n", face);
7545 todo_wine ok(info.lsb > info2.lsb, "%s: expected less than %d, got %d\n", face, info.lsb, info2.lsb);
7546 todo_wine ok(info.rsb > info2.rsb, "%s: expected less than %d, got %d\n", face, info.rsb, info2.rsb);
7547 DeleteObject(SelectObject(hdc, hfont_prev));
7548 }
7549
7550 ReleaseDC(NULL, hdc);
7551}
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define pt(x, y)
Definition: drawing.c:79
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
SHORT minLeftSideBearing
Definition: font.c:7378
SHORT minRightSideBearing
Definition: font.c:7379
BOOL WINAPI SetViewportExtEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPSIZE)
Definition: coord.c:465
BOOL WINAPI DPtoLP(_In_ HDC hdc, _Inout_updates_(c) LPPOINT lppt, _In_ int c)
#define MM_ISOTROPIC
Definition: wingdi.h:870

Referenced by START_TEST().

◆ test_GetFontUnicodeRanges()

static void test_GetFontUnicodeRanges ( void  )
static

Definition at line 2803 of file font.c.

2804{
2805 LOGFONTA lf;
2806 HDC hdc;
2807 HFONT hfont, hfont_old;
2808 DWORD size;
2809 GLYPHSET *gs;
2810
2811 memset(&lf, 0, sizeof(lf));
2812 lstrcpyA(lf.lfFaceName, "Arial");
2813 hfont = create_font("Arial", &lf);
2814
2815 hdc = GetDC(0);
2816 hfont_old = SelectObject(hdc, hfont);
2817
2818 size = GetFontUnicodeRanges(NULL, NULL);
2819 ok(!size, "GetFontUnicodeRanges succeeded unexpectedly\n");
2820
2821 size = GetFontUnicodeRanges(hdc, NULL);
2822 ok(size, "GetFontUnicodeRanges failed unexpectedly\n");
2823
2824 gs = calloc(1, size);
2825
2826 size = GetFontUnicodeRanges(hdc, gs);
2827 ok(size, "GetFontUnicodeRanges failed\n");
2828 ok(gs->cRanges, "Unexpected ranges count.\n");
2829
2830 free(gs);
2831
2832 SelectObject(hdc, hfont_old);
2834 ReleaseDC(NULL, hdc);
2835}
#define gs
Definition: i386-dis.c:445
#define calloc
Definition: rosglue.h:14

Referenced by START_TEST().

◆ test_GetGlyphIndices()

static void test_GetGlyphIndices ( void  )
static

Definition at line 1578 of file font.c.

1579{
1580 HDC hdc;
1581 HFONT hfont;
1582 DWORD charcount;
1583 LOGFONTA lf;
1584 DWORD flags = 0;
1585 WCHAR testtext[] = L"Test\xffff";
1586 WCHAR c[] = { 0x25bc /* Black Down-Pointing Triangle */, 0x212a /* Kelvin Sign */ };
1587 WORD glyphs[(sizeof(testtext)/2)-1];
1588 TEXTMETRICA textm;
1589 HFONT hOldFont;
1590 HANDLE rsrc;
1591 DWORD ret, font_size, num_fonts;
1592 void *font;
1593 char ttf_name[MAX_PATH];
1594
1595 hdc = GetDC(0);
1596
1597 memset(&lf, 0, sizeof(lf));
1598 strcpy(lf.lfFaceName, "System");
1599 lf.lfHeight = 16;
1600 lf.lfCharSet = ANSI_CHARSET;
1601
1603 ok(hfont != 0, "CreateFontIndirect failed\n");
1604 hOldFont = SelectObject(hdc, hfont);
1605 ok(GetTextMetricsA(hdc, &textm), "GetTextMetrics failed\n");
1606 if (textm.tmCharSet == ANSI_CHARSET)
1607 {
1609 charcount = GetGlyphIndicesW(hdc, testtext, (sizeof(testtext)/2)-1, glyphs, flags);
1610 ok(charcount == 5, "GetGlyphIndicesW count of glyphs should = 5 not %ld\n", charcount);
1611 ok((glyphs[4] == 0x001f || glyphs[4] == 0xffff /* Vista */), "GetGlyphIndicesW should have returned a nonexistent char not %04x\n", glyphs[4]);
1612 flags = 0;
1613 charcount = GetGlyphIndicesW(hdc, testtext, (sizeof(testtext)/2)-1, glyphs, flags);
1614 ok(charcount == 5, "GetGlyphIndicesW count of glyphs should = 5 not %ld\n", charcount);
1615 ok(glyphs[4] == textm.tmDefaultChar || glyphs[4] == 0x20 /* CJK Windows */,
1616 "GetGlyphIndicesW should have returned a %04x not %04x\n", textm.tmDefaultChar, glyphs[4]);
1617 }
1618 else
1619 /* FIXME: Write tests for non-ANSI charsets. */
1620 skip("GetGlyphIndices System font tests only for ANSI_CHARSET\n");
1621
1622 DeleteObject(SelectObject(hdc, hOldFont));
1623
1624 memset(&lf, 0, sizeof(lf));
1625 strcpy(lf.lfFaceName, "MS Sans Serif");
1626 lf.lfHeight = -13;
1627 lf.lfCharSet = DEFAULT_CHARSET;
1629 ok(hfont != 0, "CreateFontIndirect failed\n");
1630 hOldFont = SelectObject(hdc, hfont);
1631 ok(GetTextMetricsA(hdc, &textm), "GetTextMetrics failed\n");
1632
1633 glyphs[0] = glyphs[1] = 0;
1635 ok(charcount == ARRAY_SIZE(c), "got %lu\n", charcount);
1636 ok(glyphs[0] == 0x001f || glyphs[0] == 0xffff /* Vista */, "got %#x\n", glyphs[0]);
1637 ok(glyphs[1] == 0x001f || glyphs[1] == 0xffff /* Vista */, "got %#x\n", glyphs[1]);
1638
1639 glyphs[0] = glyphs[1] = 0;
1640 charcount = GetGlyphIndicesW(hdc, c, ARRAY_SIZE(c), glyphs, 0);
1641 ok(charcount == ARRAY_SIZE(c), "got %lu\n", charcount);
1642 ok(glyphs[0] == textm.tmDefaultChar || glyphs[0] == 0x20 /* CJK Windows */, "got %#x\n", glyphs[0]);
1643 ok(glyphs[1] == textm.tmDefaultChar || glyphs[1] == 0x20 /* CJK Windows */, "got %#x\n", glyphs[1]);
1644
1645 DeleteObject(SelectObject(hdc, hOldFont));
1646
1647 if(!is_font_installed("Tahoma"))
1648 {
1649 skip("Tahoma is not installed so skipping this test\n");
1650 ReleaseDC(0, hdc);
1651 return;
1652 }
1653 memset(&lf, 0, sizeof(lf));
1654 strcpy(lf.lfFaceName, "Tahoma");
1655 lf.lfHeight = 20;
1656
1658 hOldFont = SelectObject(hdc, hfont);
1659 ok(GetTextMetricsA(hdc, &textm), "GetTextMetric failed\n");
1661 charcount = GetGlyphIndicesW(hdc, testtext, (sizeof(testtext)/2)-1, glyphs, flags);
1662 ok(charcount == 5, "GetGlyphIndicesW count of glyphs should = 5 not %ld\n", charcount);
1663 ok(glyphs[4] == 0xffff, "GetGlyphIndicesW should have returned 0xffff char not %04x\n", glyphs[4]);
1664 flags = 0;
1665 testtext[0] = textm.tmDefaultChar;
1666 charcount = GetGlyphIndicesW(hdc, testtext, (sizeof(testtext)/2)-1, glyphs, flags);
1667 ok(charcount == 5, "GetGlyphIndicesW count of glyphs should = 5 not %ld\n", charcount);
1668 ok(glyphs[0] == 0, "GetGlyphIndicesW for tmDefaultChar should be 0 not %04x\n", glyphs[0]);
1669 ok(glyphs[4] == 0, "GetGlyphIndicesW should have returned 0 not %04x\n", glyphs[4]);
1670 DeleteObject(SelectObject(hdc, hOldFont));
1671
1672 ret = write_ttf_file("wine_nul.ttf", ttf_name);
1673 ok(ret, "Failed to create test font file.\n");
1674 font = load_font(ttf_name, &font_size);
1675 ok(font != NULL, "Failed to map font file.\n");
1676 num_fonts = 0;
1677 rsrc = AddFontMemResourceEx(font, font_size, NULL, &num_fonts);
1678 ok(ret != 0, "Failed to add resource, %ld.\n", GetLastError());
1679 ok(num_fonts == 1, "Unexpected number of fonts %lu.\n", num_fonts);
1680
1681 memset(&lf, 0, sizeof(lf));
1682 strcpy(lf.lfFaceName, "wine_nul");
1683 lf.lfHeight = 20;
1684 flags = 0;
1686 hOldFont = SelectObject(hdc, hfont);
1687 ok(GetTextMetricsA(hdc, &textm), "GetTextMetric failed\n");
1688 testtext[0] = 'T';
1689 charcount = GetGlyphIndicesW(hdc, testtext, (sizeof(testtext)/2)-1, glyphs, flags);
1690 ok(charcount == 5, "GetGlyphIndicesW count of glyphs should = 5 not %ld\n", charcount);
1691 ok(glyphs[0] == 0, "GetGlyphIndicesW for tmDefaultChar should be 0 not %04x\n", glyphs[0]);
1692 ok(glyphs[4] == 0, "GetGlyphIndicesW should have returned 0 not %04x\n", glyphs[4]);
1693 DeleteObject(SelectObject(hdc, hOldFont));
1694
1695 ReleaseDC(0, hdc);
1696
1698 ok(ret, "RemoveFontMemResourceEx error %ld\n", GetLastError());
1699 free_font(font);
1700 ret = DeleteFileA(ttf_name);
1701 ok(ret, "Failed to delete font file, %ld.\n", GetLastError());
1702}
GLbitfield flags
Definition: glext.h:7161
static const char * testtext
Definition: dialog.c:1459
#define GGI_MARK_NONEXISTING_GLYPHS
Definition: wingdi.h:1085

Referenced by START_TEST().

◆ test_GetGlyphOutline()

static void test_GetGlyphOutline ( void  )
static

Definition at line 4684 of file font.c.

4685{
4686 HDC hdc;
4687 GLYPHMETRICS gm, gm2;
4688 LOGFONTA lf;
4689 HFONT hfont, old_hfont;
4690 INT ret, ret2;
4693 static const struct
4694 {
4695 UINT cs;
4696 UINT a;
4697 UINT w;
4698 } c[] =
4699 {
4700 {ANSI_CHARSET, 0x30, 0x30},
4701 {SHIFTJIS_CHARSET, 0x82a0, 0x3042},
4702 {HANGEUL_CHARSET, 0x8141, 0xac02},
4703 {GB2312_CHARSET, 0x8141, 0x4e04},
4704 {CHINESEBIG5_CHARSET, 0xa142, 0x3001}
4705 };
4706 UINT i;
4707
4708 if (!is_truetype_font_installed("Tahoma"))
4709 {
4710 skip("Tahoma is not installed\n");
4711 return;
4712 }
4713
4715 memset(&lf, 0, sizeof(lf));
4716 lf.lfHeight = 72;
4717 lstrcpyA(lf.lfFaceName, "Tahoma");
4718 SetLastError(0xdeadbeef);
4720 ok(hfont != 0, "CreateFontIndirectA error %lu\n", GetLastError());
4721 old_hfont = SelectObject(hdc, hfont);
4722
4723 memset(&gm, 0, sizeof(gm));
4724 SetLastError(0xdeadbeef);
4725 ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
4726 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %lu\n", GetLastError());
4727
4728 memset(&gm, 0, sizeof(gm));
4729 SetLastError(0xdeadbeef);
4730 ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, NULL);
4731 ok(ret == GDI_ERROR, "GetGlyphOutlineA should fail\n");
4732 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", GetLastError());
4733
4734 memset(&gm, 0, sizeof(gm));
4735 SetLastError(0xdeadbeef);
4736 ret = GetGlyphOutlineW(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
4738 ok(ret != GDI_ERROR, "GetGlyphOutlineW error %lu\n", GetLastError());
4739
4740 memset(&gm, 0, sizeof(gm));
4741 SetLastError(0xdeadbeef);
4742 ret = GetGlyphOutlineW(hdc, 'A', GGO_METRICS, &gm, 0, NULL, NULL);
4744 {
4745 ok(ret == GDI_ERROR, "GetGlyphOutlineW should fail\n");
4746 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", GetLastError());
4747 }
4748
4749 /* test for needed buffer size request on space char */
4750 memset(&gm, 0, sizeof(gm));
4751 SetLastError(0xdeadbeef);
4752 ret = GetGlyphOutlineW(hdc, ' ', GGO_NATIVE, &gm, 0, NULL, &mat);
4754 {
4755 ok(ret == 0, "GetGlyphOutlineW should return 0 buffer size for space char\n");
4756 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", GetLastError());
4757 ok(gm.gmBlackBoxX == 1, "Expected 1, got %u\n", gm.gmBlackBoxX);
4758 ok(gm.gmBlackBoxY == 1, "Expected 1, got %u\n", gm.gmBlackBoxY);
4759 }
4760
4761 /* requesting buffer size for space char + error */
4762 memset(&gm, 0, sizeof(gm));
4763 SetLastError(0xdeadbeef);
4764 ret = GetGlyphOutlineW(0, ' ', GGO_NATIVE, &gm, 0, NULL, NULL);
4766 {
4767 ok(ret == GDI_ERROR, "GetGlyphOutlineW should return GDI_ERROR\n");
4768 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", GetLastError());
4769 ok(gm.gmBlackBoxX == 0, "Expected 0, got %u\n", gm.gmBlackBoxX);
4770 ok(gm.gmBlackBoxY == 0, "Expected 0, got %u\n", gm.gmBlackBoxY);
4771 }
4772
4773 /* test GetGlyphOutline with a buffer too small */
4774 SetLastError(0xdeadbeef);
4775 ret = GetGlyphOutlineA(hdc, 'A', GGO_NATIVE, &gm, sizeof(i), &i, &mat);
4777 ok(ret == GDI_ERROR, "GetGlyphOutlineW should return an error when the buffer size is too small.\n");
4778
4779 for (i = 0; i < ARRAY_SIZE(fmt); ++i)
4780 {
4781 DWORD dummy;
4782
4783 memset(&gm, 0xab, sizeof(gm));
4784 SetLastError(0xdeadbeef);
4785 ret = GetGlyphOutlineW(hdc, ' ', fmt[i], &gm, 0, NULL, &mat);
4787 {
4788 if (fmt[i] == GGO_METRICS)
4789 ok(ret != GDI_ERROR, "%2d:GetGlyphOutlineW should succeed, got %d\n", fmt[i], ret);
4790 else
4791 ok(ret == 0, "%2d:GetGlyphOutlineW should return 0, got %d\n", fmt[i], ret);
4792 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", GetLastError());
4793 ok(gm.gmBlackBoxX == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxX);
4794 ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
4795 }
4796
4797 memset(&gm, 0xab, sizeof(gm));
4798 SetLastError(0xdeadbeef);
4799 ret = GetGlyphOutlineW(hdc, ' ', fmt[i], &gm, 0, &dummy, &mat);
4801 {
4802 if (fmt[i] == GGO_METRICS)
4803 ok(ret != GDI_ERROR, "%2d:GetGlyphOutlineW should succeed, got %d\n", fmt[i], ret);
4804 else
4805 ok(ret == 0, "%2d:GetGlyphOutlineW should return 0, got %d\n", fmt[i], ret);
4806 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", GetLastError());
4807 ok(gm.gmBlackBoxX == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxX);
4808 ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
4809 }
4810
4811 memset(&gm, 0xab, sizeof(gm));
4812 SetLastError(0xdeadbeef);
4813 ret = GetGlyphOutlineW(hdc, ' ', fmt[i], &gm, sizeof(dummy), NULL, &mat);
4815 {
4816 if (fmt[i] == GGO_METRICS)
4817 ok(ret != GDI_ERROR, "%2d:GetGlyphOutlineW should succeed, got %d\n", fmt[i], ret);
4818 else
4819 ok(ret == 0, "%2d:GetGlyphOutlineW should return 0, got %d\n", fmt[i], ret);
4820 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %lu\n", GetLastError());
4821 ok(gm.gmBlackBoxX == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxX);
4822 ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
4823 }
4824
4825 memset(&gm, 0xab, sizeof(gm));
4826 SetLastError(0xdeadbeef);
4827 ret = GetGlyphOutlineW(hdc, ' ', fmt[i], &gm, sizeof(dummy), &dummy, &mat);
4829 {
4830 if (fmt[i] == GGO_METRICS) {
4831 ok(ret != GDI_ERROR, "%2d:GetGlyphOutlineW should succeed, got %d\n", fmt[i], ret);
4832 ok(gm.gmBlackBoxX == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxX);
4833 ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
4834 }
4835 else
4836 {
4837 ok(ret == GDI_ERROR, "%2d:GetGlyphOutlineW should return GDI_ERROR, got %d\n", fmt[i], ret);
4838 memset(&gm2, 0xab, sizeof(gm2));
4839 ok(memcmp(&gm, &gm2, sizeof(GLYPHMETRICS)) == 0,
4840 "%2d:GLYPHMETRICS shouldn't be touched on error\n", fmt[i]);
4841 }
4842 }
4843 }
4844
4845 SelectObject(hdc, old_hfont);
4847
4848 for (i = 0; i < ARRAY_SIZE(c); ++i)
4849 {
4850 static const MAT2 rotate_mat = {{0, 0}, {0, -1}, {0, 1}, {0, 0}};
4852
4853 lf.lfFaceName[0] = '\0';
4854 lf.lfCharSet = c[i].cs;
4855 lf.lfPitchAndFamily = 0;
4857 {
4858 skip("TrueType font for charset %u is not installed\n", c[i].cs);
4859 continue;
4860 }
4861
4862 old_hfont = SelectObject(hdc, hfont);
4863
4864 /* expected to ignore superfluous bytes (single-byte character) */
4865 ret = GetGlyphOutlineA(hdc, 0x8041, GGO_BITMAP, &gm, 0, NULL, &mat);
4866 ret2 = GetGlyphOutlineA(hdc, 0x41, GGO_BITMAP, &gm2, 0, NULL, &mat);
4867 ok(ret == ret2 && memcmp(&gm, &gm2, sizeof gm) == 0, "%d %d\n", ret, ret2);
4868
4869 ret = GetGlyphOutlineA(hdc, 0xcc8041, GGO_BITMAP, &gm, 0, NULL, &mat);
4870 ok(ret == ret2 && memcmp(&gm, &gm2, sizeof gm) == 0,
4871 "Expected to ignore superfluous bytes, got %d %d\n", ret, ret2);
4872
4873 /* expected to ignore superfluous bytes (double-byte character) */
4874 ret = GetGlyphOutlineA(hdc, c[i].a, GGO_BITMAP, &gm, 0, NULL, &mat);
4875 ret2 = GetGlyphOutlineA(hdc, c[i].a | 0xdead0000, GGO_BITMAP, &gm2, 0, NULL, &mat);
4876 ok(ret == ret2 && memcmp(&gm, &gm2, sizeof gm) == 0,
4877 "Expected to ignore superfluous bytes, got %d %d\n", ret, ret2);
4878
4879 /* expected to match wide-char version results */
4880 ret2 = GetGlyphOutlineW(hdc, c[i].w, GGO_BITMAP, &gm2, 0, NULL, &mat);
4881 ok(ret == ret2 && memcmp(&gm, &gm2, sizeof gm) == 0, "%d %d\n", ret, ret2);
4882
4884 {
4885 skip("Fixed-pitch TrueType font for charset %u is not available\n", c[i].cs);
4886 continue;
4887 }
4889 if (c[i].a <= 0xff)
4890 {
4891 DeleteObject(SelectObject(hdc, old_hfont));
4892 continue;
4893 }
4894
4895 ret = GetObjectA(hfont, sizeof lf, &lf);
4896 ok(ret > 0, "GetObject error %lu\n", GetLastError());
4897
4899 ok(ret, "GetTextMetrics error %lu\n", GetLastError());
4900 ret = GetGlyphOutlineA(hdc, c[i].a, GGO_METRICS, &gm2, 0, NULL, &mat);
4901 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %lu\n", GetLastError());
4902 ok(gm2.gmCellIncX == tm.tmAveCharWidth * 2 || broken(gm2.gmCellIncX == -lf.lfHeight),
4903 "expected %ld, got %d (%s:%d)\n",
4904 tm.tmAveCharWidth * 2, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
4905
4906 ret = GetGlyphOutlineA(hdc, c[i].a, GGO_METRICS, &gm2, 0, NULL, &rotate_mat);
4907 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %lu\n", GetLastError());
4908 ok(gm2.gmCellIncY == -lf.lfHeight,
4909 "expected %ld, got %d (%s:%d)\n",
4910 -lf.lfHeight, gm2.gmCellIncY, lf.lfFaceName, lf.lfCharSet);
4911
4912 lf.lfItalic = TRUE;
4914 ok(hfont != NULL, "CreateFontIndirect error %lu\n", GetLastError());
4917 ok(ret, "GetTextMetrics error %lu\n", GetLastError());
4918 ret = GetGlyphOutlineA(hdc, c[i].a, GGO_METRICS, &gm2, 0, NULL, &mat);
4919 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %lu\n", GetLastError());
4920 ok(gm2.gmCellIncX == tm.tmAveCharWidth * 2 || broken(gm2.gmCellIncX == -lf.lfHeight),
4921 "expected %ld, got %d (%s:%d)\n",
4922 tm.tmAveCharWidth * 2, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
4923
4924 lf.lfItalic = FALSE;
4925 lf.lfEscapement = lf.lfOrientation = 2700;
4927 ok(hfont != NULL, "CreateFontIndirect error %lu\n", GetLastError());
4929 ret = GetGlyphOutlineA(hdc, c[i].a, GGO_METRICS, &gm2, 0, NULL, &mat);
4930 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %lu\n", GetLastError());
4931 ok(gm2.gmCellIncY == -lf.lfHeight,
4932 "expected %ld, got %d (%s:%d)\n",
4933 -lf.lfHeight, gm2.gmCellIncY, lf.lfFaceName, lf.lfCharSet);
4934
4935 hfont = SelectObject(hdc, old_hfont);
4937 }
4938
4939 DeleteDC(hdc);
4940}
static int CALLBACK create_fixed_pitch_font_proc(const LOGFONTA *lpelfe, const TEXTMETRICA *lpntme, DWORD FontType, LPARAM lParam)
Definition: font.c:4632
UINT gmBlackBoxY
Definition: wingdi.h:2889
short gmCellIncY
Definition: wingdi.h:2892
Definition: dsound.c:943
#define GGO_GRAY2_BITMAP
Definition: wingdi.h:852
#define GGO_GRAY8_BITMAP
Definition: wingdi.h:854
#define GGO_BITMAP
Definition: wingdi.h:849
#define GGO_GRAY4_BITMAP
Definition: wingdi.h:853
#define GGO_NATIVE
Definition: wingdi.h:850

Referenced by START_TEST().

◆ test_GetGlyphOutline_character()

static void test_GetGlyphOutline_character ( void  )
static

Definition at line 5879 of file font.c.

5880{
5881 HFONT hfont, hfont_old;
5882 LOGFONTA lf;
5883 HDC hdc;
5884 DWORD ret;
5885 GLYPHMETRICS gm1, gm2, gmn;
5886 char test_chars[] = { 'A', 'D', '!', '\0' };
5887 char *current_char;
5888
5889 memset(&lf, 0, sizeof(lf));
5890 lf.lfHeight = 72;
5891 lstrcpyA(lf.lfFaceName, "wine_test");
5892
5894 ok(hfont != 0, "CreateFontIndirectA error %lu\n", GetLastError());
5895
5896 hdc = GetDC(NULL);
5897
5898 hfont_old = SelectObject(hdc, hfont);
5899 ok(hfont_old != NULL, "SelectObject failed\n");
5900
5901 ret = GetGlyphOutlineW(hdc, 'Z', GGO_METRICS, &gmn, 0, NULL, &mat);
5902 ok(ret != GDI_ERROR, "GetGlyphOutlineW failed to default to .notdef for character 'Z'\n");
5903
5904 for (current_char = test_chars; *current_char != '\0'; current_char++)
5905 {
5906 ret = GetGlyphOutlineW(hdc, *current_char, GGO_METRICS, &gm1, 0, NULL, &mat);
5907 ok(ret != GDI_ERROR, "GetGlyphOutlineW failed for '%c'\n", *current_char);
5908 ok(memcmp(&gm1, &gmn, sizeof(gmn)) != 0, "the test character '%c' matches .notdef\n", *current_char);
5909
5910 ret = GetGlyphOutlineW(hdc, 0x10000 + *current_char, GGO_METRICS, &gm2, 0, NULL, &mat);
5911 ok(ret != GDI_ERROR, "GetGlyphOutlineW failed for 0x10000 + '%c'\n", *current_char);
5912 ok(memcmp(&gm1, &gm2, sizeof(gmn)) == 0, "GetGlyphOutlineW returned wrong metrics for character 0x10000 + '%c'\n", *current_char);
5913 }
5914
5916 ok(ret != GDI_ERROR, "GetGlyphOutlineW failed for glyph index 0x3\n");
5917
5918 ret = GetGlyphOutlineW(hdc, 0xFFFF, GGO_METRICS|GGO_GLYPH_INDEX, &gm2, 0, NULL, &mat);
5919 ok(ret == GDI_ERROR, "GetGlyphOutlineW for nonexistent glyph index 0xFFFF has succeeded\n");
5920
5921 ret = GetGlyphOutlineW(hdc, 0x10003, GGO_METRICS|GGO_GLYPH_INDEX, &gm2, 0, NULL, &mat);
5922 ok(ret != GDI_ERROR, "GetGlyphOutlineW for index 0x10003 has failed\n");
5923 ok(memcmp(&gm1, &gm2, sizeof(gmn)) == 0, "GetGlyphOutlineW returned wrong metrics for glyph 0x10003\n");
5924
5925 SelectObject(hdc, hfont_old);
5927 ReleaseDC(NULL, hdc);
5928}
#define GGO_GLYPH_INDEX
Definition: wingdi.h:855

Referenced by test_CreateScalableFontResource().

◆ test_GetGlyphOutline_empty_contour()

static void test_GetGlyphOutline_empty_contour ( void  )
static

Definition at line 5793 of file font.c.

5794{
5795 HDC hdc;
5796 LOGFONTA lf;
5797 HFONT hfont, hfont_prev;
5799 GLYPHMETRICS gm;
5800 char buf[1024];
5801 DWORD ret;
5802
5803 memset(&lf, 0, sizeof(lf));
5804 lf.lfHeight = 72;
5805 lstrcpyA(lf.lfFaceName, "wine_test");
5806
5808 ok(hfont != 0, "CreateFontIndirectA error %lu\n", GetLastError());
5809
5810 hdc = GetDC(NULL);
5811
5812 hfont_prev = SelectObject(hdc, hfont);
5813 ok(hfont_prev != NULL, "SelectObject failed\n");
5814
5815 ret = GetGlyphOutlineW(hdc, 0xa8, GGO_NATIVE, &gm, 0, NULL, &mat);
5816 ok(ret == 228, "GetGlyphOutline returned %ld, expected 228\n", ret);
5817
5819 ret = GetGlyphOutlineW(hdc, 0xa8, GGO_NATIVE, &gm, sizeof(buf), buf, &mat);
5820 ok(ret == 228, "GetGlyphOutline returned %ld, expected 228\n", ret);
5821 ok(header->cb == 36, "header->cb = %ld, expected 36\n", header->cb);
5822 ok(header->dwType == TT_POLYGON_TYPE, "header->dwType = %ld, expected TT_POLYGON_TYPE\n", header->dwType);
5823 header = (TTPOLYGONHEADER*)((char*)header+header->cb);
5824 ok(header->cb == 96, "header->cb = %ld, expected 96\n", header->cb);
5825 header = (TTPOLYGONHEADER*)((char*)header+header->cb);
5826 ok(header->cb == 96, "header->cb = %ld, expected 96\n", header->cb);
5827
5828 SelectObject(hdc, hfont_prev);
5830 ReleaseDC(NULL, hdc);
5831}
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define TT_POLYGON_TYPE
Definition: wingdi.h:1318

Referenced by test_CreateScalableFontResource().

◆ test_GetGlyphOutline_metric_clipping()

static void test_GetGlyphOutline_metric_clipping ( void  )
static

Definition at line 5833 of file font.c.

5834{
5835 HDC hdc;
5836 LOGFONTA lf;
5837 HFONT hfont, hfont_prev;
5838 GLYPHMETRICS gm;
5840 TEXTMETRICW tmW;
5841 DWORD ret;
5842
5843 memset(&lf, 0, sizeof(lf));
5844 lf.lfHeight = 72;
5845 lstrcpyA(lf.lfFaceName, "wine_test");
5846
5847 SetLastError(0xdeadbeef);
5849 ok(hfont != 0, "CreateFontIndirectA error %lu\n", GetLastError());
5850
5851 hdc = GetDC(NULL);
5852
5853 hfont_prev = SelectObject(hdc, hfont);
5854 ok(hfont_prev != NULL, "SelectObject failed\n");
5855
5856 SetLastError(0xdeadbeef);
5858 ok(ret, "GetTextMetrics error %lu\n", GetLastError());
5859
5860 GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
5861 ok(gm.gmptGlyphOrigin.y <= tm.tmAscent,
5862 "Glyph top(%ld) exceeds ascent(%ld)\n",
5863 gm.gmptGlyphOrigin.y, tm.tmAscent);
5864 GetGlyphOutlineA(hdc, 'D', GGO_METRICS, &gm, 0, NULL, &mat);
5865 ok(gm.gmptGlyphOrigin.y - gm.gmBlackBoxY >= -tm.tmDescent,
5866 "Glyph bottom(%ld) exceeds descent(%ld)\n",
5867 gm.gmptGlyphOrigin.y - gm.gmBlackBoxY, -tm.tmDescent);
5868
5869 /* Test tmLastChar - wine_test has code points fffb-fffe mapped to glyph 0 */
5870 GetTextMetricsW(hdc, &tmW);
5871 todo_wine
5872 ok( tmW.tmLastChar == 0xfffe, "got %04x\n", tmW.tmLastChar);
5873
5874 SelectObject(hdc, hfont_prev);
5876 ReleaseDC(NULL, hdc);
5877}
WCHAR tmLastChar
Definition: wingdi.h:2841

Referenced by test_CreateScalableFontResource().

◆ test_GetKerningPairs()

static void test_GetKerningPairs ( void  )
static

Definition at line 1704 of file font.c.

1705{
1706 static const struct kerning_data
1707 {
1708 const char face_name[LF_FACESIZE];
1709 LONG height;
1710 /* some interesting fields from OUTLINETEXTMETRIC */
1711 LONG tmHeight, tmAscent, tmDescent;
1712 UINT otmEMSquare;
1713 INT otmAscent;
1714 INT otmDescent;
1715 UINT otmLineGap;
1716 UINT otmsCapEmHeight;
1717 UINT otmsXHeight;
1718 INT otmMacAscent;
1719 INT otmMacDescent;
1720 UINT otmMacLineGap;
1721 UINT otmusMinimumPPEM;
1722 /* small subset of kerning pairs to test */
1723 DWORD total_kern_pairs;
1724 const KERNINGPAIR kern_pair[26];
1725 } kd[] =
1726 {
1727 {"Arial", 12, 12, 9, 3,
1728 2048, 7, -2, 1, 5, 2, 8, -2, 0, 9,
1729 26,
1730 {
1731 {' ','A',-1},{' ','T',0},{' ','Y',0},{'1','1',-1},
1732 {'A',' ',-1},{'A','T',-1},{'A','V',-1},{'A','W',0},
1733 {'A','Y',-1},{'A','v',0},{'A','w',0},{'A','y',0},
1734 {'F',',',-1},{'F','.',-1},{'F','A',-1},{'L',' ',0},
1735 {'L','T',-1},{'L','V',-1},{'L','W',-1},{'L','Y',-1},
1736 {915,912,+1},{915,913,-1},{910,912,+1},{910,913,-1},
1737 {933,970,+1},{933,972,-1}
1738 }
1739 },
1740 {"Arial", -34, 39, 32, 7,
1741 2048, 25, -7, 5, 17, 9, 31, -7, 1, 9,
1742 26,
1743 {
1744 {' ','A',-2},{' ','T',-1},{' ','Y',-1},{'1','1',-3},
1745 {'A',' ',-2},{'A','T',-3},{'A','V',-3},{'A','W',-1},
1746 {'A','Y',-3},{'A','v',-1},{'A','w',-1},{'A','y',-1},
1747 {'F',',',-4},{'F','.',-4},{'F','A',-2},{'L',' ',-1},
1748 {'L','T',-3},{'L','V',-3},{'L','W',-3},{'L','Y',-3},
1749 {915,912,+3},{915,913,-3},{910,912,+3},{910,913,-3},
1750 {933,970,+2},{933,972,-3}
1751 }
1752 },
1753 { "Arial", 120, 120, 97, 23,
1754 2048, 79, -23, 16, 54, 27, 98, -23, 4, 9,
1755 26,
1756 {
1757 {' ','A',-6},{' ','T',-2},{' ','Y',-2},{'1','1',-8},
1758 {'A',' ',-6},{'A','T',-8},{'A','V',-8},{'A','W',-4},
1759 {'A','Y',-8},{'A','v',-2},{'A','w',-2},{'A','y',-2},
1760 {'F',',',-12},{'F','.',-12},{'F','A',-6},{'L',' ',-4},
1761 {'L','T',-8},{'L','V',-8},{'L','W',-8},{'L','Y',-8},
1762 {915,912,+9},{915,913,-10},{910,912,+9},{910,913,-8},
1763 {933,970,+6},{933,972,-10}
1764 }
1765 },
1766#if 0 /* this set fails due to +1/-1 errors (rounding bug?), needs investigation. */
1767 { "Arial", 1024 /* usually 1/2 of EM Square */, 1024, 830, 194,
1768 2048, 668, -193, 137, 459, 229, 830, -194, 30, 9,
1769 26,
1770 {
1771 {' ','A',-51},{' ','T',-17},{' ','Y',-17},{'1','1',-68},
1772 {'A',' ',-51},{'A','T',-68},{'A','V',-68},{'A','W',-34},
1773 {'A','Y',-68},{'A','v',-17},{'A','w',-17},{'A','y',-17},
1774 {'F',',',-102},{'F','.',-102},{'F','A',-51},{'L',' ',-34},
1775 {'L','T',-68},{'L','V',-68},{'L','W',-68},{'L','Y',-68},
1776 {915,912,+73},{915,913,-84},{910,912,+76},{910,913,-68},
1777 {933,970,+54},{933,972,-83}
1778 }
1779 }
1780#endif
1781 };
1782 LOGFONTA lf;
1783 HFONT hfont, hfont_old;
1784 KERNINGPAIR *kern_pair;
1785 HDC hdc;
1786 DWORD total_kern_pairs, ret, i, n, matches;
1787
1788 hdc = GetDC(0);
1789
1790 for (i = 0; i < ARRAY_SIZE(kd); i++)
1791 {
1793 UINT uiRet;
1794
1795 if (!is_font_installed(kd[i].face_name))
1796 {
1797 skip("%s is not installed so skipping this test\n", kd[i].face_name);
1798 continue;
1799 }
1800
1801 memset(&lf, 0, sizeof(lf));
1802 strcpy(lf.lfFaceName, kd[i].face_name);
1803 lf.lfHeight = kd[i].height;
1805 ok(hfont != NULL, "failed to create a font, name %s\n", kd[i].face_name);
1806
1807 hfont_old = SelectObject(hdc, hfont);
1808
1809 SetLastError(0xdeadbeef);
1810 uiRet = GetOutlineTextMetricsW(hdc, sizeof(otm), &otm);
1811 ok(uiRet == sizeof(otm), "GetOutlineTextMetricsW error %ld\n", GetLastError());
1812
1813 ok(match_off_by_1(kd[i].tmHeight, otm.otmTextMetrics.tmHeight, FALSE), "expected %ld, got %ld\n",
1814 kd[i].tmHeight, otm.otmTextMetrics.tmHeight);
1815 ok(match_off_by_1(kd[i].tmAscent, otm.otmTextMetrics.tmAscent, FALSE), "expected %ld, got %ld\n",
1816 kd[i].tmAscent, otm.otmTextMetrics.tmAscent);
1817 ok(kd[i].tmDescent == otm.otmTextMetrics.tmDescent, "expected %ld, got %ld\n",
1818 kd[i].tmDescent, otm.otmTextMetrics.tmDescent);
1819
1820 ok(kd[i].otmEMSquare == otm.otmEMSquare, "expected %u, got %u\n",
1821 kd[i].otmEMSquare, otm.otmEMSquare);
1822 ok(kd[i].otmAscent == otm.otmAscent, "expected %d, got %d\n",
1823 kd[i].otmAscent, otm.otmAscent);
1824 ok(kd[i].otmDescent == otm.otmDescent, "expected %d, got %d\n",
1825 kd[i].otmDescent, otm.otmDescent);
1826 ok(kd[i].otmLineGap == otm.otmLineGap, "expected %u, got %u\n",
1827 kd[i].otmLineGap, otm.otmLineGap);
1828 ok(near_match(kd[i].otmMacDescent, otm.otmMacDescent), "expected %d, got %d\n",
1829 kd[i].otmMacDescent, otm.otmMacDescent);
1830 ok(near_match(kd[i].otmMacAscent, otm.otmMacAscent), "expected %d, got %d\n",
1831 kd[i].otmMacAscent, otm.otmMacAscent);
1832 todo_wine
1833 ok(kd[i].otmsCapEmHeight == otm.otmsCapEmHeight, "expected %u, got %u\n",
1834 kd[i].otmsCapEmHeight, otm.otmsCapEmHeight);
1835 todo_wine
1836 ok(kd[i].otmsXHeight == otm.otmsXHeight, "expected %u, got %u\n",
1837 kd[i].otmsXHeight, otm.otmsXHeight);
1838 ok(kd[i].otmMacLineGap == otm.otmMacLineGap, "expected %u, got %u\n",
1839 kd[i].otmMacLineGap, otm.otmMacLineGap);
1840 todo_wine
1841 ok(kd[i].otmusMinimumPPEM == otm.otmusMinimumPPEM, "expected %u, got %u\n",
1842 kd[i].otmusMinimumPPEM, otm.otmusMinimumPPEM);
1843
1844 total_kern_pairs = GetKerningPairsW(hdc, 0, NULL);
1845 kern_pair = malloc(total_kern_pairs * sizeof(*kern_pair));
1846
1847 /* Win98 (GetKerningPairsA) and XP behave differently here, the test
1848 * passes on XP.
1849 */
1850 SetLastError(0xdeadbeef);
1851 ret = GetKerningPairsW(hdc, 0, kern_pair);
1853 "got error %lu, expected ERROR_INVALID_PARAMETER\n", GetLastError());
1854 ok(ret == 0, "got %lu, expected 0\n", ret);
1855
1856 ret = GetKerningPairsW(hdc, 100, NULL);
1857 ok(ret == total_kern_pairs, "got %lu, expected %lu\n", ret, total_kern_pairs);
1858
1859 ret = GetKerningPairsW(hdc, total_kern_pairs/2, kern_pair);
1860 ok(ret == total_kern_pairs/2, "got %lu, expected %lu\n", ret, total_kern_pairs/2);
1861
1862 ret = GetKerningPairsW(hdc, total_kern_pairs, kern_pair);
1863 ok(ret == total_kern_pairs, "got %lu, expected %lu\n", ret, total_kern_pairs);
1864
1865 matches = 0;
1866
1867 for (n = 0; n < ret; n++)
1868 {
1869 DWORD j;
1870
1871 for (j = 0; j < kd[i].total_kern_pairs; j++)
1872 {
1873 if (kern_pair[n].wFirst == kd[i].kern_pair[j].wFirst &&
1874 kern_pair[n].wSecond == kd[i].kern_pair[j].wSecond)
1875 {
1876 ok(kern_pair[n].iKernAmount == kd[i].kern_pair[j].iKernAmount,
1877 "pair %d:%d got %d, expected %d\n",
1878 kern_pair[n].wFirst, kern_pair[n].wSecond,
1879 kern_pair[n].iKernAmount, kd[i].kern_pair[j].iKernAmount);
1880 matches++;
1881 }
1882 }
1883 }
1884
1885 ok(matches == kd[i].total_kern_pairs, "got matches %lu, expected %lu\n",
1886 matches, kd[i].total_kern_pairs);
1887
1888 free(kern_pair);
1889
1890 SelectObject(hdc, hfont_old);
1892 }
1893
1894 ReleaseDC(0, hdc);
1895}
#define matches(FN)
Definition: match.h:70
TEXTMETRICW otmTextMetrics
Definition: wingdi.h:2960
LONG tmAscent
Definition: wingdi.h:2830
LONG tmHeight
Definition: wingdi.h:2829
LONG tmDescent
Definition: wingdi.h:2831
UINT WINAPI GetOutlineTextMetricsW(_In_ HDC hdc, _In_ UINT cjCopy, _Out_writes_bytes_opt_(cjCopy) LPOUTLINETEXTMETRICW potm)

Referenced by START_TEST().

◆ test_GetOutlineTextMetrics()

static void test_GetOutlineTextMetrics ( void  )
static

Definition at line 2182 of file font.c.

2183{
2184 OUTLINETEXTMETRICA *otm;
2185 LOGFONTA lf;
2186 HFONT hfont, hfont_old;
2187 HDC hdc;
2188 DWORD ret, otm_size;
2189 LPSTR unset_ptr;
2190 UINT fsSelection;
2191
2192 /* check fsSelection field with bold simulation */
2193 memset(&lf, 0, sizeof(lf));
2194 strcpy(lf.lfFaceName, "Wingdings");
2196
2197 /* regular face */
2198 fsSelection = get_font_fsselection(&lf);
2199 ok((fsSelection & (1 << 5)) == 0, "got 0x%x\n", fsSelection);
2200
2201 /* face with bold simulation */
2202 lf.lfWeight = FW_BOLD;
2203 fsSelection = get_font_fsselection(&lf);
2204 ok((fsSelection & (1 << 5)) != 0, "got 0x%x\n", fsSelection);
2205
2206 /* check fsSelection field with oblique simulation */
2207 memset(&lf, 0, sizeof(lf));
2208 strcpy(lf.lfFaceName, "Tahoma");
2209 lf.lfHeight = -13;
2210 lf.lfWeight = FW_NORMAL;
2213
2214 /* regular face */
2215 fsSelection = get_font_fsselection(&lf);
2216 ok((fsSelection & 1) == 0, "got 0x%x\n", fsSelection);
2217
2218 lf.lfItalic = 1;
2219 /* face with oblique simulation */
2220 fsSelection = get_font_fsselection(&lf);
2221 ok((fsSelection & 1) == 1, "got 0x%x\n", fsSelection);
2222
2223 if (!is_font_installed("Arial"))
2224 {
2225 skip("Arial is not installed\n");
2226 return;
2227 }
2228
2229 hdc = GetDC(0);
2230
2231 memset(&lf, 0, sizeof(lf));
2232 strcpy(lf.lfFaceName, "Arial");
2233 lf.lfHeight = -13;
2234 lf.lfWeight = FW_NORMAL;
2238 ok(hfont != NULL, "failed to create a font\n");
2239
2240 hfont_old = SelectObject(hdc, hfont);
2241 otm_size = GetOutlineTextMetricsA(hdc, 0, NULL);
2242
2243 otm = malloc(otm_size);
2244
2245 memset(otm, 0xAA, otm_size);
2246 SetLastError(0xdeadbeef);
2247 otm->otmSize = sizeof(*otm);
2248 ret = GetOutlineTextMetricsA(hdc, otm->otmSize, otm);
2249 ok(ret == otm->otmSize, "expected %u, got %lu, error %ld\n", otm->otmSize, ret, GetLastError());
2250 ok(otm->otmpFamilyName == NULL, "expected NULL got %p\n", otm->otmpFamilyName);
2251 ok(otm->otmpFaceName == NULL, "expected NULL got %p\n", otm->otmpFaceName);
2252 ok(otm->otmpStyleName == NULL, "expected NULL got %p\n", otm->otmpStyleName);
2253 ok(otm->otmpFullName == NULL, "expected NULL got %p\n", otm->otmpFullName);
2254
2255 memset(otm, 0xAA, otm_size);
2256 SetLastError(0xdeadbeef);
2257 ret = GetOutlineTextMetricsA(hdc, otm->otmSize, otm);
2258 ok(ret == otm->otmSize, "expected %u, got %lu, error %ld\n", otm->otmSize, ret, GetLastError());
2259 ok(otm->otmpFamilyName != NULL, "expected not NULL got %p\n", otm->otmpFamilyName);
2260 ok(otm->otmpFaceName != NULL, "expected not NULL got %p\n", otm->otmpFaceName);
2261 ok(otm->otmpStyleName != NULL, "expected not NULL got %p\n", otm->otmpStyleName);
2262 ok(otm->otmpFullName != NULL, "expected not NULL got %p\n", otm->otmpFullName);
2263
2264 /* ask about truncated data */
2265 memset(otm, 0xAA, otm_size);
2266 memset(&unset_ptr, 0xAA, sizeof(unset_ptr));
2267 SetLastError(0xdeadbeef);
2268 otm->otmSize = sizeof(*otm) - sizeof(char*);
2269 ret = GetOutlineTextMetricsA(hdc, otm->otmSize, otm);
2270 ok(ret == otm->otmSize, "expected %u, got %lu, error %ld\n", otm->otmSize, ret, GetLastError());
2271 ok(otm->otmpFamilyName == NULL, "expected NULL got %p\n", otm->otmpFamilyName);
2272 ok(otm->otmpFaceName == NULL, "expected NULL got %p\n", otm->otmpFaceName);
2273 ok(otm->otmpStyleName == NULL, "expected NULL got %p\n", otm->otmpStyleName);
2274 ok(otm->otmpFullName == unset_ptr, "expected %p got %p\n", unset_ptr, otm->otmpFullName);
2275
2276 /* check handling of NULL pointer */
2277 SetLastError(0xdeadbeef);
2278 ret = GetOutlineTextMetricsA(hdc, otm_size, NULL);
2279 ok(ret == otm_size, "expected %lu, got %lu, error %ld\n", otm_size, ret, GetLastError());
2280
2281 free(otm);
2282
2283 SelectObject(hdc, hfont_old);
2285
2286 ReleaseDC(0, hdc);
2287}
static UINT get_font_fsselection(LOGFONTA *lf)
Definition: font.c:2154
#define PROOF_QUALITY
Definition: wingdi.h:438

Referenced by START_TEST().

◆ test_GetOutlineTextMetrics_subst()

static void test_GetOutlineTextMetrics_subst ( void  )
static

Definition at line 7733 of file font.c.

7734{
7735 OUTLINETEXTMETRICA *otm;
7736 LOGFONTA lf;
7737 HFONT hfont, hfont_old;
7738 HDC hdc;
7739 DWORD ret;
7740 char face_name[LF_FACESIZE];
7741 const char* family_name;
7742
7743 if (!is_font_installed("MS SHELL DLG"))
7744 {
7745 skip("MS Shell Dlg is not installed\n");
7746 return;
7747 }
7748
7749 hdc = GetDC(0);
7750 memset(&lf, 0, sizeof(lf));
7751 strcpy(lf.lfFaceName, "MS SHELL DLG");
7754 ok(hfont != NULL, "failed to create a font\n");
7755 hfont_old = SelectObject(hdc, hfont);
7756
7757 /* face name */
7758 ret = GetTextFaceA(hdc, sizeof(face_name), face_name);
7759 ok(ret, "GetTextFace failed\n");
7760 ok(!lstrcmpiA(lf.lfFaceName, face_name), "expected %s, got %s\n", lf.lfFaceName, face_name);
7761
7763 otm = calloc(1, ret);
7765 ok(ret != 0, "GetOutlineTextMetrics failed\n");
7766
7767 /* family name */
7768 family_name = (const char*)otm + (UINT_PTR)otm->otmpFamilyName;
7769 ok(lstrcmpiA(lf.lfFaceName, family_name), "expected a real family name (e.g. Tahoma), got %s\n", family_name);
7770
7771 free(otm);
7772 SelectObject(hdc, hfont_old);
7774
7775 ReleaseDC(0, hdc);
7776}
T1_FIELD_DICT_FONTDICT family_name
Definition: t1tokens.h:30

Referenced by START_TEST().

◆ test_GetTextFace()

static void test_GetTextFace ( void  )
static

Definition at line 4484 of file font.c.

4485{
4486 static const char faceA[] = "Tahoma";
4487 static const WCHAR faceW[] = L"Tahoma";
4488 LOGFONTA fA = {0};
4489 LOGFONTW fW = {0};
4490 char bufA[LF_FACESIZE];
4491 WCHAR bufW[LF_FACESIZE];
4492 HFONT f, g;
4493 HDC dc;
4494 int n;
4495
4496 if(!is_font_installed("Tahoma"))
4497 {
4498 skip("Tahoma is not installed so skipping this test\n");
4499 return;
4500 }
4501
4502 /* 'A' case. */
4503 memcpy(fA.lfFaceName, faceA, sizeof faceA);
4504 f = CreateFontIndirectA(&fA);
4505 ok(f != NULL, "CreateFontIndirectA failed\n");
4506
4507 dc = GetDC(NULL);
4508 g = SelectObject(dc, f);
4509 n = GetTextFaceA(dc, sizeof bufA, bufA);
4510 ok(n == sizeof faceA - 1, "GetTextFaceA returned %d\n", n);
4511 ok(lstrcmpA(faceA, bufA) == 0, "GetTextFaceA\n");
4512
4513 /* Play with the count arg. */
4514 bufA[0] = 'x';
4515 n = GetTextFaceA(dc, 0, bufA);
4516 ok(n == 0, "GetTextFaceA returned %d\n", n);
4517 ok(bufA[0] == 'x', "GetTextFaceA buf[0] == %d\n", bufA[0]);
4518
4519 bufA[0] = 'x';
4520 n = GetTextFaceA(dc, 1, bufA);
4521 ok(n == 0, "GetTextFaceA returned %d\n", n);
4522 ok(bufA[0] == '\0', "GetTextFaceA buf[0] == %d\n", bufA[0]);
4523
4524 bufA[0] = 'x'; bufA[1] = 'y';
4525 n = GetTextFaceA(dc, 2, bufA);
4526 ok(n == 1, "GetTextFaceA returned %d\n", n);
4527 ok(bufA[0] == faceA[0] && bufA[1] == '\0', "GetTextFaceA didn't copy\n");
4528
4529 n = GetTextFaceA(dc, 0, NULL);
4530 ok(n == sizeof faceA, "GetTextFaceA returned %d\n", n);
4531
4533 ReleaseDC(NULL, dc);
4534
4535 /* 'W' case. */
4536 memcpy(fW.lfFaceName, faceW, sizeof faceW);
4537 SetLastError(0xdeadbeef);
4538 f = CreateFontIndirectW(&fW);
4540 {
4541 win_skip("CreateFontIndirectW is not implemented\n");
4542 return;
4543 }
4544 ok(f != NULL, "CreateFontIndirectW failed\n");
4545
4546 dc = GetDC(NULL);
4547 g = SelectObject(dc, f);
4548 n = GetTextFaceW(dc, ARRAY_SIZE(bufW), bufW);
4549 ok(n == ARRAY_SIZE(faceW), "GetTextFaceW returned %d\n", n);
4550 ok(lstrcmpW(faceW, bufW) == 0, "GetTextFaceW\n");
4551
4552 /* Play with the count arg. */
4553 bufW[0] = 'x';
4554 n = GetTextFaceW(dc, 0, bufW);
4555 ok(n == 0, "GetTextFaceW returned %d\n", n);
4556 ok(bufW[0] == 'x', "GetTextFaceW buf[0] == %d\n", bufW[0]);
4557
4558 bufW[0] = 'x';
4559 n = GetTextFaceW(dc, 1, bufW);
4560 ok(n == 1, "GetTextFaceW returned %d\n", n);
4561 ok(bufW[0] == '\0', "GetTextFaceW buf[0] == %d\n", bufW[0]);
4562
4563 bufW[0] = 'x'; bufW[1] = 'y';
4564 n = GetTextFaceW(dc, 2, bufW);
4565 ok(n == 2, "GetTextFaceW returned %d\n", n);
4566 ok(bufW[0] == faceW[0] && bufW[1] == '\0', "GetTextFaceW didn't copy\n");
4567
4568 n = GetTextFaceW(dc, 0, NULL);
4569 ok(n == ARRAY_SIZE(faceW), "GetTextFaceW returned %d\n", n);
4570
4572 ReleaseDC(NULL, dc);
4573}
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4152
GLboolean GLboolean g
Definition: glext.h:6204
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
int WINAPI GetTextFaceW(_In_ HDC hdc, _In_ int c, _Out_writes_to_opt_(c, return) LPWSTR lpName)

Referenced by START_TEST().

◆ test_GetTextMetrics()

static void test_GetTextMetrics ( void  )
static

Definition at line 4102 of file font.c.

4103{
4104 HFONT old_hf, hf;
4106 LOGFONTA lf;
4107 BOOL ret;
4108 HDC hdc;
4109 INT enumed;
4110
4111 hdc = GetDC(0);
4112
4113 memset(&lf, 0, sizeof(lf));
4115 enumed = 0;
4117
4118 /* Test a bug triggered by rounding up FreeType ppem */
4119 hf = CreateFontA(20, 0, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, DEFAULT_CHARSET,
4121 "Tahoma");
4122 ok(hf != NULL, "CreateFontA failed, error %lu\n", GetLastError());
4123 old_hf = SelectObject(hdc, hf);
4125 ok(ret, "GetTextMetricsA failed, error %lu\n", GetLastError());
4126 ok(tm.tmHeight <= 20, "Got unexpected tmHeight %ld\n", tm.tmHeight);
4127 SelectObject(hdc, old_hf);
4128 DeleteObject(hf);
4129
4130 ReleaseDC(0, hdc);
4131}
static INT CALLBACK enum_truetype_font_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
Definition: font.c:4090
#define OUT_DEFAULT_PRECIS
Definition: wingdi.h:415
HFONT WINAPI CreateFontA(_In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_opt_ LPCSTR)

Referenced by START_TEST().

◆ test_GetTextMetrics2()

static void test_GetTextMetrics2 ( const char fontname,
int  font_height 
)
static

Definition at line 4943 of file font.c.

4944{
4945 HFONT of, hf;
4946 HDC hdc;
4948 BOOL ret;
4949 int ave_width, height, width, ratio;
4950
4951 if (!is_truetype_font_installed( fontname)) {
4952 skip("%s is not installed\n", fontname);
4953 return;
4954 }
4956 ok( hdc != NULL, "CreateCompatibleDC failed\n");
4957 /* select width = 0 */
4958 hf = CreateFontA(font_height, 0, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
4961 fontname);
4962 ok( hf != NULL, "CreateFontA(%s, %d) failed\n", fontname, font_height);
4963 of = SelectObject( hdc, hf);
4964 ret = GetTextMetricsA( hdc, &tm);
4965 ok(ret, "GetTextMetricsA error %lu\n", GetLastError());
4966 height = tm.tmHeight;
4967 ave_width = tm.tmAveCharWidth;
4968 SelectObject( hdc, of);
4969 DeleteObject( hf);
4970
4971 for (width = ave_width * 2; /* nothing*/; width += ave_width)
4972 {
4975 DEFAULT_QUALITY, VARIABLE_PITCH, fontname);
4976 ok(hf != 0, "CreateFont failed\n");
4977 of = SelectObject(hdc, hf);
4979 ok(ret, "GetTextMetrics error %lu\n", GetLastError());
4980 SelectObject(hdc, of);
4981 DeleteObject(hf);
4982
4983 if (match_off_by_1(tm.tmAveCharWidth, ave_width, FALSE) || width / height > 200)
4984 break;
4985 }
4986
4987 DeleteDC(hdc);
4988
4989 ratio = width / height;
4990
4991 ok(ratio >= 90 && ratio <= 110, "expected width/height ratio 90-110, got %d\n", ratio);
4992}
#define VARIABLE_PITCH
Definition: wingdi.h:445
#define CLIP_LH_ANGLES
Definition: wingdi.h:430
#define OUT_TT_PRECIS
Definition: wingdi.h:419

Referenced by START_TEST().

◆ test_height()

static void test_height ( HDC  hdc,
const struct font_data fd 
)
static

Definition at line 1905 of file font.c.

1906{
1907 LOGFONTA lf;
1908 HFONT hfont, old_hfont;
1910 INT ret, i;
1911
1912 for (i = 0; fd[i].face_name[0]; i++)
1913 {
1914 if (!is_truetype_font_installed(fd[i].face_name))
1915 {
1916 skip("%s is not installed\n", fd[i].face_name);
1917 continue;
1918 }
1919
1920 memset(&lf, 0, sizeof(lf));
1921 lf.lfHeight = fd[i].requested_height;
1922 lf.lfWeight = fd[i].weight;
1923 strcpy(lf.lfFaceName, fd[i].face_name);
1924
1926 ok(hfont != NULL, "failed to create a font, name %s\n", fd[i].face_name);
1927
1928 old_hfont = SelectObject(hdc, hfont);
1930 ok(ret, "GetTextMetrics error %ld\n", GetLastError());
1931 if(fd[i].dpi == tm.tmDigitizedAspectX)
1932 {
1933 ok(tm.tmWeight == fd[i].weight, "%s(%d): tm.tmWeight %ld != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmWeight, fd[i].weight);
1934 ok(match_off_by_1(tm.tmHeight, fd[i].height, fd[i].exact), "%s(%d): tm.tmHeight %ld != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmHeight, fd[i].height);
1935 ok(match_off_by_1(tm.tmAscent, fd[i].ascent, fd[i].exact), "%s(%d): tm.tmAscent %ld != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmAscent, fd[i].ascent);
1936 ok(match_off_by_1(tm.tmDescent, fd[i].descent, fd[i].exact), "%s(%d): tm.tmDescent %ld != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmDescent, fd[i].descent);
1937 ok(match_off_by_1(tm.tmInternalLeading, fd[i].int_leading, fd[i].exact), "%s(%d): tm.tmInternalLeading %ld != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmInternalLeading, fd[i].int_leading);
1938 ok(tm.tmExternalLeading == fd[i].ext_leading, "%s(%d): tm.tmExternalLeading %ld != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmExternalLeading, fd[i].ext_leading);
1939 }
1940
1941 SelectObject(hdc, old_hfont);
1942 /* force GDI to use new font, otherwise Windows leaks the font reference */
1945 }
1946}

◆ test_height_selection()

static void test_height_selection ( void  )
static

Definition at line 2129 of file font.c.

2130{
2131 static const struct font_data tahoma[] =
2132 {
2133 {"Tahoma", -12, FW_NORMAL, 14, 12, 2, 2, 0, 96, TRUE },
2134 {"Tahoma", -24, FW_NORMAL, 29, 24, 5, 5, 0, 96, TRUE },
2135 {"Tahoma", -48, FW_NORMAL, 58, 48, 10, 10, 0, 96, TRUE },
2136 {"Tahoma", -96, FW_NORMAL, 116, 96, 20, 20, 0, 96, TRUE },
2137 {"Tahoma", -192, FW_NORMAL, 232, 192, 40, 40, 0, 96, TRUE },
2138 {"Tahoma", 12, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
2139 {"Tahoma", 24, FW_NORMAL, 24, 20, 4, 4, 0, 96, TRUE },
2140 {"Tahoma", 48, FW_NORMAL, 48, 40, 8, 8, 0, 96, TRUE },
2141 {"Tahoma", 96, FW_NORMAL, 96, 80, 16, 17, 0, 96, FALSE },
2142 {"Tahoma", 192, FW_NORMAL, 192, 159, 33, 33, 0, 96, TRUE },
2143 {"", 0, 0, 0, 0, 0, 0, 0, 0, 0 }
2144 };
2146 ok(hdc != NULL, "failed to create hdc\n");
2147
2148 test_height( hdc, tahoma );
2150
2151 DeleteDC(hdc);
2152}
static void test_height(void)
Definition: status.c:168
static void test_height_selection_vdmx(HDC hdc)
Definition: font.c:1962

Referenced by START_TEST().

◆ test_height_selection_vdmx()

static void test_height_selection_vdmx ( HDC  hdc)
static

Definition at line 1962 of file font.c.

1963{
1964 static const struct font_data charset_0[] = /* doesn't use VDMX */
1965 {
1966 { "wine_vdmx", 10, FW_NORMAL, 10, 8, 2, 2, 0, 96, TRUE },
1967 { "wine_vdmx", 11, FW_NORMAL, 11, 9, 2, 2, 0, 96, TRUE },
1968 { "wine_vdmx", 12, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
1969 { "wine_vdmx", 13, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
1970 { "wine_vdmx", 14, FW_NORMAL, 14, 12, 2, 2, 0, 96, TRUE },
1971 { "wine_vdmx", 15, FW_NORMAL, 15, 12, 3, 3, 0, 96, FALSE },
1972 { "wine_vdmx", 16, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
1973 { "wine_vdmx", 17, FW_NORMAL, 17, 14, 3, 3, 0, 96, TRUE },
1974 { "wine_vdmx", 18, FW_NORMAL, 18, 15, 3, 3, 0, 96, TRUE },
1975 { "wine_vdmx", 19, FW_NORMAL, 19, 16, 3, 3, 0, 96, TRUE },
1976 { "wine_vdmx", 20, FW_NORMAL, 20, 17, 3, 4, 0, 96, FALSE },
1977 { "wine_vdmx", 21, FW_NORMAL, 21, 17, 4, 4, 0, 96, TRUE },
1978 { "wine_vdmx", 22, FW_NORMAL, 22, 18, 4, 4, 0, 96, TRUE },
1979 { "wine_vdmx", 23, FW_NORMAL, 23, 19, 4, 4, 0, 96, TRUE },
1980 { "wine_vdmx", 24, FW_NORMAL, 24, 20, 4, 4, 0, 96, TRUE },
1981 { "wine_vdmx", 25, FW_NORMAL, 25, 21, 4, 4, 0, 96, TRUE },
1982 { "wine_vdmx", 26, FW_NORMAL, 26, 22, 4, 5, 0, 96, FALSE },
1983 { "wine_vdmx", 27, FW_NORMAL, 27, 22, 5, 5, 0, 96, TRUE },
1984 { "wine_vdmx", 28, FW_NORMAL, 28, 23, 5, 5, 0, 96, TRUE },
1985 { "wine_vdmx", 29, FW_NORMAL, 29, 24, 5, 5, 0, 96, TRUE },
1986 { "wine_vdmx", 30, FW_NORMAL, 30, 25, 5, 5, 0, 96, TRUE },
1987 { "wine_vdmx", 31, FW_NORMAL, 31, 26, 5, 5, 0, 96, TRUE },
1988 { "wine_vdmx", 32, FW_NORMAL, 32, 27, 5, 6, 0, 96, FALSE },
1989 { "wine_vdmx", 48, FW_NORMAL, 48, 40, 8, 8, 0, 96, TRUE },
1990 { "wine_vdmx", 64, FW_NORMAL, 64, 53, 11, 11, 0, 96, TRUE },
1991 { "wine_vdmx", 96, FW_NORMAL, 96, 80, 16, 17, 0, 96, FALSE },
1992 { "wine_vdmx", -10, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
1993 { "wine_vdmx", -11, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
1994 { "wine_vdmx", -12, FW_NORMAL, 14, 12, 2, 2, 0, 96, TRUE },
1995 { "wine_vdmx", -13, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
1996 { "wine_vdmx", -14, FW_NORMAL, 17, 14, 3, 3, 0, 96, TRUE },
1997 { "wine_vdmx", -15, FW_NORMAL, 18, 15, 3, 3, 0, 96, TRUE },
1998 { "wine_vdmx", -16, FW_NORMAL, 19, 16, 3, 3, 0, 96, TRUE },
1999 { "wine_vdmx", -17, FW_NORMAL, 21, 17, 4, 4, 0, 96, TRUE },
2000 { "wine_vdmx", -18, FW_NORMAL, 22, 18, 4, 4, 0, 96, TRUE },
2001 { "wine_vdmx", -19, FW_NORMAL, 23, 19, 4, 4, 0, 96, TRUE },
2002 { "wine_vdmx", -20, FW_NORMAL, 24, 20, 4, 4, 0, 96, TRUE },
2003 { "wine_vdmx", -21, FW_NORMAL, 25, 21, 4, 4, 0, 96, TRUE },
2004 { "wine_vdmx", -22, FW_NORMAL, 27, 22, 5, 5, 0, 96, TRUE },
2005 { "wine_vdmx", -23, FW_NORMAL, 28, 23, 5, 5, 0, 96, TRUE },
2006 { "wine_vdmx", -24, FW_NORMAL, 29, 24, 5, 5, 0, 96, TRUE },
2007 { "wine_vdmx", -25, FW_NORMAL, 30, 25, 5, 5, 0, 96, TRUE },
2008 { "wine_vdmx", -26, FW_NORMAL, 31, 26, 5, 5, 0, 96, TRUE },
2009 { "wine_vdmx", -27, FW_NORMAL, 33, 27, 6, 6, 0, 96, TRUE },
2010 { "wine_vdmx", -28, FW_NORMAL, 34, 28, 6, 6, 0, 96, TRUE },
2011 { "wine_vdmx", -29, FW_NORMAL, 35, 29, 6, 6, 0, 96, TRUE },
2012 { "wine_vdmx", -30, FW_NORMAL, 36, 30, 6, 6, 0, 96, TRUE },
2013 { "wine_vdmx", -31, FW_NORMAL, 37, 31, 6, 6, 0, 96, TRUE },
2014 { "wine_vdmx", -32, FW_NORMAL, 39, 32, 7, 7, 0, 96, TRUE },
2015 { "wine_vdmx", -48, FW_NORMAL, 58, 48, 10, 10, 0, 96, TRUE },
2016 { "wine_vdmx", -64, FW_NORMAL, 77, 64, 13, 13, 0, 96, TRUE },
2017 { "wine_vdmx", -96, FW_NORMAL, 116, 96, 20, 20, 0, 96, TRUE },
2018 { "", 0, 0, 0, 0, 0, 0, 0, 0, 0 }
2019 };
2020
2021 static const struct font_data charset_1[] = /* Uses VDMX */
2022 {
2023 { "wine_vdmx", 10, FW_NORMAL, 10, 8, 2, 2, 0, 96, TRUE },
2024 { "wine_vdmx", 11, FW_NORMAL, 11, 9, 2, 2, 0, 96, TRUE },
2025 { "wine_vdmx", 12, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
2026 { "wine_vdmx", 13, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
2027 { "wine_vdmx", 14, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
2028 { "wine_vdmx", 15, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
2029 { "wine_vdmx", 16, FW_NORMAL, 16, 13, 3, 4, 0, 96, TRUE },
2030 { "wine_vdmx", 17, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
2031 { "wine_vdmx", 18, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
2032 { "wine_vdmx", 19, FW_NORMAL, 19, 15, 4, 5, 0, 96, TRUE },
2033 { "wine_vdmx", 20, FW_NORMAL, 20, 16, 4, 5, 0, 96, TRUE },
2034 { "wine_vdmx", 21, FW_NORMAL, 21, 17, 4, 5, 0, 96, TRUE },
2035 { "wine_vdmx", 22, FW_NORMAL, 22, 18, 4, 5, 0, 96, TRUE },
2036 { "wine_vdmx", 23, FW_NORMAL, 23, 19, 4, 5, 0, 96, TRUE },
2037 { "wine_vdmx", 24, FW_NORMAL, 23, 19, 4, 5, 0, 96, TRUE },
2038 { "wine_vdmx", 25, FW_NORMAL, 25, 21, 4, 6, 0, 96, TRUE },
2039 { "wine_vdmx", 26, FW_NORMAL, 26, 22, 4, 6, 0, 96, TRUE },
2040 { "wine_vdmx", 27, FW_NORMAL, 27, 23, 4, 6, 0, 96, TRUE },
2041 { "wine_vdmx", 28, FW_NORMAL, 27, 23, 4, 5, 0, 96, TRUE },
2042 { "wine_vdmx", 29, FW_NORMAL, 29, 24, 5, 6, 0, 96, TRUE },
2043 { "wine_vdmx", 30, FW_NORMAL, 29, 24, 5, 6, 0, 96, TRUE },
2044 { "wine_vdmx", 31, FW_NORMAL, 29, 24, 5, 6, 0, 96, TRUE },
2045 { "wine_vdmx", 32, FW_NORMAL, 32, 26, 6, 8, 0, 96, TRUE },
2046 { "wine_vdmx", 48, FW_NORMAL, 48, 40, 8, 10, 0, 96, TRUE },
2047 { "wine_vdmx", 64, FW_NORMAL, 64, 54, 10, 13, 0, 96, TRUE },
2048 { "wine_vdmx", 96, FW_NORMAL, 95, 79, 16, 18, 0, 96, TRUE },
2049 { "wine_vdmx", -10, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
2050 { "wine_vdmx", -11, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
2051 { "wine_vdmx", -12, FW_NORMAL, 16, 13, 3, 4, 0, 96, TRUE },
2052 { "wine_vdmx", -13, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
2053 { "wine_vdmx", -14, FW_NORMAL, 19, 15, 4, 5, 0, 96, TRUE },
2054 { "wine_vdmx", -15, FW_NORMAL, 20, 16, 4, 5, 0, 96, TRUE },
2055 { "wine_vdmx", -16, FW_NORMAL, 21, 17, 4, 5, 0, 96, TRUE },
2056 { "wine_vdmx", -17, FW_NORMAL, 22, 18, 4, 5, 0, 96, TRUE },
2057 { "wine_vdmx", -18, FW_NORMAL, 23, 19, 4, 5, 0, 96, TRUE },
2058 { "wine_vdmx", -19, FW_NORMAL, 25, 21, 4, 6, 0, 96, TRUE },
2059 { "wine_vdmx", -20, FW_NORMAL, 26, 22, 4, 6, 0, 96, TRUE },
2060 { "wine_vdmx", -21, FW_NORMAL, 27, 23, 4, 6, 0, 96, TRUE },
2061 { "wine_vdmx", -22, FW_NORMAL, 27, 23, 4, 5, 0, 96, TRUE },
2062 { "wine_vdmx", -23, FW_NORMAL, 29, 24, 5, 6, 0, 96, TRUE },
2063 { "wine_vdmx", -24, FW_NORMAL, 32, 26, 6, 8, 0, 96, TRUE },
2064 { "wine_vdmx", -25, FW_NORMAL, 32, 26, 6, 7, 0, 96, TRUE },
2065 { "wine_vdmx", -26, FW_NORMAL, 33, 27, 6, 7, 0, 96, TRUE },
2066 { "wine_vdmx", -27, FW_NORMAL, 35, 29, 6, 8, 0, 96, TRUE },
2067 { "wine_vdmx", -28, FW_NORMAL, 36, 30, 6, 8, 0, 96, TRUE },
2068 { "wine_vdmx", -29, FW_NORMAL, 36, 30, 6, 7, 0, 96, TRUE },
2069 { "wine_vdmx", -30, FW_NORMAL, 38, 32, 6, 8, 0, 96, TRUE },
2070 { "wine_vdmx", -31, FW_NORMAL, 39, 33, 6, 8, 0, 96, TRUE },
2071 { "wine_vdmx", -32, FW_NORMAL, 40, 33, 7, 8, 0, 96, TRUE },
2072 { "wine_vdmx", -48, FW_NORMAL, 60, 50, 10, 12, 0, 96, TRUE },
2073 { "wine_vdmx", -64, FW_NORMAL, 81, 67, 14, 17, 0, 96, TRUE },
2074 { "wine_vdmx", -96, FW_NORMAL, 119, 99, 20, 23, 0, 96, TRUE },
2075 { "", 0, 0, 0, 0, 0, 0, 0, 0, 0 }
2076 };
2077
2078 static const struct vdmx_data
2079 {
2080 WORD version;
2081 BYTE bCharSet;
2082 const struct font_data *fd;
2083 } data[] =
2084 {
2085 { 0, 0, charset_0 },
2086 { 0, 1, charset_1 },
2087 { 1, 0, charset_0 },
2088 { 1, 1, charset_1 }
2089 };
2090 int i;
2091 DWORD size, num;
2092 WORD *vdmx_header;
2093 BYTE *ratio_rec;
2094 char ttf_name[MAX_PATH];
2095 void *res, *copy;
2096 BOOL ret;
2097
2098 for (i = 0; i < ARRAY_SIZE(data); i++)
2099 {
2100 res = get_res_data( "wine_vdmx.ttf", &size );
2101
2102 copy = malloc( size );
2103 memcpy( copy, res, size );
2104 vdmx_header = find_ttf_table( copy, size, MS_MAKE_TAG('V','D','M','X') );
2105 vdmx_header[0] = GET_BE_WORD( data[i].version );
2106 ok( GET_BE_WORD( vdmx_header[1] ) == 1, "got %04x\n", GET_BE_WORD( vdmx_header[1] ) );
2107 ok( GET_BE_WORD( vdmx_header[2] ) == 1, "got %04x\n", GET_BE_WORD( vdmx_header[2] ) );
2108 ratio_rec = (BYTE *)&vdmx_header[3];
2109 ratio_rec[0] = data[i].bCharSet;
2110
2111 write_tmp_file( copy, &size, ttf_name );
2112 free( copy );
2113
2114 ok( !is_truetype_font_installed("wine_vdmx"), "Already installed\n" );
2115 num = AddFontResourceExA( ttf_name, FR_PRIVATE, 0 );
2116 if (!num) win_skip("Unable to add ttf font resource\n");
2117 else
2118 {
2119 ok( is_truetype_font_installed("wine_vdmx"), "Not installed\n" );
2120 test_height( hdc, data[i].fd );
2121 RemoveFontResourceExA( ttf_name, FR_PRIVATE, 0 );
2122 }
2123 ret = DeleteFileA( ttf_name );
2125 "DeleteFile error %ld\n", GetLastError());
2126 }
2127}
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
static const WCHAR version[]
Definition: asmname.c:66
GLuint GLuint num
Definition: glext.h:9618
static void * get_res_data(const char *fontname, DWORD *rsrc_size)
Definition: font.c:120
static void * find_ttf_table(void *ttf, DWORD size, DWORD tag)
Definition: font.c:1948
static BOOL write_tmp_file(const void *data, DWORD *size, char *tmp_name)
Definition: font.c:137

Referenced by test_height_selection().

◆ test_lang_names()

static void test_lang_names ( void  )
static

Definition at line 7120 of file font.c.

7121{
7122 static const WCHAR name_cond_ja_w[] = L"\x30d5\x30a9\x30f3\x30c8\x540d Cond (ja)";
7123 static const WCHAR name_cond_ja_reg_w[] = L"\x30d5\x30a9\x30f3\x30c8\x540d Cond (ja) Reg";
7124 static const WCHAR name_cond_ja_reg_ja_w[] = L"\x30d5\x30a9\x30f3\x30c8\x540d Cond (ja) Reg (ja)";
7125 static const WCHAR name_wws_ja_w[] = L"\x30d5\x30a9\x30f3\x30c8\x540d WWS (ja)";
7126
7127 struct enum_fullname_data efnd;
7128 struct enum_fullname_data_w efnd_w;
7129 char ttf_name[MAX_PATH], ttf_name2[MAX_PATH], ttf_name3[MAX_PATH];
7130 LOGFONTA font = {0};
7131 LOGFONTW font_w = {0};
7132 int ret, i;
7133 HDC dc;
7134 const WCHAR *primary_family, *primary_fullname;
7135
7137 {
7138 skip( "Primary language is neither English nor Japanese, skipping test\n" );
7139 return;
7140 }
7141
7142 if (!write_ttf_file( "wine_langnames.ttf", ttf_name ))
7143 {
7144 skip( "Failed to create ttf file for testing\n" );
7145 return;
7146 }
7147
7148 if (!write_ttf_file( "wine_langnames2.ttf", ttf_name2 ))
7149 {
7150 skip( "Failed to create ttf file for testing\n" );
7151 DeleteFileA( ttf_name );
7152 return;
7153 }
7154
7155 if (!write_ttf_file( "wine_langnames3.ttf", ttf_name3 ))
7156 {
7157 skip( "Failed to create ttf file for testing\n" );
7158 DeleteFileA( ttf_name2 );
7159 DeleteFileA( ttf_name );
7160 return;
7161 }
7162
7163 ret = AddFontResourceExA( ttf_name, FR_PRIVATE, 0 );
7164 ok( ret, "AddFontResourceEx() failed\n" );
7165
7166 dc = GetDC( NULL );
7167
7169 {
7170 primary_family = L"Wine Lang Cond (en)";
7171 primary_fullname = L"Wine Lang Cond Reg (en)";
7172 }
7173 else
7174 {
7175 primary_family = name_cond_ja_w;
7176 primary_fullname = name_cond_ja_reg_w;
7177 }
7178
7179 for (i = 0; i < 3; ++i)
7180 {
7181 /* check that lookup by preferred or WWS family / full names or postscript FontName doesn't work */
7182
7183 strcpy( font.lfFaceName, "Wine Lang (en)" );
7184 memset( &efnd, 0, sizeof(efnd) );
7186 ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7187
7188 strcpy( font.lfFaceName, "Wine Lang Condensed Bold (ko)" );
7189 memset( &efnd, 0, sizeof(efnd) );
7191 ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7192
7193 wcscpy( font_w.lfFaceName, name_wws_ja_w );
7194 memset( &efnd_w, 0, sizeof(efnd_w) );
7195 EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
7196 ok( efnd_w.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd_w.total );
7197
7198 strcpy( font.lfFaceName, "Reg WWS (zh-tw)" );
7199 memset( &efnd, 0, sizeof(efnd) );
7201 ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7202
7203 strcpy( font.lfFaceName, "Wine Lang (en) Reg WWS (en)" );
7204 memset( &efnd, 0, sizeof(efnd) );
7206 ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7207
7208 strcpy( font.lfFaceName, "WineLangNamesRegular" );
7209 memset( &efnd, 0, sizeof(efnd) );
7211 ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7212
7213 /* then, the primary ttf family name always works */
7214
7215 wcscpy( font_w.lfFaceName, primary_family );
7216 memset( &efnd_w, 0, sizeof(efnd_w) );
7217 EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
7218 ok( efnd_w.total == min( 2, i + 1 ), "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd_w.total );
7219
7221 {
7222 wcscpy( font_w.lfFaceName, name_cond_ja_w );
7223 memset( &efnd_w, 0, sizeof(efnd_w) );
7224 EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
7225 ok( efnd_w.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd_w.total );
7226 }
7227
7228 /* if there is no primary ttf family name, the english ttf name, or postscript FamilyName are used instead */
7229
7230 strcpy( font.lfFaceName, "Wine_Lang_Names" );
7231 memset( &efnd, 0, sizeof(efnd) );
7233 if (i == 2)
7234 ok( efnd.total == 1, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7235 else
7236 ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7237
7238 /* same goes for ttf full names */
7239
7240 wcscpy( font_w.lfFaceName, primary_fullname );
7241 memset( &efnd_w, 0, sizeof(efnd_w) );
7242 EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
7243 ok( efnd_w.total == 1, "%d: EnumFontFamiliesExW unexpected count %u.\n", i, efnd_w.total );
7244
7245 if (efnd_w.total >= 1)
7246 {
7247 ok( !wcscmp( (WCHAR *)efnd_w.elf[0].elfLogFont.lfFaceName, primary_family ),
7248 "%d: (%d) unexpected lfFaceName %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[0].elfLogFont.lfFaceName) );
7249 ok( !wcscmp( (WCHAR *)efnd_w.elf[0].elfFullName, primary_fullname ),
7250 "%d: (%d) unexpected elfFullName %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[0].elfFullName) );
7251 ok( !wcscmp( (WCHAR *)efnd_w.elf[0].elfStyle, PRIMARYLANGID(GetSystemDefaultLangID()) == LANG_ENGLISH ? L"Reg (en)" : L"Reg (ja)" ),
7252 "%d: (%d) unexpected elfStyle %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[0].elfStyle) );
7253 }
7254
7256 {
7257 wcscpy( font_w.lfFaceName, name_cond_ja_reg_w );
7258 memset( &efnd_w, 0, sizeof(efnd_w) );
7259 EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
7260 ok( efnd_w.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd_w.total );
7261 }
7262
7263 wcscpy( font_w.lfFaceName, L"Wine_Lang_Names_Regular" );
7264 memset( &efnd_w, 0, sizeof(efnd_w) );
7265 EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
7266 ok( efnd_w.total == i, "%d: EnumFontFamiliesExW unexpected count %u.\n", i, efnd_w.total );
7267
7268 while (efnd_w.total--)
7269 {
7270 ok( !wcscmp( (WCHAR *)efnd_w.elf[efnd_w.total].elfLogFont.lfFaceName, efnd_w.total == 1 ? L"Wine_Lang_Names" : primary_family ),
7271 "%d: (%d) unexpected lfFaceName %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[efnd_w.total].elfLogFont.lfFaceName) );
7272 ok( !wcscmp( (WCHAR *)efnd_w.elf[efnd_w.total].elfFullName, L"Wine_Lang_Names_Regular" ),
7273 "%d: (%d) unexpected elfFullName %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[efnd_w.total].elfFullName) );
7275 ok( !wcscmp( (WCHAR *)efnd_w.elf[efnd_w.total].elfStyle, efnd_w.total == 1 ? L"Regular" : L"Reg (en)" ),
7276 "%d: (%d) unexpected elfStyle %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[efnd_w.total].elfStyle) );
7277 else
7278 ok( !wcscmp( (WCHAR *)efnd_w.elf[0].elfStyle, L"Reg (ja)" ),
7279 "%d: (%d) unexpected elfStyle %s\n", i, efnd_w.total, debugstr_w((WCHAR *)efnd_w.elf[0].elfStyle) );
7280 }
7281
7283 {
7284 wcscpy( font_w.lfFaceName, name_cond_ja_reg_ja_w );
7285 memset( &efnd_w, 0, sizeof(efnd_w) );
7286 EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
7287 ok( efnd_w.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd_w.total );
7288 }
7289
7290 /* another language can also be used for lookup, if the primary langid isn't english, then
7291 english seems to have priority, otherwise or if english is already the primary langid,
7292 the family name with the smallest langid is used as secondary lookup language. */
7293
7294 strcpy( font.lfFaceName, "Wine Lang Cond (zh-tw)" );
7295 memset( &efnd, 0, sizeof(efnd) );
7298 ok( efnd.total == min( 2, i + 1 ), "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7299 else /* (zh-tw) doesn't match here probably because there's an (en) name too */
7300 ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7301
7302 strcpy( font.lfFaceName, "Wine Lang Cond (en)" );
7303 memset( &efnd, 0, sizeof(efnd) );
7305 /* either because it's the primary language, or because it's a secondary */
7306 ok( efnd.total == min( 2, i + 1 ), "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7307
7308 wcscpy( font_w.lfFaceName, L"Wine Police d'\xe9" "criture (fr)" );
7309 memset( &efnd_w, 0, sizeof(efnd_w) );
7310 EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
7311 /* as wine_langnames3.sfd does not specify (en) name, (fr) is preferred */
7312 if (i == 2) ok( efnd_w.total == 1, "%d: EnumFontFamiliesExW unexpected count %u.\n", i, efnd_w.total );
7313 else ok( efnd_w.total == 0, "%d: EnumFontFamiliesExW unexpected count %u.\n", i, efnd_w.total );
7314
7315 /* case matching should not depend on the current locale */
7316 if (i == 2)
7317 {
7318 wcscpy( font_w.lfFaceName, L"Wine POLICE D'\xc9" "CRITURE (fr)" );
7319 memset( &efnd_w, 0, sizeof(efnd_w) );
7320 EnumFontFamiliesExW( dc, &font_w, enum_fullname_data_proc_w, (LPARAM)&efnd_w, 0 );
7321 ok( efnd_w.total == 1, "%d: EnumFontFamiliesExW unexpected count %u.\n", i, efnd_w.total );
7322 }
7323
7324 strcpy( font.lfFaceName, "Wine Lang Cond (ko)" );
7325 memset( &efnd, 0, sizeof(efnd) );
7327 ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7328
7329 /* that doesn't apply to full names */
7330
7331 strcpy( font.lfFaceName, "Wine Lang Cond Reg (zh-tw)" );
7332 memset( &efnd, 0, sizeof(efnd) );
7334 ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7335
7336 strcpy( font.lfFaceName, "Wine Lang Cond Reg (fr)" );
7337 memset( &efnd, 0, sizeof(efnd) );
7339 ok( efnd.total == 0, "%d: EnumFontFamiliesExA unexpected count %u.\n", i, efnd.total );
7340
7341 if (i == 0)
7342 {
7343 ret = AddFontResourceExA( ttf_name2, FR_PRIVATE, 0 );
7344 ok( ret, "AddFontResourceEx() failed\n" );
7345 }
7346 else if (i == 1)
7347 {
7348 ret = AddFontResourceExA( ttf_name3, FR_PRIVATE, 0 );
7349 ok( ret, "AddFontResourceEx() failed\n" );
7350 }
7351 }
7352
7353 ret = RemoveFontResourceExA( ttf_name3, FR_PRIVATE, 0 );
7354 ok( ret, "RemoveFontResourceEx() failed\n" );
7355
7356 DeleteFileA( ttf_name3 );
7357
7358 ret = RemoveFontResourceExA( ttf_name2, FR_PRIVATE, 0 );
7359 ok( ret, "RemoveFontResourceEx() failed\n" );
7360
7361 DeleteFileA( ttf_name2 );
7362
7363 ret = RemoveFontResourceExA( ttf_name, FR_PRIVATE, 0 );
7364 ok( ret, "RemoveFontResourceEx() failed\n" );
7365
7366 DeleteFileA( ttf_name );
7367 ReleaseDC( NULL, dc );
7368}
static INT CALLBACK enum_fullname_data_proc_w(const LOGFONTW *lf, const TEXTMETRICW *ntm, DWORD type, LPARAM lParam)
Definition: font.c:3204

Referenced by START_TEST().

◆ test_logfont()

static void test_logfont ( void  )
static

Definition at line 201 of file font.c.

202{
203 LOGFONTA lf;
204 HFONT hfont;
205
206 memset(&lf, 0, sizeof lf);
207
211 lf.lfHeight = 16;
212 lf.lfWidth = 16;
214
215 lstrcpyA(lf.lfFaceName, "Arial");
216 hfont = create_font("Arial", &lf);
218
219 memset(&lf, 'A', sizeof(lf));
221 ok(hfont != 0, "CreateFontIndirectA with strange LOGFONT failed\n");
222
223 lf.lfFaceName[LF_FACESIZE - 1] = 0;
224 check_font("AAA...", &lf, hfont);
226}

Referenced by START_TEST().

◆ test_long_names()

static void test_long_names ( void  )
static

Definition at line 7007 of file font.c.

7008{
7009 char ttf_name[MAX_PATH];
7010 LOGFONTA font = {0};
7011 HFONT handle_font;
7012 BOOL found_font;
7013 int ret;
7014 HDC dc;
7015
7016 if (!write_ttf_file("wine_longname.ttf", ttf_name))
7017 {
7018 skip("Failed to create ttf file for testing\n");
7019 return;
7020 }
7021
7022 dc = GetDC(NULL);
7023
7024 ret = AddFontResourceExA(ttf_name, FR_PRIVATE, 0);
7025 ok(ret, "AddFontResourceEx() failed\n");
7026
7027 strcpy(font.lfFaceName, "wine_3_this_is_a_very_long_name");
7028 found_font = FALSE;
7029 EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0);
7030 ok(found_font == TRUE, "EnumFontFamiliesExA didn't find font.\n");
7031
7032 strcpy(font.lfFaceName, "wine_2_this_is_a_very_long_name");
7033 found_font = FALSE;
7034 EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0);
7035 ok(found_font == TRUE, "EnumFontFamiliesExA didn't find font.\n");
7036
7037 strcpy(font.lfFaceName, "wine_1_this_is_a_very_long_name");
7038 found_font = FALSE;
7039 EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0);
7040 ok(found_font == FALSE, "EnumFontFamiliesExA must not find font.\n");
7041
7042 handle_font = CreateFontIndirectA(&font);
7043 ok(handle_font != NULL, "CreateFontIndirectA failed\n");
7044 DeleteObject(handle_font);
7045
7046 ret = RemoveFontResourceExA(ttf_name, FR_PRIVATE, 0);
7047 ok(ret, "RemoveFontResourceEx() failed\n");
7048
7049 DeleteFileA(ttf_name);
7050 ReleaseDC(NULL, dc);
7051}
static INT CALLBACK long_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lparam)
Definition: font.c:7000

Referenced by START_TEST().

◆ test_max_height()

static void test_max_height ( void  )
static

Definition at line 6503 of file font.c.

6504{
6505 HDC hdc;
6506 LOGFONTA lf;
6507 HFONT hfont, hfont_old;
6508 TEXTMETRICA tm1, tm;
6509 BOOL r;
6510 LONG invalid_height[] = { -65536, -123456, 123456 };
6511 size_t i;
6512
6513 memset(&tm1, 0, sizeof(tm1));
6514 memset(&lf, 0, sizeof(lf));
6515 strcpy(lf.lfFaceName, "Tahoma");
6516 lf.lfHeight = -1;
6517
6518 hdc = GetDC(NULL);
6519
6520 /* get 1 ppem value */
6522 hfont_old = SelectObject(hdc, hfont);
6523 r = GetTextMetricsA(hdc, &tm1);
6524 ok(r, "GetTextMetrics failed\n");
6525 ok(tm1.tmHeight > 0, "expected a positive value, got %ld\n", tm1.tmHeight);
6526 ok(tm1.tmAveCharWidth > 0, "expected a positive value, got %ld\n", tm1.tmAveCharWidth);
6527 DeleteObject(SelectObject(hdc, hfont_old));
6528
6529 /* test the largest value */
6530 lf.lfHeight = -((1 << 14) - 1);
6532 hfont_old = SelectObject(hdc, hfont);
6533 memset(&tm, 0, sizeof(tm));
6534 r = GetTextMetricsA(hdc, &tm);
6535 ok(r, "GetTextMetrics failed\n");
6536 ok(tm.tmHeight > tm1.tmHeight,
6537 "expected greater than 1 ppem value (%ld), got %ld\n", tm1.tmHeight, tm.tmHeight);
6538 ok(tm.tmAveCharWidth > tm1.tmAveCharWidth,
6539 "expected greater than 1 ppem value (%ld), got %ld\n", tm1.tmAveCharWidth, tm.tmAveCharWidth);
6540 DeleteObject(SelectObject(hdc, hfont_old));
6541
6542 /* test an invalid value */
6543 for (i = 0; i < ARRAY_SIZE(invalid_height); i++) {
6544 winetest_push_context("height=%ld", invalid_height[i]);
6545 lf.lfHeight = invalid_height[i];
6547 hfont_old = SelectObject(hdc, hfont);
6548 memset(&tm, 0, sizeof(tm));
6549 r = GetTextMetricsA(hdc, &tm);
6550 if (r)
6551 {
6552 ok(r, "GetTextMetrics failed\n");
6553 ok(tm.tmHeight == tm1.tmHeight,
6554 "expected 1 ppem value (%ld), got %ld\n", tm1.tmHeight, tm.tmHeight);
6555 ok(tm.tmAveCharWidth == tm1.tmAveCharWidth,
6556 "expected 1 ppem value (%ld), got %ld\n", tm1.tmAveCharWidth, tm.tmAveCharWidth);
6557 DeleteObject(SelectObject(hdc, hfont_old));
6558 }
6560 }
6561
6562 ReleaseDC(NULL, hdc);
6563 return;
6564}

Referenced by START_TEST().

◆ test_negative_width()

static void test_negative_width ( HDC  hdc,
const LOGFONTA lf 
)
static

Definition at line 3268 of file font.c.

3269{
3270 HFONT hfont, hfont_prev;
3271 DWORD ret;
3272 GLYPHMETRICS gm1, gm2;
3273 LOGFONTA lf2 = *lf;
3274 WORD idx;
3275
3276 /* negative widths are handled just as positive ones */
3277 lf2.lfWidth = -lf->lfWidth;
3278
3279 SetLastError(0xdeadbeef);
3281 ok(hfont != 0, "CreateFontIndirect error %lu\n", GetLastError());
3282 check_font("original", lf, hfont);
3283
3284 hfont_prev = SelectObject(hdc, hfont);
3285
3287 if (ret == GDI_ERROR || idx == 0xffff)
3288 {
3289 SelectObject(hdc, hfont_prev);
3291 skip("Font %s doesn't contain 'x', skipping the test\n", lf->lfFaceName);
3292 return;
3293 }
3294
3295 /* filling with 0xaa causes false pass under WINEDEBUG=warn+heap */
3296 memset(&gm1, 0xab, sizeof(gm1));
3297 SetLastError(0xdeadbeef);
3298 ret = GetGlyphOutlineA(hdc, 'x', GGO_METRICS, &gm1, 0, NULL, &mat);
3299 ok(ret != GDI_ERROR, "GetGlyphOutline error 0x%lx\n", GetLastError());
3300
3301 SelectObject(hdc, hfont_prev);
3303
3304 SetLastError(0xdeadbeef);
3305 hfont = CreateFontIndirectA(&lf2);
3306 ok(hfont != 0, "CreateFontIndirect error %lu\n", GetLastError());
3307 check_font("negative width", &lf2, hfont);
3308
3309 hfont_prev = SelectObject(hdc, hfont);
3310
3311 memset(&gm2, 0xbb, sizeof(gm2));
3312 SetLastError(0xdeadbeef);
3313 ret = GetGlyphOutlineA(hdc, 'x', GGO_METRICS, &gm2, 0, NULL, &mat);
3314 ok(ret != GDI_ERROR, "GetGlyphOutline error 0x%lx\n", GetLastError());
3315
3316 SelectObject(hdc, hfont_prev);
3318
3319 ok(gm1.gmBlackBoxX == gm2.gmBlackBoxX &&
3320 gm1.gmBlackBoxY == gm2.gmBlackBoxY &&
3321 gm1.gmptGlyphOrigin.x == gm2.gmptGlyphOrigin.x &&
3322 gm1.gmptGlyphOrigin.y == gm2.gmptGlyphOrigin.y &&
3323 gm1.gmCellIncX == gm2.gmCellIncX &&
3324 gm1.gmCellIncY == gm2.gmCellIncY,
3325 "gm1=%d,%d,%ld,%ld,%d,%d gm2=%d,%d,%ld,%ld,%d,%d\n",
3327 gm1.gmptGlyphOrigin.y, gm1.gmCellIncX, gm1.gmCellIncY,
3329 gm2.gmptGlyphOrigin.y, gm2.gmCellIncX, gm2.gmCellIncY);
3330}

Referenced by test_text_metrics().

◆ test_nonexistent_font()

static void test_nonexistent_font ( void  )
static

Definition at line 4133 of file font.c.

4134{
4135 static const struct
4136 {
4137 const char *name;
4138 int charset;
4139 } font_subst[] =
4140 {
4141 { "Times New Roman Baltic", 186 },
4142 { "Times New Roman CE", 238 },
4143 { "Times New Roman CYR", 204 },
4144 { "Times New Roman Greek", 161 },
4145 { "Times New Roman TUR", 162 }
4146 };
4147 static const struct
4148 {
4149 const char *name;
4150 int charset;
4151 } shell_subst[] =
4152 {
4153 { "MS Shell Dlg", 186 },
4154 { "MS Shell Dlg", 238 },
4155 { "MS Shell Dlg", 204 },
4156 { "MS Shell Dlg", 161 },
4157 { "MS Shell Dlg", 162 }
4158 };
4159 LOGFONTA lf;
4160 HDC hdc;
4161 HFONT hfont;
4162 CHARSETINFO csi;
4163 INT cs, expected_cs, i, ret;
4164 char buf[LF_FACESIZE];
4165
4166 expected_cs = GetACP();
4167 if (!TranslateCharsetInfo(ULongToPtr(expected_cs), &csi, TCI_SRCCODEPAGE))
4168 {
4169 skip("TranslateCharsetInfo failed for code page %d\n", expected_cs);
4170 return;
4171 }
4172 expected_cs = csi.ciCharset;
4173 trace("ACP %d -> charset %d\n", GetACP(), expected_cs);
4174
4176
4177 for (i = 0; i < ARRAY_SIZE(shell_subst); i++)
4178 {
4179 ret = is_font_installed(shell_subst[i].name);
4180 ok(ret, "%s should be enumerated\n", shell_subst[i].name);
4181 ret = is_truetype_font_installed(shell_subst[i].name);
4182 ok(ret, "%s should be enumerated\n", shell_subst[i].name);
4183
4184 memset(&lf, 0, sizeof(lf));
4185 lf.lfHeight = -13;
4186 lf.lfWeight = FW_REGULAR;
4187 strcpy(lf.lfFaceName, shell_subst[i].name);
4190 GetTextFaceA(hdc, sizeof(buf), buf);
4191 ok(!lstrcmpiA(buf, shell_subst[i].name), "expected %s, got %s\n", shell_subst[i].name, buf);
4193 ok(cs == ANSI_CHARSET, "expected ANSI_CHARSET, got %d for font %s\n", cs, shell_subst[i].name);
4194
4196
4197 memset(&lf, 0, sizeof(lf));
4198 lf.lfHeight = -13;
4199 lf.lfWeight = FW_DONTCARE;
4200 strcpy(lf.lfFaceName, shell_subst[i].name);
4203 GetTextFaceA(hdc, sizeof(buf), buf);
4204 ok(!lstrcmpiA(buf, shell_subst[i].name), "expected %s, got %s\n", shell_subst[i].name, buf);
4206 ok(cs == expected_cs || cs == ANSI_CHARSET, "expected %d, got %d for font %s\n", expected_cs, cs, shell_subst[i].name);
4208 }
4209
4210 if (!is_truetype_font_installed("Arial") ||
4211 !is_truetype_font_installed("Times New Roman"))
4212 {
4213 DeleteDC(hdc);
4214 skip("Arial or Times New Roman not installed\n");
4215 return;
4216 }
4217
4218 memset(&lf, 0, sizeof(lf));
4219 lf.lfHeight = 100;
4220 lf.lfWeight = FW_REGULAR;
4223 strcpy(lf.lfFaceName, "Nonexistent font");
4226 GetTextFaceA(hdc, sizeof(buf), buf);
4227 ok(!lstrcmpiA(buf, "Arial"), "Got %s\n", buf);
4229 ok(cs == ANSI_CHARSET, "expected ANSI_CHARSET, got %d\n", cs);
4231
4232 memset(&lf, 0, sizeof(lf));
4233 lf.lfHeight = -13;
4234 lf.lfWeight = FW_DONTCARE;
4235 strcpy(lf.lfFaceName, "Nonexistent font");
4238 GetTextFaceA(hdc, sizeof(buf), buf);
4239 todo_wine /* Wine uses Arial for all substitutions */
4240 ok(!lstrcmpiA(buf, "Nonexistent font") /* XP, Vista */ ||
4241 !lstrcmpiA(buf, "MS Sans Serif"), /* win2k3 */
4242 "Got %s\n", buf);
4244 ok(cs == expected_cs || cs == ANSI_CHARSET, "expected %d, got %d\n", expected_cs, cs);
4246
4247 memset(&lf, 0, sizeof(lf));
4248 lf.lfHeight = -13;
4249 lf.lfWeight = FW_REGULAR;
4250 strcpy(lf.lfFaceName, "Nonexistent font");
4253 GetTextFaceA(hdc, sizeof(buf), buf);
4254 ok(!lstrcmpiA(buf, "Arial"), "Got %s\n", buf);
4256 ok(cs == ANSI_CHARSET, "expected ANSI_CHARSET, got %d\n", cs);
4258
4259 memset(&lf, 0, sizeof(lf));
4260 lf.lfHeight = -13;
4261 lf.lfWeight = FW_DONTCARE;
4262 strcpy(lf.lfFaceName, "Times New Roman");
4265 GetTextFaceA(hdc, sizeof(buf), buf);
4266 ok(!lstrcmpiA(buf, "Times New Roman"), "Got %s\n", buf);
4268 ok(cs == ANSI_CHARSET, "expected ANSI_CHARSET, got %d\n", cs);
4270
4271 for (i = 0; i < ARRAY_SIZE(font_subst); i++)
4272 {
4273 ret = is_font_installed(font_subst[i].name);
4274 todo_wine
4275 ok(ret, "%s should be enumerated\n", font_subst[i].name);
4276 ret = is_truetype_font_installed(font_subst[i].name);
4277 todo_wine
4278 ok(ret, "%s should be enumerated\n", font_subst[i].name);
4279
4280 memset(&lf, 0, sizeof(lf));
4281 lf.lfHeight = -13;
4282 lf.lfWeight = FW_REGULAR;
4283 strcpy(lf.lfFaceName, font_subst[i].name);
4287 if (font_subst[i].charset == expected_cs)
4288 {
4289 ok(cs == expected_cs, "expected %d, got %d for font %s\n", expected_cs, cs, font_subst[i].name);
4290 GetTextFaceA(hdc, sizeof(buf), buf);
4291 ok(!lstrcmpiA(buf, font_subst[i].name), "expected %s, got %s\n", font_subst[i].name, buf);
4292 }
4293 else
4294 {
4295 ok(cs == ANSI_CHARSET, "expected ANSI_CHARSET, got %d for font %s\n", cs, font_subst[i].name);
4296 GetTextFaceA(hdc, sizeof(buf), buf);
4297 ok(!lstrcmpiA(buf, "Arial"), "got %s for font %s\n", buf, font_subst[i].name);
4298 }
4300
4301 memset(&lf, 0, sizeof(lf));
4302 lf.lfHeight = -13;
4303 lf.lfWeight = FW_DONTCARE;
4304 strcpy(lf.lfFaceName, font_subst[i].name);
4307 GetTextFaceA(hdc, sizeof(buf), buf);
4308 ok(!lstrcmpiA(buf, "Arial") /* Wine */ ||
4309 !lstrcmpiA(buf, font_subst[i].name) /* XP, Vista */ ||
4310 !lstrcmpiA(buf, "MS Sans Serif"), /* win2k3 */
4311 "got %s for font %s\n", buf, font_subst[i].name);
4313 ok(cs == expected_cs || cs == ANSI_CHARSET, "expected %d, got %d for font %s\n", expected_cs, cs, font_subst[i].name);
4315 }
4316
4317 DeleteDC(hdc);
4318}
#define FF_SWISS
Definition: wingdi.h:452

Referenced by START_TEST().

◆ test_oemcharset()

static void test_oemcharset ( void  )
static

Definition at line 4604 of file font.c.

4605{
4606 HDC hdc;
4607 LOGFONTA lf, clf;
4608 HFONT hfont, old_hfont;
4609 int charset;
4610
4612 ZeroMemory(&lf, sizeof(lf));
4613 lf.lfHeight = 12;
4616 lstrcpyA(lf.lfFaceName, "Terminal");
4618 old_hfont = SelectObject(hdc, hfont);
4620 todo_wine
4621 ok(charset == OEM_CHARSET, "expected %d charset, got %d\n", OEM_CHARSET, charset);
4622 hfont = SelectObject(hdc, old_hfont);
4623 GetObjectA(hfont, sizeof(clf), &clf);
4624 ok(!lstrcmpA(clf.lfFaceName, lf.lfFaceName), "expected %s face name, got %s\n", lf.lfFaceName, clf.lfFaceName);
4625 ok(clf.lfPitchAndFamily == lf.lfPitchAndFamily, "expected %x family, got %x\n", lf.lfPitchAndFamily, clf.lfPitchAndFamily);
4626 ok(clf.lfCharSet == lf.lfCharSet, "expected %d charset, got %d\n", lf.lfCharSet, clf.lfCharSet);
4627 ok(clf.lfHeight == lf.lfHeight, "expected %ld height, got %ld\n", lf.lfHeight, clf.lfHeight);
4629 DeleteDC(hdc);
4630}
#define ZeroMemory
Definition: minwinbase.h:31
#define FF_MODERN
Definition: wingdi.h:449
#define OEM_CHARSET
Definition: wingdi.h:400

Referenced by START_TEST().

◆ test_orientation()

static void test_orientation ( void  )
static

Definition at line 4575 of file font.c.

4576{
4577 static const char test_str[11] = "Test String";
4578 HDC hdc;
4579 LOGFONTA lf;
4580 HFONT hfont, old_hfont;
4581 SIZE size;
4582
4583 if (!is_truetype_font_installed("Arial"))
4584 {
4585 skip("Arial is not installed\n");
4586 return;
4587 }
4588
4590 memset(&lf, 0, sizeof(lf));
4591 lstrcpyA(lf.lfFaceName, "Arial");
4592 lf.lfHeight = 72;
4593 lf.lfOrientation = lf.lfEscapement = 900;
4594 hfont = create_font("orientation", &lf);
4595 old_hfont = SelectObject(hdc, hfont);
4596 ok(GetTextExtentExPointA(hdc, test_str, sizeof(test_str), 32767, NULL, NULL, &size), "GetTextExtentExPointA failed\n");
4597 ok(near_match(311, size.cx), "cx should be about 311, got %ld\n", size.cx);
4598 ok(near_match(75, size.cy), "cy should be about 75, got %ld\n", size.cy);
4599 SelectObject(hdc, old_hfont);
4601 DeleteDC(hdc);
4602}
BOOL WINAPI GetTextExtentExPointA(_In_ HDC hdc, _In_reads_(cchString) LPCSTR lpszString, _In_ int cchString, _In_ int nMaxExtent, _Out_opt_ LPINT lpnFit, _Out_writes_to_opt_(cchString, *lpnFit) LPINT lpnDx, _Out_ LPSIZE lpSize)

Referenced by START_TEST().

◆ test_outline_font()

static void test_outline_font ( void  )
static

Definition at line 448 of file font.c.

449{
450 static const char test_str[11] = "Test String";
451 HDC hdc, hdc_2;
452 LOGFONTA lf;
453 HFONT hfont, old_hfont, old_hfont_2;
455 SIZE size_orig;
456 INT width_orig, height_orig, lfWidth;
457 XFORM xform;
458 GLYPHMETRICS gm;
459 MAT2 mat2 = { {0x8000,0}, {0,0}, {0,0}, {0x8000,0} };
460 POINT pt;
461 INT ret;
462
463 if (!is_truetype_font_installed("Arial"))
464 {
465 skip("Arial is not installed\n");
466 return;
467 }
468
470
471 memset(&lf, 0, sizeof(lf));
472 strcpy(lf.lfFaceName, "Arial");
473 lf.lfHeight = 72;
474 hfont = create_font("outline", &lf);
475 old_hfont = SelectObject(hdc, hfont);
476 otm.otmSize = sizeof(otm);
477 ok(GetOutlineTextMetricsA(hdc, sizeof(otm), &otm), "GetTextMetricsA failed\n");
478 ok(GetTextExtentPoint32A(hdc, test_str, sizeof(test_str), &size_orig), "GetTextExtentPoint32A failed\n");
479 ok(GetCharWidthA(hdc, 'A', 'A', &width_orig), "GetCharWidthA failed\n");
480
481 test_font_metrics("outline", hdc, hfont, lf.lfHeight, otm.otmTextMetrics.tmAveCharWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
482 SelectObject(hdc, old_hfont);
484
485 /* font of otmEMSquare height helps to avoid a lot of rounding errors */
486 lf.lfHeight = otm.otmEMSquare;
487 lf.lfHeight = -lf.lfHeight;
488 hfont = create_font("outline", &lf);
489 old_hfont = SelectObject(hdc, hfont);
490 otm.otmSize = sizeof(otm);
491 ok(GetOutlineTextMetricsA(hdc, sizeof(otm), &otm), "GetTextMetricsA failed\n");
492 ok(GetTextExtentPoint32A(hdc, test_str, sizeof(test_str), &size_orig), "GetTextExtentPoint32A failed\n");
493 ok(GetCharWidthA(hdc, 'A', 'A', &width_orig), "GetCharWidthA failed\n");
494 SelectObject(hdc, old_hfont);
496
497 height_orig = otm.otmTextMetrics.tmHeight;
498 lfWidth = otm.otmTextMetrics.tmAveCharWidth;
499
500 /* test integer scaling 3x2 */
501 lf.lfHeight = height_orig * 2;
502 lf.lfWidth = lfWidth * 3;
503 hfont = create_font("3x2", &lf);
504 old_hfont = SelectObject(hdc, hfont);
505 test_font_metrics("outline 3x2", hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 3, 2);
506 SelectObject(hdc, old_hfont);
508
509 /* test integer scaling 3x3 */
510 lf.lfHeight = height_orig * 3;
511 lf.lfWidth = lfWidth * 3;
512 hfont = create_font("3x3", &lf);
513 old_hfont = SelectObject(hdc, hfont);
514 test_font_metrics("outline 3x3", hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 3, 3);
515 SelectObject(hdc, old_hfont);
517
518 /* test integer scaling 1x1 */
519 lf.lfHeight = height_orig * 1;
520 lf.lfWidth = lfWidth * 1;
521 hfont = create_font("1x1", &lf);
522 old_hfont = SelectObject(hdc, hfont);
523 test_font_metrics("outline 1x1", hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
524 SelectObject(hdc, old_hfont);
526
527 /* test integer scaling 1x1 */
528 lf.lfHeight = height_orig;
529 lf.lfWidth = 0;
530 hfont = create_font("1x1", &lf);
531 old_hfont = SelectObject(hdc, hfont);
532 test_font_metrics("outline 1x0", hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
533
534 /* with an identity matrix */
535 memset(&gm, 0, sizeof(gm));
536 SetLastError(0xdeadbeef);
537 ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
538 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %ld\n", GetLastError());
539 ok(gm.gmCellIncX == width_orig, "incX %d != %d\n", gm.gmCellIncX, width_orig);
540 ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
541 /* with a custom matrix */
542 memset(&gm, 0, sizeof(gm));
543 SetLastError(0xdeadbeef);
544 ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat2);
545 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %ld\n", GetLastError());
546 ok(gm.gmCellIncX == width_orig/2, "incX %d != %d\n", gm.gmCellIncX, width_orig/2);
547 ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
548
549 /* Test that changing the DC transformation affects only the font
550 * selected on this DC and doesn't affect the same font selected on
551 * another DC.
552 */
553 hdc_2 = CreateCompatibleDC(0);
554 old_hfont_2 = SelectObject(hdc_2, hfont);
555 test_font_metrics("dc2.base", hdc_2, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
556
558
559 /* font metrics on another DC should be unchanged */
560 test_font_metrics("dc2.aniso", hdc_2, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
561
562 /* test restrictions of compatibility mode GM_COMPATIBLE */
563 /* part 1: rescaling only X should not change font scaling on screen.
564 So compressing the X axis by 2 is not done, and this
565 appears as X scaling of 2 that no one requested. */
566 SetWindowExtEx(hdc, 100, 100, NULL);
567 SetViewportExtEx(hdc, 50, 100, NULL);
568 test_font_metrics("xscaling", hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 2, 1);
569 /* font metrics on another DC should be unchanged */
570 test_font_metrics("dc2.xscaling", hdc_2, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
571
572 /* part 2: rescaling only Y should change font scaling.
573 As also X is scaled by a factor of 2, but this is not
574 requested by the DC transformation, we get a scaling factor
575 of 2 in the X coordinate. */
576 SetViewportExtEx(hdc, 100, 200, NULL);
577 test_font_metrics("yscaling", hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 2, 1);
578 /* font metrics on another DC should be unchanged */
579 test_font_metrics("dc2.yscaling", hdc_2, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
580
581 /* restore scaling */
583
584 /* font metrics on another DC should be unchanged */
585 test_font_metrics("dc2.text", hdc_2, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
586
587 SelectObject(hdc_2, old_hfont_2);
588 DeleteDC(hdc_2);
589
591 {
592 SelectObject(hdc, old_hfont);
594 DeleteDC(hdc);
595 skip("GM_ADVANCED is not supported on this platform\n");
596 return;
597 }
598
599 xform.eM11 = 20.0f;
600 xform.eM12 = 0.0f;
601 xform.eM21 = 0.0f;
602 xform.eM22 = 20.0f;
603 xform.eDx = 0.0f;
604 xform.eDy = 0.0f;
605
606 SetLastError(0xdeadbeef);
607 ret = SetWorldTransform(hdc, &xform);
608 ok(ret, "SetWorldTransform error %lu\n", GetLastError());
609
610 test_font_metrics("xform", hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
611
612 /* with an identity matrix */
613 memset(&gm, 0, sizeof(gm));
614 SetLastError(0xdeadbeef);
615 ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
616 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %ld\n", GetLastError());
617 pt.x = width_orig; pt.y = 0;
618 LPtoDP(hdc, &pt, 1);
619 ok(gm.gmCellIncX == pt.x, "incX %d != %ld\n", gm.gmCellIncX, pt.x);
620 ok(gm.gmCellIncX == 20 * width_orig, "incX %d != %d\n", gm.gmCellIncX, 20 * width_orig);
621 ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
622 /* with a custom matrix */
623 memset(&gm, 0, sizeof(gm));
624 SetLastError(0xdeadbeef);
625 ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat2);
626 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %ld\n", GetLastError());
627 pt.x = width_orig; pt.y = 0;
628 LPtoDP(hdc, &pt, 1);
629 ok(gm.gmCellIncX == pt.x/2, "incX %d != %ld\n", gm.gmCellIncX, pt.x/2);
630 ok(near_match(gm.gmCellIncX, 10 * width_orig), "incX %d != %d\n", gm.gmCellIncX, 10 * width_orig);
631 ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
632
633 SetLastError(0xdeadbeef);
635 ok(ret == MM_TEXT, "expected MM_TEXT, got %d, error %lu\n", ret, GetLastError());
636
637 test_font_metrics("lometric", hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
638
639 /* with an identity matrix */
640 memset(&gm, 0, sizeof(gm));
641 SetLastError(0xdeadbeef);
642 ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
643 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %ld\n", GetLastError());
644 pt.x = width_orig; pt.y = 0;
645 LPtoDP(hdc, &pt, 1);
646 ok(near_match(gm.gmCellIncX, pt.x), "incX %d != %ld\n", gm.gmCellIncX, pt.x);
647 ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
648 /* with a custom matrix */
649 memset(&gm, 0, sizeof(gm));
650 SetLastError(0xdeadbeef);
651 ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat2);
652 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %ld\n", GetLastError());
653 pt.x = width_orig; pt.y = 0;
654 LPtoDP(hdc, &pt, 1);
655 ok(near_match(gm.gmCellIncX, (pt.x + 1)/2), "incX %d != %ld\n", gm.gmCellIncX, (pt.x + 1)/2);
656 ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
657
658 SetLastError(0xdeadbeef);
660 ok(ret == MM_LOMETRIC, "expected MM_LOMETRIC, got %d, error %lu\n", ret, GetLastError());
661
662 test_font_metrics("text", hdc, hfont, lf.lfHeight, lf.lfWidth, test_str, sizeof(test_str), &otm.otmTextMetrics, &size_orig, width_orig, 1, 1);
663
664 /* with an identity matrix */
665 memset(&gm, 0, sizeof(gm));
666 SetLastError(0xdeadbeef);
667 ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
668 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %ld\n", GetLastError());
669 pt.x = width_orig; pt.y = 0;
670 LPtoDP(hdc, &pt, 1);
671 ok(gm.gmCellIncX == pt.x, "incX %d != %ld\n", gm.gmCellIncX, pt.x);
672 ok(gm.gmCellIncX == 20 * width_orig, "incX %d != %d\n", gm.gmCellIncX, 20 * width_orig);
673 ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
674 /* with a custom matrix */
675 memset(&gm, 0, sizeof(gm));
676 SetLastError(0xdeadbeef);
677 ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat2);
678 ok(ret != GDI_ERROR, "GetGlyphOutlineA error %ld\n", GetLastError());
679 pt.x = width_orig; pt.y = 0;
680 LPtoDP(hdc, &pt, 1);
681 ok(gm.gmCellIncX == pt.x/2, "incX %d != %ld\n", gm.gmCellIncX, pt.x/2);
682 ok(gm.gmCellIncX == 10 * width_orig, "incX %d != %d\n", gm.gmCellIncX, 10 * width_orig);
683 ok(gm.gmCellIncY == 0, "incY %d != 0\n", gm.gmCellIncY);
684
685 SelectObject(hdc, old_hfont);
687 DeleteDC(hdc);
688}
FLOAT eDy
Definition: wingdi.h:2172
FLOAT eM11
Definition: wingdi.h:2167
FLOAT eM21
Definition: wingdi.h:2169
FLOAT eM22
Definition: wingdi.h:2170
FLOAT eM12
Definition: wingdi.h:2168
FLOAT eDx
Definition: wingdi.h:2171
BOOL WINAPI LPtoDP(_In_ HDC hdc, _Inout_updates_(c) LPPOINT lppt, _In_ int c)
#define MM_LOMETRIC
Definition: wingdi.h:872
#define MM_TEXT
Definition: wingdi.h:873
BOOL WINAPI SetWorldTransform(_In_ HDC, _In_ const XFORM *)

Referenced by START_TEST().

◆ test_realization_info()

static void test_realization_info ( const char name,
DWORD  size,
BOOL  is_memory_resource 
)
static

Definition at line 5105 of file font.c.

5106{
5108 struct file_info file_info;
5109 HFONT hfont, hfont_prev;
5110 SIZE_T needed;
5111 LOGFONTA lf;
5112 BYTE *data;
5113 BOOL ret;
5114 HDC hdc;
5115
5116 if (!pGetFontRealizationInfo)
5117 return;
5118
5119 memset(&lf, 0, sizeof(lf));
5120 lf.lfHeight = 72;
5121 strcpy(lf.lfFaceName, name);
5122
5124 ok(hfont != 0, "Failed to create a font, %lu.\n", GetLastError());
5125
5126 hdc = GetDC(NULL);
5127
5128 hfont_prev = SelectObject(hdc, hfont);
5129 ok(hfont_prev != NULL, "Failed to select font.\n");
5130
5131 memset(&info, 0xcc, sizeof(info));
5132 info.size = sizeof(info);
5133 ret = pGetFontRealizationInfo(hdc, (DWORD *)&info);
5134 ok(ret != 0, "Unexpected return value %d.\n", ret);
5135
5136 ok((info.flags & 0xf) == 0x3, "Unexpected flags %#lx.\n", info.flags);
5137 ok(info.cache_num != 0, "Unexpected cache num %lu.\n", info.cache_num);
5138 ok(info.instance_id != 0, "Unexpected instance id %lu.\n", info.instance_id);
5139 ok(info.simulations == 0, "Unexpected simulations %#x.\n", info.simulations);
5140 ok(info.face_index == 0, "Unexpected face index %u.\n", info.face_index);
5141
5142 ret = pGetFontFileInfo(info.instance_id, 0, NULL, 0, NULL);
5143 ok(ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected return value %d, error %ld.\n",
5144 ret, GetLastError());
5145
5146 needed = 0;
5147 ret = pGetFontFileInfo(info.instance_id, 0, NULL, 0, &needed);
5148 ok(ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected return value %d, error %ld.\n",
5149 ret, GetLastError());
5150
5151 ret = pGetFontFileInfo(info.instance_id, 0, &file_info, 0, NULL);
5152 ok(ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected return value %d, error %ld.\n",
5153 ret, GetLastError());
5154
5155 ret = pGetFontFileInfo(info.instance_id, 0, &file_info, needed - 1, NULL);
5156 ok(ret == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected return value %d, error %ld.\n",
5157 ret, GetLastError());
5158
5159 ret = pGetFontFileInfo(info.instance_id, 0, &file_info, needed, NULL);
5160 ok(ret != 0, "Failed to get font file info, ret %d gle %ld.\n", ret, GetLastError());
5161
5162 memset(&file_info, 0xcc, sizeof(file_info));
5163 ret = pGetFontFileInfo(info.instance_id, 0, &file_info, sizeof(file_info), NULL);
5164 ok(ret != 0, "Failed to get font file info, ret %d gle %ld.\n", ret, GetLastError());
5165 if (ret)
5166 {
5167 ok(is_memory_resource ? file_info.size.QuadPart == size : file_info.size.QuadPart > 0, "Unexpected file size.\n");
5168 ok(is_memory_resource ? !file_info.path[0] : file_info.path[0], "Unexpected file path %s.\n",
5170 }
5171
5173 data = malloc(size + 16);
5174
5175 memset(data, 0xcc, size);
5176 ret = pGetFontFileData(info.instance_id, 0, 0, data, size);
5177 ok(ret != 0, "Failed to get font file data, %ld\n", GetLastError());
5178 ok(*(DWORD *)data == 0x00000100, "Unexpected sfnt header version %#lx.\n", *(DWORD *)data);
5179 ok(*(WORD *)(data + 4) == 0x0e00, "Unexpected table count %#x.\n", *(WORD *)(data + 4));
5180
5181 /* Larger than font data size. */
5182 memset(data, 0xcc, size);
5183 ret = pGetFontFileData(info.instance_id, 0, 0, data, size + 16);
5184 ok(ret == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "Unexpected return value %d, error %ld\n",
5185 ret, GetLastError());
5186 ok(*(DWORD *)data == 0xcccccccc, "Unexpected buffer contents %#lx.\n", *(DWORD *)data);
5187
5188 /* With offset. */
5189 memset(data, 0xcc, size);
5190 ret = pGetFontFileData(info.instance_id, 0, 16, data, size - 16);
5191 ok(ret != 0, "Failed to get font file data, %ld\n", GetLastError());
5192 ok(*(DWORD *)data == 0x1000000, "Unexpected buffer contents %#lx.\n", *(DWORD *)data);
5193
5194 memset(data, 0xcc, size);
5195 ret = pGetFontFileData(info.instance_id, 0, 16, data, size);
5196 ok(ret == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "Unexpected return value %d, error %ld\n",
5197 ret, GetLastError());
5198 ok(*(DWORD *)data == 0xcccccccc, "Unexpected buffer contents %#lx.\n", *(DWORD *)data);
5199
5200 /* Zero buffer size. */
5201 memset(data, 0xcc, size);
5202 ret = pGetFontFileData(info.instance_id, 0, 16, data, 0);
5203 todo_wine
5204 ok(ret == 0 && GetLastError() == ERROR_NOACCESS, "Unexpected return value %d, error %ld\n", ret, GetLastError());
5205 ok(*(DWORD *)data == 0xcccccccc, "Unexpected buffer contents %#lx.\n", *(DWORD *)data);
5206
5207 free(data);
5208
5209 SelectObject(hdc, hfont_prev);
5211 ReleaseDC(NULL, hdc);
5212}
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define wine_dbgstr_w
Definition: kernel32.h:34
LARGE_INTEGER size
Definition: font.c:4334
WCHAR * info
Definition: actctx.c:140
WCHAR path[MAX_PATH]
Definition: font.c:4335
ULONG_PTR SIZE_T
Definition: typedefs.h:80
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
#define ERROR_NOACCESS
Definition: winerror.h:902

Referenced by test_AddFontMemResource().

◆ test_RealizationInfo()

static void test_RealizationInfo ( void  )
static

Definition at line 4338 of file font.c.

4339{
4340 struct realization_info_t
4341 {
4342 DWORD flags;
4343 DWORD cache_num;
4344 DWORD instance_id;
4345 };
4346
4347 struct file_info file_info;
4348 HDC hdc;
4349 DWORD info[4], info2[32], read;
4350 HFONT hfont, hfont_old;
4351 SIZE_T needed;
4352 LOGFONTA lf;
4353 HANDLE h;
4354 BYTE file[16], data[14];
4355 FILETIME time;
4357 BOOL r;
4358
4359 if(!pGdiRealizationInfo)
4360 {
4361 win_skip("GdiRealizationInfo not available\n");
4362 return;
4363 }
4364
4365 hdc = GetDC(0);
4366
4367 memset(info, 0xcc, sizeof(info));
4368 r = pGdiRealizationInfo(hdc, info);
4369 ok(r != 0, "ret 0\n");
4370 ok((info[0] & 0xf) == 1, "info[0] = %lx for the system font\n", info[0]);
4371 ok(info[3] == 0xcccccccc, "structure longer than 3 dwords\n");
4372
4373 if (!is_truetype_font_installed("Tahoma"))
4374 {
4375 skip("skipping GdiRealizationInfo with truetype font\n");
4376 goto end;
4377 }
4378
4379 memset(&lf, 0, sizeof(lf));
4380 strcpy(lf.lfFaceName, "Tahoma");
4381 lf.lfHeight = 20;
4382 lf.lfWeight = FW_BOLD;
4383 lf.lfItalic = 1;
4385 hfont_old = SelectObject(hdc, hfont);
4386
4387 memset(info, 0xcc, sizeof(info));
4388 r = pGdiRealizationInfo(hdc, info);
4389 ok(r != 0, "ret 0\n");
4390 ok((info[0] & 0xf) == 3, "info[0] = %lx for arial\n", info[0]);
4391 ok(info[3] == 0xcccccccc, "structure longer than 3 dwords\n");
4392
4393 if (pGetFontRealizationInfo)
4394 {
4395 struct font_realization_info *fri = (struct font_realization_info*)info2;
4396 struct realization_info_t *ri = (struct realization_info_t*)info;
4397
4398 /* The first DWORD represents a struct size. On a
4399 newly rebooted system setting this to < 16 results
4400 in GetFontRealizationInfo failing. However there
4401 appears to be some caching going on which results
4402 in calls after a successful call also succeeding even
4403 if the size < 16. This means we can't reliably test
4404 this behaviour. */
4405
4406 memset(info2, 0xcc, sizeof(info2));
4407 info2[0] = 16;
4408 r = pGetFontRealizationInfo(hdc, info2);
4409 ok(r != 0, "ret 0\n");
4410 /* We may get the '24' version here if that has been previously
4411 requested. */
4412 ok(fri->size == 16 || fri->size == 24, "got %ld\n", info2[0]);
4413 ok(fri->flags == ri->flags, "flags mismatch\n");
4414 ok(fri->cache_num == ri->cache_num, "cache_num mismatch\n");
4415 ok(fri->instance_id == ri->instance_id, "instance id mismatch\n");
4416 ok(info2[6] == 0xcccccccc, "got wrong dword 6, 0x%08lx\n", info2[6]);
4417
4418 memset(info2, 0xcc, sizeof(info2));
4419 info2[0] = 28;
4420 r = pGetFontRealizationInfo(hdc, info2);
4421 ok(r == FALSE, "got %d\n", r);
4422
4423 memset(info2, 0xcc, sizeof(info2));
4424 info2[0] = 24;
4425 r = pGetFontRealizationInfo(hdc, info2);
4426 ok(r != 0, "ret 0\n");
4427 ok(fri->size == 24, "got %ld\n", fri->size);
4428 ok(fri->flags == ri->flags, "flags mismatch\n");
4429 ok(fri->cache_num == ri->cache_num, "cache_num mismatch\n");
4430 ok(fri->instance_id == ri->instance_id, "instance id mismatch\n");
4431 ok(fri->simulations == 0x2, "got simulations flags 0x%04x\n", fri->simulations);
4432 ok(fri->face_index == 0, "got wrong face index %u\n", fri->face_index);
4433 ok(info2[6] == 0xcccccccc, "structure longer than 6 dwords\n");
4434
4435 /* Test GetFontFileInfo() */
4436 /* invalid font id */
4437 SetLastError(0xdeadbeef);
4438 r = pGetFontFileInfo(0xabababab, 0, &file_info, sizeof(file_info), &needed);
4439 ok(r == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "ret %d gle %ld\n", r, GetLastError());
4440
4441 needed = 0;
4442 r = pGetFontFileInfo(fri->instance_id, 0, &file_info, sizeof(file_info), &needed);
4443 ok(r != 0, "Failed to get font file info, error %ld.\n", GetLastError());
4444
4445 if (r)
4446 {
4447 ok(needed > 0 && needed < sizeof(file_info), "Unexpected required size.\n");
4448
4450 ok(h != INVALID_HANDLE_VALUE, "Unable to open file %ld\n", GetLastError());
4451
4452 GetFileTime(h, NULL, NULL, &time);
4453 ok(!CompareFileTime(&file_info.time, &time), "time mismatch\n");
4454 GetFileSizeEx(h, &size);
4455 ok(file_info.size.QuadPart == size.QuadPart, "size mismatch\n");
4456
4457 /* Read first 16 bytes from the file */
4458 ReadFile(h, file, sizeof(file), &read, NULL);
4459 CloseHandle(h);
4460
4461 /* shorter buffer */
4462 SetLastError(0xdeadbeef);
4463 r = pGetFontFileInfo(fri->instance_id, 0, &file_info, needed - 1, &needed);
4464 ok(r == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "ret %d gle %ld\n", r, GetLastError());
4465 }
4466
4467 /* Get bytes 2 - 16 using GetFontFileData */
4468 r = pGetFontFileData(fri->instance_id, 0, 2, data, sizeof(data));
4469 ok(r != 0, "ret 0 gle %ld\n", GetLastError());
4470
4471 ok(!memcmp(data, file + 2, sizeof(data)), "mismatch\n");
4472 }
4473
4474 DeleteObject(SelectObject(hdc, hfont_old));
4475
4476 end:
4477 ReleaseDC(0, hdc);
4478}
#define read
Definition: acwin.h:96
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define CreateFileW
Definition: compat.h:741
#define GetFileSizeEx
Definition: compat.h:757
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI GetFileTime(IN HANDLE hFile, OUT LPFILETIME lpCreationTime OPTIONAL, OUT LPFILETIME lpLastAccessTime OPTIONAL, OUT LPFILETIME lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:880
LONG WINAPI CompareFileTime(IN CONST FILETIME *lpFileTime1, IN CONST FILETIME *lpFileTime2)
Definition: time.c:106
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
__u16 time
Definition: mkdosfs.c:8
FILETIME time
Definition: font.c:4333

Referenced by START_TEST().

◆ test_select_object()

static void test_select_object ( void  )
static

Definition at line 7707 of file font.c.

7708{
7709 HFONT hfont, old_font;
7710 LOGFONTA lf;
7711
7712 memset(&lf, 0, sizeof lf);
7713
7716 lf.lfWeight = FW_DONTCARE;
7717 lf.lfHeight = 16;
7718 lf.lfWidth = 16;
7720
7721 lstrcpyA(lf.lfFaceName, "Arial");
7722 hfont = create_font("Arial", &lf);
7723
7724 SetLastError(0xdeadbeef);
7725 old_font = SelectObject(NULL, hfont);
7726 ok(!old_font, "SelectObject returned %p\n", old_font);
7727 ok(GetLastError() == ERROR_INVALID_HANDLE, "GetLastError() = %lu\n",
7728 GetLastError());
7729
7731}
#define ERROR_INVALID_HANDLE
Definition: compat.h:98

Referenced by START_TEST().

◆ test_SetTextJustification()

static void test_SetTextJustification ( void  )
static

Definition at line 2366 of file font.c.

2367{
2368 HDC hdc;
2369 RECT clientArea;
2370 LOGFONTA lf;
2371 HFONT hfont;
2372 HWND hwnd;
2373 SIZE size, expect;
2374 int i;
2375 WORD indices[2];
2376 static const char testText[] =
2377 "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
2378 "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut "
2379 "enim ad minim veniam, quis nostrud exercitation ullamco laboris "
2380 "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in "
2381 "reprehenderit in voluptate velit esse cillum dolore eu fugiat "
2382 "nulla pariatur. Excepteur sint occaecat cupidatat non proident, "
2383 "sunt in culpa qui officia deserunt mollit anim id est laborum.";
2384
2385 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0, 400,400, 0, 0, 0, NULL);
2386 GetClientRect( hwnd, &clientArea );
2387 hdc = GetDC( hwnd );
2388
2389 if (!is_font_installed("Times New Roman"))
2390 {
2391 skip("Times New Roman is not installed\n");
2392 return;
2393 }
2394
2395 memset(&lf, 0, sizeof lf);
2398 lf.lfWeight = FW_DONTCARE;
2399 lf.lfHeight = 20;
2401 lstrcpyA(lf.lfFaceName, "Times New Roman");
2402 hfont = create_font("Times New Roman", &lf);
2404
2405 testJustification("default", hdc, testText, &clientArea);
2406
2407 GetGlyphIndicesA( hdc, "A ", 2, indices, 0 );
2408
2410 GetTextExtentPoint32A(hdc, " ", 1, &expect);
2411 GetTextExtentPoint32A(hdc, " ", 3, &size);
2412 ok( size.cx == 3 * expect.cx, "wrong size %ld/%ld\n", size.cx, expect.cx );
2414 GetTextExtentPoint32A(hdc, " ", 1, &size);
2415 ok( size.cx == expect.cx + 4, "wrong size %ld/%ld\n", size.cx, expect.cx );
2417 GetTextExtentPoint32A(hdc, " ", 2, &size);
2418 ok( size.cx == 2 * expect.cx + 9, "wrong size %ld/%ld\n", size.cx, expect.cx );
2420 GetTextExtentPoint32A(hdc, " ", 3, &size);
2421 ok( size.cx == 3 * expect.cx + 7, "wrong size %ld/%ld\n", size.cx, expect.cx );
2424 GetTextExtentPoint32A(hdc, " ", 3, &size);
2425 ok( size.cx == 3 * (expect.cx + 2) + 7, "wrong size %ld/%ld\n", size.cx, expect.cx );
2428 size.cx = size.cy = 1234;
2429 GetTextExtentPoint32A(hdc, " ", 0, &size);
2430 ok( size.cx == 0 && size.cy == 0, "wrong size %ld,%ld\n", size.cx, size.cy );
2434 ok( size.cx == expect.cx + 5, "wrong size %ld/%ld\n", size.cx, expect.cx );
2436
2438 SetWindowExtEx( hdc, 2, 2, NULL );
2439 GetClientRect( hwnd, &clientArea );
2440 DPtoLP( hdc, (POINT *)&clientArea, 2 );
2441 testJustification("2x2", hdc, testText, &clientArea);
2442
2443 GetTextExtentPoint32A(hdc, "A", 1, &expect);
2444 for (i = 0; i < 10; i++)
2445 {
2447 GetTextExtentPoint32A(hdc, "A", 1, &size);
2448 ok( size.cx == expect.cx + i, "wrong size %ld/%ld+%d\n", size.cx, expect.cx, i );
2449 }
2452 for (i = 0; i < 10; i++)
2453 {
2456 ok( size.cx == expect.cx + i, "wrong size %ld/%ld+%d\n", size.cx, expect.cx, i );
2457 }
2459
2460 SetViewportExtEx( hdc, 3, 3, NULL );
2461 GetClientRect( hwnd, &clientArea );
2462 DPtoLP( hdc, (POINT *)&clientArea, 2 );
2463 testJustification("3x3", hdc, testText, &clientArea);
2464
2465 GetTextExtentPoint32A(hdc, "A", 1, &expect);
2466 for (i = 0; i < 10; i++)
2467 {
2469 GetTextExtentPoint32A(hdc, "A", 1, &size);
2470 ok( size.cx == expect.cx + i, "wrong size %ld/%ld+%d\n", size.cx, expect.cx, i );
2471 }
2472
2474 ReleaseDC(hwnd, hdc);
2476}
static void testJustification(const char *context, HDC hdc, PCSTR str, RECT *clientArea)
Definition: font.c:2289
#define expect(expected, got)
Definition: font.c:40
BOOL WINAPI GetTextExtentExPointI(_In_ HDC hdc, _In_reads_(cwchString) LPWORD lpwszString, _In_ int cwchString, _In_ int nMaxExtent, _Out_opt_ LPINT lpnFit, _Out_writes_to_opt_(cwchString, *lpnFit) LPINT lpnDx, _Out_ LPSIZE lpSize)
int WINAPI SetTextCharacterExtra(_In_ HDC, _In_ int)
BOOL WINAPI SetTextJustification(_In_ HDC, _In_ int, _In_ int)
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)

Referenced by START_TEST().

◆ test_stock_fonts()

static void test_stock_fonts ( void  )
static

Definition at line 6382 of file font.c.

6383{
6384 static const int font[] =
6385 {
6387 /* SYSTEM_FIXED_FONT, OEM_FIXED_FONT */
6388 };
6389 static const struct test_data
6390 {
6391 int charset, weight, height, height_pixels, dpi;
6392 const char face_name[LF_FACESIZE];
6393 WORD lang_id;
6394 } td[][17] =
6395 {
6396 { /* ANSI_FIXED_FONT */
6397 { ANSI_CHARSET, FW_NORMAL, 12, 12, 96, "Courier", LANG_ARABIC },
6398 { ANSI_CHARSET, FW_NORMAL, 12, 12, 96, "Courier", LANG_HEBREW},
6399 { DEFAULT_CHARSET, FW_NORMAL, 12, 13, 96, "Courier" },
6400 { DEFAULT_CHARSET, FW_NORMAL, 12, 13, 120, "Courier" },
6401 { 0 }
6402 },
6403 { /* ANSI_VAR_FONT */
6404 { DEFAULT_CHARSET, FW_NORMAL, 12, 13, 96, "MS Sans Serif" },
6405 { DEFAULT_CHARSET, FW_NORMAL, 12, 13, 120, "MS Sans Serif" },
6406 { 0 }
6407 },
6408 { /* SYSTEM_FONT */
6409 { SHIFTJIS_CHARSET, FW_NORMAL, 18, 18, 96, "System" },
6410 { SHIFTJIS_CHARSET, FW_NORMAL, 22, 22, 120, "System" },
6411 { HANGEUL_CHARSET, FW_NORMAL, 16, 16, 96, "System" },
6412 { HANGEUL_CHARSET, FW_NORMAL, 20, 20, 120, "System" },
6413 { DEFAULT_CHARSET, FW_BOLD, 16, 16, 96, "System" },
6414 { DEFAULT_CHARSET, FW_BOLD, 20, 20, 120, "System" },
6415 { 0 }
6416 },
6417 { /* DEVICE_DEFAULT_FONT */
6418 { SHIFTJIS_CHARSET, FW_NORMAL, 18, 18, 96, "System" },
6419 { SHIFTJIS_CHARSET, FW_NORMAL, 22, 22, 120, "System" },
6420 { HANGEUL_CHARSET, FW_NORMAL, 16, 16, 96, "System" },
6421 { HANGEUL_CHARSET, FW_NORMAL, 20, 20, 120, "System" },
6422 { DEFAULT_CHARSET, FW_BOLD, 16, 16, 96, "System" },
6423 { DEFAULT_CHARSET, FW_BOLD, 20, 20, 120, "System" },
6424 { 0 }
6425 },
6426 { /* DEFAULT_GUI_FONT */
6427 { SHIFTJIS_CHARSET, FW_NORMAL, -11, 13, 96, "MS Shell Dlg" },
6428 { SHIFTJIS_CHARSET, FW_NORMAL, -13, 16, 120, "MS Shell Dlg" },
6429 { SHIFTJIS_CHARSET, FW_NORMAL, -12, 15, 96, "?MS UI Gothic" },
6430 { SHIFTJIS_CHARSET, FW_NORMAL, -15, 18, 120, "?MS UI Gothic" },
6431 { HANGEUL_CHARSET, FW_NORMAL, -11, 13, 96, "MS Shell Dlg" },
6432 { HANGEUL_CHARSET, FW_NORMAL, -13, 16, 120, "MS Shell Dlg" },
6433 { HANGEUL_CHARSET, FW_NORMAL, -12, 15, 96, "?Gulim" },
6434 { HANGEUL_CHARSET, FW_NORMAL, -15, 18, 120, "?Gulim" },
6435 { GB2312_CHARSET, FW_NORMAL, -11, 13, 96, "MS Shell Dlg" },
6436 { GB2312_CHARSET, FW_NORMAL, -13, 16, 120, "MS Shell Dlg" },
6437 { GB2312_CHARSET, FW_NORMAL, -12, 15, 96, "?SimHei" },
6438 { GB2312_CHARSET, FW_NORMAL, -15, 18, 120, "?SimHei" },
6439 { CHINESEBIG5_CHARSET, FW_NORMAL, -12, 15, 96, "?MingLiU" },
6440 { CHINESEBIG5_CHARSET, FW_NORMAL, -15, 18, 120, "?MingLiU" },
6441 { DEFAULT_CHARSET, FW_NORMAL, -11, 13, 96, "MS Shell Dlg" },
6442 { DEFAULT_CHARSET, FW_NORMAL, -13, 16, 120, "MS Shell Dlg" },
6443 { 0 }
6444 }
6445 };
6446 int i, j;
6447
6448 for (i = 0; i < ARRAY_SIZE(font); i++)
6449 {
6450 HFONT hfont;
6451 LOGFONTA lf;
6452 int ret, height;
6453
6455 ok(hfont != 0, "%d: GetStockObject(%d) failed\n", i, font[i]);
6456
6457 ret = GetObjectA(hfont, sizeof(lf), &lf);
6458 ok(ret == sizeof(lf), "%d: GetObject returned %d instead of sizeof(LOGFONT)\n", i, ret);
6459
6460 for (j = 0; td[i][j].face_name[0] != 0; j++)
6461 {
6462 if ((lf.lfCharSet != td[i][j].charset && td[i][j].charset != DEFAULT_CHARSET) ||
6463 (system_lang_id != td[i][j].lang_id && td[i][j].lang_id != LANG_NEUTRAL) ||
6464 (td[i][j].face_name[0] != '?' && strcmp(lf.lfFaceName, td[i][j].face_name)))
6465 {
6466 continue;
6467 }
6468
6469 ret = get_font_dpi(&lf, &height);
6470 if (ret != td[i][j].dpi)
6471 {
6472 trace("%d(%d): font %s %d dpi doesn't match test data %d\n",
6473 i, j, lf.lfFaceName, ret, td[i][j].dpi);
6474 continue;
6475 }
6476
6477 /* FIXME: Remove once Wine is fixed */
6478 todo_wine_if (td[i][j].dpi != 96 &&
6479 /* MS Sans Serif for 120 dpi and higher should include 12 pixel bitmap set */
6480 ((!strcmp(td[i][j].face_name, "MS Sans Serif") && td[i][j].height == 12) ||
6481 /* System for 120 dpi and higher should include 20 pixel bitmap set */
6482 (!strcmp(td[i][j].face_name, "System") && td[i][j].height > 16)))
6483 ok(height == td[i][j].height_pixels, "%d(%d): expected height %d, got %d\n", i, j, td[i][j].height_pixels, height);
6484
6485 ok(td[i][j].weight == lf.lfWeight, "%d(%d): expected lfWeight %d, got %ld\n", i, j, td[i][j].weight, lf.lfWeight);
6486 ok(td[i][j].height == lf.lfHeight, "%d(%d): expected lfHeight %d, got %ld\n", i, j, td[i][j].height, lf.lfHeight);
6487 if (td[i][j].face_name[0] == '?')
6488 {
6489 /* Wine doesn't have this font, skip this case for now.
6490 Actually, the face name is localized on Windows and varies
6491 dpending on Windows versions (e.g. Japanese NT4 vs win2k). */
6492 trace("%d(%d): default gui font is %s\n", i, j, lf.lfFaceName);
6493 }
6494 else
6495 {
6496 ok(!strcmp(td[i][j].face_name, lf.lfFaceName), "%d(%d): expected lfFaceName %s, got %s\n", i, j, td[i][j].face_name, lf.lfFaceName);
6497 }
6498 break;
6499 }
6500 }
6501}
#define d
Definition: ke_i.h:81
BOOL expected
Definition: store.c:2000
static int get_font_dpi(const LOGFONTA *lf, int *height)
Definition: font.c:6360
#define LANG_NEUTRAL
Definition: nls.h:22
weight
Definition: sortkey.c:157
#define ANSI_FIXED_FONT
Definition: wingdi.h:906
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define ANSI_VAR_FONT
Definition: wingdi.h:907
#define DEFAULT_GUI_FONT
Definition: wingdi.h:909
#define SYSTEM_FONT
Definition: wingdi.h:911
#define DEVICE_DEFAULT_FONT
Definition: wingdi.h:908

Referenced by START_TEST().

◆ test_text_extents()

static void test_text_extents ( void  )
static

Definition at line 1399 of file font.c.

1400{
1401 static const WCHAR wt[] = L"One\ntwo 3";
1402 LPINT extents;
1403 INT i, len, fit1, fit2, extents2[3];
1404 LOGFONTA lf;
1406 HDC hdc;
1407 HFONT hfont;
1408 SIZE sz;
1409 SIZE sz1, sz2;
1410 BOOL ret;
1411
1412 memset(&lf, 0, sizeof(lf));
1413 strcpy(lf.lfFaceName, "Arial");
1414 lf.lfHeight = 20;
1415
1417 hdc = GetDC(0);
1420 ret = GetTextExtentPointA(hdc, "o", 1, &sz);
1421 ok(ret, "got %d\n", ret);
1422 ok(sz.cy == tm.tmHeight, "cy %ld tmHeight %ld\n", sz.cy, tm.tmHeight);
1423
1424 memset(&sz, 0xcc, sizeof(sz));
1425 ret = GetTextExtentPointA(hdc, "o", 0, &sz);
1426 ok(ret, "got %d\n", ret);
1427 ok(sz.cx == 0 && sz.cy == 0, "cx %ld, cy %ld\n", sz.cx, sz.cy);
1428
1429 memset(&sz, 0xcc, sizeof(sz));
1430 ret = GetTextExtentPointA(hdc, "", 0, &sz);
1431 ok(ret, "got %d\n", ret);
1432 ok(sz.cx == 0 && sz.cy == 0, "cx %ld, cy %ld\n", sz.cx, sz.cy);
1433
1434 memset(&sz, 0xcc, sizeof(sz));
1435 ret = GetTextExtentPointW(hdc, wt, 0, &sz);
1436 ok(ret, "got %d\n", ret);
1437 ok(sz.cx == 0 && sz.cy == 0, "cx %ld, cy %ld\n", sz.cx, sz.cy);
1438
1439 memset(&sz, 0xcc, sizeof(sz));
1440 ret = GetTextExtentPointW(hdc, L"", 0, &sz);
1441 ok(ret, "got %d\n", ret);
1442 ok(sz.cx == 0 && sz.cy == 0, "cx %ld, cy %ld\n", sz.cx, sz.cy);
1443
1444 len = lstrlenW(wt);
1445 extents = calloc(len, sizeof extents[0]);
1446 extents[0] = 1; /* So that the increasing sequence test will fail
1447 if the extents array is untouched. */
1448 GetTextExtentExPointW(hdc, wt, len, 32767, &fit1, extents, &sz1);
1449 GetTextExtentPointW(hdc, wt, len, &sz2);
1450 ok(sz1.cy == sz2.cy,
1451 "cy from GetTextExtentExPointW (%ld) and GetTextExtentPointW (%ld) differ\n", sz1.cy, sz2.cy);
1452 /* Because of the '\n' in the string GetTextExtentExPoint and
1453 GetTextExtentPoint return different widths under Win2k, but
1454 under WinXP they return the same width. So we don't test that
1455 here. */
1456
1457 for (i = 1; i < len; ++i)
1458 ok(extents[i-1] <= extents[i],
1459 "GetTextExtentExPointW generated a non-increasing sequence of partial extents (at position %d)\n",
1460 i);
1461 ok(extents[len-1] == sz1.cx, "GetTextExtentExPointW extents and size don't match\n");
1462 ok(0 <= fit1 && fit1 <= len, "GetTextExtentExPointW generated illegal value %d for fit\n", fit1);
1463 ok(0 < fit1, "GetTextExtentExPointW says we can't even fit one letter in 32767 logical units\n");
1464 GetTextExtentExPointW(hdc, wt, len, extents[2], &fit2, NULL, &sz2);
1465 ok(sz1.cx == sz2.cx && sz1.cy == sz2.cy, "GetTextExtentExPointW returned different sizes for the same string\n");
1466 ok(fit2 == 3, "GetTextExtentExPointW extents isn't consistent with fit\n");
1467 GetTextExtentExPointW(hdc, wt, len, extents[2]-1, &fit2, NULL, &sz2);
1468 ok(fit2 == 2, "GetTextExtentExPointW extents isn't consistent with fit\n");
1469 GetTextExtentExPointW(hdc, wt, 2, 0, NULL, extents + 2, &sz2);
1470 ok(extents[0] == extents[2] && extents[1] == extents[3],
1471 "GetTextExtentExPointW with lpnFit == NULL returns incorrect results\n");
1472 GetTextExtentExPointW(hdc, wt, 2, 0, NULL, NULL, &sz1);
1473 ok(sz1.cx == sz2.cx && sz1.cy == sz2.cy,
1474 "GetTextExtentExPointW with lpnFit and alpDx both NULL returns incorrect results\n");
1475
1476 /* extents functions fail with -ve counts (the interesting case being -1) */
1477 ret = GetTextExtentPointA(hdc, "o", -1, &sz);
1478 ok(ret == FALSE, "got %d\n", ret);
1479 ret = GetTextExtentExPointA(hdc, "o", -1, 0, NULL, NULL, &sz);
1480 ok(ret == FALSE, "got %d\n", ret);
1481 ret = GetTextExtentExPointW(hdc, wt, -1, 0, NULL, NULL, &sz1);
1482 ok(ret == FALSE, "got %d\n", ret);
1483
1484 /* max_extent = 0 succeeds and returns zero */
1485 fit1 = fit2 = -215;
1486 ret = GetTextExtentExPointA(hdc, NULL, 0, 0, &fit1, NULL, &sz);
1487 ok(ret == TRUE, "got %d\n", ret);
1488 ok(fit1 == 0, "fit = %d\n", fit1);
1489 ret = GetTextExtentExPointW(hdc, NULL, 0, 0, &fit2, NULL, &sz1);
1490 ok(ret == TRUE, "got %d\n", ret);
1491 ok(fit2 == 0, "fit = %d\n", fit2);
1492
1493 /* max_extent = -1 is interpreted as a very large width that will
1494 * definitely fit our three characters */
1495 fit1 = fit2 = -215;
1496 ret = GetTextExtentExPointA(hdc, "One", 3, -1, &fit1, NULL, &sz);
1497 ok(ret == TRUE, "got %d\n", ret);
1498 ok(fit1 == 3, "fit = %d\n", fit1);
1499 ret = GetTextExtentExPointW(hdc, wt, 3, -1, &fit2, NULL, &sz);
1500 ok(ret == TRUE, "got %d\n", ret);
1501 ok(fit2 == 3, "fit = %d\n", fit2);
1502
1503 /* max_extent = -2 is interpreted similarly, but the Ansi version
1504 * rejects it while the Unicode one accepts it */
1505 fit1 = fit2 = -215;
1506 ret = GetTextExtentExPointA(hdc, "One", 3, -2, &fit1, NULL, &sz);
1507 ok(ret == FALSE, "got %d\n", ret);
1508 ok(fit1 == -215, "fit = %d\n", fit1);
1509 ret = GetTextExtentExPointW(hdc, wt, 3, -2, &fit2, NULL, &sz);
1510 ok(ret == TRUE, "got %d\n", ret);
1511 ok(fit2 == 3, "fit = %d\n", fit2);
1512
1515
1516 /* non-MM_TEXT mapping mode */
1517 lf.lfHeight = 2000;
1520
1522 ret = GetTextExtentExPointW(hdc, wt, 3, 0, NULL, extents, &sz);
1523 ok(ret, "got %d\n", ret);
1524 ok(sz.cx == extents[2], "got %ld vs %d\n", sz.cx, extents[2]);
1525
1526 ret = GetTextExtentExPointW(hdc, wt, 3, extents[1], &fit1, extents2, &sz2);
1527 ok(ret, "got %d\n", ret);
1528 ok(fit1 == 2, "got %d\n", fit1);
1529 ok(sz2.cx == sz.cx, "got %ld vs %ld\n", sz2.cx, sz.cx);
1530 for(i = 0; i < 2; i++)
1531 ok(extents2[i] == extents[i], "%d: %d, %d\n", i, extents2[i], extents[i]);
1532
1535 free(extents);
1536 ReleaseDC(NULL, hdc);
1537}
int * LPINT
Definition: minwindef.h:151
#define MM_HIMETRIC
Definition: wingdi.h:869
BOOL WINAPI GetTextExtentPointW(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpString, _In_ int c, _Out_ LPSIZE lpsz)
BOOL WINAPI GetTextExtentExPointW(_In_ HDC hdc, _In_reads_(cchString) LPCWSTR lpszString, _In_ int cchString, _In_ int nMaxExtent, _Out_opt_ LPINT lpnFit, _Out_writes_to_opt_(cchString, *lpnFit) LPINT lpnDx, _Out_ LPSIZE lpSize)

Referenced by START_TEST().

◆ test_text_metrics()

static void test_text_metrics ( const LOGFONTA lf,
const NEWTEXTMETRICA ntm 
)
static

Definition at line 3853 of file font.c.

3854{
3855 HDC hdc;
3856 HFONT hfont, hfont_old;
3857 TEXTMETRICA tmA;
3858 TT_OS2_V4 tt_os2;
3859 LONG size, ret;
3860 const char *font_name = lf->lfFaceName;
3861 DWORD cmap_first = 0, cmap_last = 0;
3862 UINT ascent, descent, cell_height;
3864 BOOL sys_lang_non_english;
3865
3866 sys_lang_non_english = PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH;
3867 hdc = GetDC(0);
3868
3869 SetLastError(0xdeadbeef);
3871 ok(hfont != 0, "CreateFontIndirect error %lu\n", GetLastError());
3872
3873 hfont_old = SelectObject(hdc, hfont);
3874
3875 size = GetFontData(hdc, MS_OS2_TAG, 0, NULL, 0);
3876 if (size == GDI_ERROR)
3877 {
3878 trace("OS/2 chunk was not found\n");
3879 goto end_of_test;
3880 }
3881 if (size > sizeof(tt_os2))
3882 {
3883 trace("got too large OS/2 chunk of size %lu\n", size);
3884 size = sizeof(tt_os2);
3885 }
3886
3887 memset(&tt_os2, 0, sizeof(tt_os2));
3888 ret = GetFontData(hdc, MS_OS2_TAG, 0, &tt_os2, size);
3889 ok(ret >= TT_OS2_V0_SIZE && ret <= size, "GetFontData should return size from [%lu,%lu] not %lu\n", TT_OS2_V0_SIZE,
3890 size, ret);
3891
3892 SetLastError(0xdeadbeef);
3893 ret = GetTextMetricsA(hdc, &tmA);
3894 ok(ret, "GetTextMetricsA error %lu\n", GetLastError());
3895
3896 if(!get_first_last_from_cmap(hdc, &cmap_first, &cmap_last, &cmap_type))
3897 {
3898 skip("%s is not a Windows font, OS/2 metrics may be invalid.\n",font_name);
3899 }
3900 else
3901 {
3902 USHORT expect_first_A, expect_last_A, expect_break_A, expect_default_A;
3903 USHORT expect_first_W, expect_last_W, expect_break_W, expect_default_W;
3904 UINT os2_first_char, os2_last_char, default_char, break_char;
3906 TEXTMETRICW tmW;
3907
3908 ascent = GET_BE_WORD(tt_os2.usWinAscent);
3909 descent = abs((SHORT)GET_BE_WORD(tt_os2.usWinDescent));
3910 cell_height = ascent + descent;
3911 ok(ntm->ntmCellHeight == cell_height, "%s: ntmCellHeight %u != %u, os2.usWinAscent/os2.usWinDescent %u/%u\n",
3912 font_name, ntm->ntmCellHeight, cell_height, ascent, descent);
3913
3914 /* NEWTEXTMETRIC's scaling method is different from TEXTMETRIC's */
3915#define SCALE_NTM(value) (MulDiv(ntm->tmHeight, (value), cell_height))
3916 size = MulDiv(32, ntm->ntmCellHeight, ntm->ntmSizeEM);
3917 ok(ntm->tmHeight == size, "%s: ntm->tmHeight %ld != %ld (%u/%u)\n",
3918 font_name, ntm->tmHeight, size, ntm->ntmCellHeight, ntm->ntmSizeEM);
3919 size = SCALE_NTM(ntm->ntmAvgWidth);
3920 ok(ntm->tmAveCharWidth == size, "%s: ntm->tmAveCharWidth %ld != %ld (%u/%u,%ld)\n",
3921 font_name, ntm->tmAveCharWidth, size, ntm->ntmAvgWidth, cell_height, ntm->tmHeight);
3922 size = SCALE_NTM(ascent);
3923 ok(ntm->tmAscent == size, "%s: ntm->tmAscent %ld != %ld (%u/%u,%ld)\n",
3924 font_name, ntm->tmAscent, size, ascent, cell_height, ntm->tmHeight);
3925 size = ntm->tmHeight - ntm->tmAscent;
3926 ok(ntm->tmDescent == size, "%s: ntm->tmDescent %ld != %ld (%u/%u,%ld)\n",
3927 font_name, ntm->tmDescent, size, descent, cell_height, ntm->tmHeight);
3928 size = SCALE_NTM(cell_height - ntm->ntmSizeEM);
3929 ok(ntm->tmInternalLeading == size, "%s: ntm->tmInternalLeading %ld != %ld (%u/%u,%ld)\n",
3930 font_name, ntm->tmInternalLeading, size, cell_height - ntm->ntmSizeEM, cell_height, ntm->tmHeight);
3931#undef SCALE_NTM
3932
3933 version = GET_BE_WORD(tt_os2.version);
3934
3935 os2_first_char = GET_BE_WORD(tt_os2.usFirstCharIndex);
3936 os2_last_char = GET_BE_WORD(tt_os2.usLastCharIndex);
3937 default_char = GET_BE_WORD(tt_os2.usDefaultChar);
3938 break_char = GET_BE_WORD(tt_os2.usBreakChar);
3939
3940 if (winetest_debug > 1)
3941 trace("font %s charset %u: %x-%x (%lx-%lx) default %x break %x OS/2 version %u vendor %4.4s\n",
3942 font_name, lf->lfCharSet, os2_first_char, os2_last_char, cmap_first, cmap_last,
3943 default_char, break_char, version, (LPCSTR)&tt_os2.achVendID);
3944
3945 if (cmap_type == cmap_ms_symbol || (cmap_first >= 0xf000 && cmap_first < 0xf100))
3946 {
3947 expect_first_W = 0;
3948 switch(GetACP())
3949 {
3950 case 1255: /* Hebrew */
3951 expect_last_W = 0xf896;
3952 break;
3953 case 1257: /* Baltic */
3954 expect_last_W = 0xf8fd;
3955 break;
3956 default:
3957 expect_last_W = 0xf0ff;
3958 }
3959 expect_break_W = 0x20;
3960 expect_default_W = expect_break_W - 1;
3961 expect_first_A = 0x1e;
3962 expect_last_A = min(os2_last_char - os2_first_char + 0x20, 0xff);
3963 }
3964 else
3965 {
3966 expect_first_W = cmap_first;
3967 expect_last_W = cmap_last;
3968 if(os2_first_char <= 1)
3969 expect_break_W = os2_first_char + 2;
3970 else if(os2_first_char > 0xff)
3971 expect_break_W = 0x20;
3972 else
3973 expect_break_W = os2_first_char;
3974 expect_default_W = expect_break_W - 1;
3975 expect_first_A = expect_default_W - 1;
3976 expect_last_A = min(os2_last_char, 0xff);
3977 }
3978 expect_break_A = expect_break_W;
3979 expect_default_A = expect_default_W;
3980
3981 /* Wine currently uses SYMBOL_CHARSET to identify whether the ANSI metrics need special handling */
3982 todo_wine_if(cmap_type != cmap_ms_symbol && tmA.tmCharSet == SYMBOL_CHARSET && expect_first_A != 0x1e)
3983 ok(tmA.tmFirstChar == expect_first_A,
3984 "A: tmFirstChar for %s got %02x expected %02x\n", font_name, tmA.tmFirstChar, expect_first_A);
3985 if (pGdiGetCodePage == NULL || ! IsDBCSLeadByteEx(pGdiGetCodePage(hdc), tmA.tmLastChar))
3986 todo_wine_if(expect_last_A != 0 && expect_last_A != 0xff) ok(tmA.tmLastChar == expect_last_A,
3987 "A: tmLastChar for %s got %02x expected %02x\n", font_name, tmA.tmLastChar, expect_last_A);
3988 else
3989 skip("tmLastChar is DBCS lead byte\n");
3990 ok(tmA.tmBreakChar == expect_break_A, "A: tmBreakChar for %s got %02x expected %02x\n",
3991 font_name, tmA.tmBreakChar, expect_break_A);
3992 ok(tmA.tmDefaultChar == expect_default_A || broken(sys_lang_non_english),
3993 "A: tmDefaultChar for %s got %02x expected %02x\n",
3994 font_name, tmA.tmDefaultChar, expect_default_A);
3995
3996
3997 SetLastError(0xdeadbeef);
3998 ret = GetTextMetricsW(hdc, &tmW);
4001 if (ret)
4002 {
4003 /* Wine uses the os2 first char */
4004 todo_wine_if(cmap_first != os2_first_char && cmap_type != cmap_ms_symbol)
4005 ok(tmW.tmFirstChar == expect_first_W, "W: tmFirstChar for %s got %02x expected %02x\n",
4006 font_name, tmW.tmFirstChar, expect_first_W);
4007
4008 /* Wine uses the os2 last char */
4009 todo_wine_if(expect_last_W != os2_last_char && cmap_type != cmap_ms_symbol)
4010 ok(tmW.tmLastChar == expect_last_W, "W: tmLastChar for %s got %02x expected %02x\n",
4011 font_name, tmW.tmLastChar, expect_last_W);
4012 ok(tmW.tmBreakChar == expect_break_W, "W: tmBreakChar for %s got %02x expected %02x\n",
4013 font_name, tmW.tmBreakChar, expect_break_W);
4014 ok(tmW.tmDefaultChar == expect_default_W || broken(sys_lang_non_english),
4015 "W: tmDefaultChar for %s got %02x expected %02x\n",
4016 font_name, tmW.tmDefaultChar, expect_default_W);
4017
4018 /* Test the aspect ratio while we have tmW */
4020 ok(tmW.tmDigitizedAspectX == ret, "W: tmDigitizedAspectX %lu != %lu\n",
4021 tmW.tmDigitizedAspectX, ret);
4023 ok(tmW.tmDigitizedAspectX == ret, "W: tmDigitizedAspectY %lu != %lu\n",
4024 tmW.tmDigitizedAspectX, ret);
4025 }
4026 }
4027
4028 /* test FF_ values */
4029 switch(tt_os2.panose.bFamilyType)
4030 {
4031 case PAN_ANY:
4032 case PAN_NO_FIT:
4035 default:
4036 if((tmA.tmPitchAndFamily & 1) == 0 || /* fixed */
4038 {
4039 expect_ff(&tmA, &tt_os2, FF_MODERN, font_name);
4040 break;
4041 }
4042 switch(tt_os2.panose.bSerifStyle)
4043 {
4044 case PAN_ANY:
4045 case PAN_NO_FIT:
4046 default:
4047 expect_ff(&tmA, &tt_os2, FF_DONTCARE, font_name);
4048 break;
4049
4050 case PAN_SERIF_COVE:
4054 case PAN_SERIF_SQUARE:
4055 case PAN_SERIF_THIN:
4056 case PAN_SERIF_BONE:
4058 case PAN_SERIF_TRIANGLE:
4059 expect_ff(&tmA, &tt_os2, FF_ROMAN, font_name);
4060 break;
4061
4065 case PAN_SERIF_FLARED:
4066 case PAN_SERIF_ROUNDED:
4067 expect_ff(&tmA, &tt_os2, FF_SWISS, font_name);
4068 break;
4069 }
4070 break;
4071
4072 case PAN_FAMILY_SCRIPT:
4073 expect_ff(&tmA, &tt_os2, FF_SCRIPT, font_name);
4074 break;
4075
4077 expect_ff(&tmA, &tt_os2, FF_DECORATIVE, font_name);
4078 break;
4079 }
4080
4082
4083end_of_test:
4084 SelectObject(hdc, hfont_old);
4086
4087 ReleaseDC(0, hdc);
4088}
Definition: ehthrow.cxx:93
#define MS_OS2_TAG
Definition: font.c:116
for(i=0;i< ARRAY_SIZE(offsets);i++)
GLdouble s
Definition: gl.h:2039
#define error(str)
Definition: mkdosfs.c:1605
static void test_negative_width(HDC hdc, const LOGFONTA *lf)
Definition: font.c:3268
#define SCALE_NTM(value)
static void expect_ff(const TEXTMETRICA *tmA, const TT_OS2_V4 *os2, WORD family, const char *name)
Definition: font.c:3438
#define TT_OS2_V0_SIZE
Definition: font.c:3385
static BOOL get_first_last_from_cmap(HDC hdc, DWORD *first, DWORD *last, cmap_type *cmap_type)
Definition: font.c:3519
USHORT usLastCharIndex
Definition: font.c:3360
USHORT version
Definition: font.c:3336
USHORT usDefaultChar
Definition: font.c:3376
USHORT usWinDescent
Definition: font.c:3369
USHORT usFirstCharIndex
Definition: font.c:3359
USHORT usWinAscent
Definition: font.c:3368
USHORT usBreakChar
Definition: font.c:3377
CHAR achVendID[4]
Definition: font.c:3357
LONG tmInternalLeading
Definition: wingdi.h:3067
LONG tmAveCharWidth
Definition: wingdi.h:3069
else
Definition: tritemp.h:161
#define PAN_SERIF_THIN
Definition: wingdi.h:476
#define PAN_FAMILY_TEXT_DISPLAY
Definition: wingdi.h:467
#define PAN_PROP_MONOSPACED
Definition: wingdi.h:502
#define FF_DECORATIVE
Definition: wingdi.h:447
#define PAN_SERIF_NORMAL_SANS
Definition: wingdi.h:480
#define FF_SCRIPT
Definition: wingdi.h:451
#define PAN_SERIF_BONE
Definition: wingdi.h:477
#define FF_ROMAN
Definition: wingdi.h:450
#define PAN_SERIF_OBTUSE_SANS
Definition: wingdi.h:481
#define PAN_FAMILY_PICTORIAL
Definition: wingdi.h:470
#define PAN_SERIF_TRIANGLE
Definition: wingdi.h:479
#define PAN_NO_FIT
Definition: wingdi.h:466
#define PAN_SERIF_SQUARE_COVE
Definition: wingdi.h:473
#define PAN_SERIF_SQUARE
Definition: wingdi.h:475
#define PAN_SERIF_OBTUSE_SQUARE_COVE
Definition: wingdi.h:474
#define PAN_SERIF_COVE
Definition: wingdi.h:471
#define PAN_SERIF_EXAGGERATED
Definition: wingdi.h:478
#define PAN_SERIF_ROUNDED
Definition: wingdi.h:484
#define PAN_FAMILY_DECORATIVE
Definition: wingdi.h:469
#define PAN_SERIF_PERP_SANS
Definition: wingdi.h:482
#define PAN_SERIF_FLARED
Definition: wingdi.h:483
#define PAN_FAMILY_SCRIPT
Definition: wingdi.h:468
#define PAN_SERIF_OBTUSE_COVE
Definition: wingdi.h:472
#define PAN_ANY
Definition: wingdi.h:465

Referenced by enum_truetype_font_proc().

◆ test_TranslateCharsetInfo()

static void test_TranslateCharsetInfo ( void  )
static

Definition at line 2571 of file font.c.

2572{
2573 static CHARSETINFO tests[] =
2574 {
2575 { ANSI_CHARSET, 1252, { {0}, { FS_LATIN1 }}},
2576 { EASTEUROPE_CHARSET, 1250, { {0}, { FS_LATIN2 }}},
2577 { RUSSIAN_CHARSET, 1251, { {0}, { FS_CYRILLIC }}},
2578 { GREEK_CHARSET, 1253, { {0}, { FS_GREEK }}},
2579 { TURKISH_CHARSET, 1254, { {0}, { FS_TURKISH }}},
2580 { HEBREW_CHARSET, 1255, { {0}, { FS_HEBREW }}},
2581 { ARABIC_CHARSET, 1256, { {0}, { FS_ARABIC }}},
2582 { BALTIC_CHARSET, 1257, { {0}, { FS_BALTIC }}},
2583 { VIETNAMESE_CHARSET, 1258, { {0}, { FS_VIETNAMESE }}},
2584 { THAI_CHARSET, 874, { {0}, { FS_THAI }}},
2585 { SHIFTJIS_CHARSET, 932, { {0}, { FS_JISJAPAN }}},
2586 { GB2312_CHARSET, 936, { {0}, { FS_CHINESESIMP }}},
2587 { HANGEUL_CHARSET, 949, { {0}, { FS_WANSUNG }}},
2588 { CHINESEBIG5_CHARSET, 950, { {0}, { FS_CHINESETRAD }}},
2589 { JOHAB_CHARSET, 1361, { {0}, { FS_JOHAB }}},
2590 { 254, CP_UTF8, { {0}, { 0x04000000 }}},
2591 { SYMBOL_CHARSET, CP_SYMBOL, { {0}, { FS_SYMBOL }}}
2592 };
2593 CHARSETINFO csi;
2594 DWORD i, j;
2595 BOOL ret;
2596
2597 /* try all codepages */
2598 for (i = 0; i < 65536; i++)
2599 {
2600 memset( &csi, 0xcc, sizeof(csi) );
2602 if (ret)
2603 {
2604 for (j = 0; j < ARRAY_SIZE(tests); j++)
2605 {
2606 if (tests[j].ciACP != i) continue;
2607 ok( !memcmp( &csi, &tests[j], sizeof(csi) ),
2608 "%lu: wrong info %u %u %08lx %08lx %08lx %08lx %08lx %08lx\n", i,
2609 csi.ciCharset, csi.ciACP, csi.fs.fsUsb[0], csi.fs.fsUsb[1],
2610 csi.fs.fsUsb[2], csi.fs.fsUsb[3], csi.fs.fsCsb[0], csi.fs.fsCsb[1] );
2611 break;
2612 }
2613 ok( j < ARRAY_SIZE(tests), "%lu: TranslateCharsetInfo succeeded\n", i );
2614 }
2615 else ok( !ret, "%lu: TranslateCharsetInfo succeeded\n", i );
2616 }
2617
2618 /* try all charsets */
2619 for (i = 0; i < 256; i++)
2620 {
2621 memset( &csi, 0xcc, sizeof(csi) );
2623 if (ret)
2624 {
2625 for (j = 0; j < ARRAY_SIZE(tests); j++)
2626 {
2627 if (tests[j].ciCharset != i) continue;
2628 ok( !memcmp( &csi, &tests[j], sizeof(csi) ),
2629 "%lu: wrong info %u %u %08lx %08lx %08lx %08lx %08lx %08lx\n", i,
2630 csi.ciCharset, csi.ciACP, csi.fs.fsUsb[0], csi.fs.fsUsb[1],
2631 csi.fs.fsUsb[2], csi.fs.fsUsb[3], csi.fs.fsCsb[0], csi.fs.fsCsb[1] );
2632 break;
2633 }
2634 ok( j < ARRAY_SIZE(tests), "%lu: TranslateCharsetInfo succeeded\n", i );
2635 }
2636 else ok( !ret, "%lu: TranslateCharsetInfo succeeded\n", i );
2637 }
2638
2639 /* try all fontsigs */
2640 for (i = 0; i < 64; i++)
2641 {
2642 DWORD csb[2] = { 0, 0 };
2643 csb[i / 32] = 1 << (i % 32);
2644 memset( &csi, 0xcc, sizeof(csi) );
2645 ret = TranslateCharsetInfo( csb, &csi, TCI_SRCFONTSIG );
2646 if (ret)
2647 {
2648 for (j = 0; j < ARRAY_SIZE(tests); j++)
2649 {
2650 if (tests[j].fs.fsCsb[0] != csb[0]) continue;
2651 ok( !memcmp( &csi, &tests[j], sizeof(csi) ),
2652 "%lu: wrong info %u %u %08lx %08lx %08lx %08lx %08lx %08lx\n", i,
2653 csi.ciCharset, csi.ciACP, csi.fs.fsUsb[0], csi.fs.fsUsb[1],
2654 csi.fs.fsUsb[2], csi.fs.fsUsb[3], csi.fs.fsCsb[0], csi.fs.fsCsb[1] );
2655 break;
2656 }
2657 ok( j < ARRAY_SIZE(tests), "%lu: TranslateCharsetInfo succeeded\n", i );
2658 }
2659 else ok( !ret, "%lu: TranslateCharsetInfo succeeded\n", i );
2660 }
2661}
static struct test_info tests[]
#define CP_UTF8
Definition: nls.h:20
#define FS_TURKISH
Definition: wingdi.h:564
#define FS_JOHAB
Definition: wingdi.h:574
#define FS_THAI
Definition: wingdi.h:569
#define FS_WANSUNG
Definition: wingdi.h:572
#define FS_VIETNAMESE
Definition: wingdi.h:568
#define ARABIC_CHARSET
Definition: wingdi.h:394
#define FS_GREEK
Definition: wingdi.h:563
#define THAI_CHARSET
Definition: wingdi.h:397
#define GREEK_CHARSET
Definition: wingdi.h:391
#define FS_HEBREW
Definition: wingdi.h:565
#define FS_SYMBOL
Definition: wingdi.h:575
#define FS_CHINESETRAD
Definition: wingdi.h:573
#define FS_CHINESESIMP
Definition: wingdi.h:571
#define VIETNAMESE_CHARSET
Definition: wingdi.h:402
#define HEBREW_CHARSET
Definition: wingdi.h:393
#define FS_BALTIC
Definition: wingdi.h:567
#define EASTEUROPE_CHARSET
Definition: wingdi.h:399
#define BALTIC_CHARSET
Definition: wingdi.h:395
#define TURKISH_CHARSET
Definition: wingdi.h:392

Referenced by START_TEST().

◆ test_ttf_names()

static void test_ttf_names ( void  )
static

Definition at line 7053 of file font.c.

7054{
7055 struct enum_fullname_data efnd;
7056 char ttf_name[MAX_PATH], ttf_name_bold[MAX_PATH];
7057 LOGFONTA font = {0};
7058 HFONT handle_font;
7059 int ret;
7060 HDC dc;
7061
7062 if (!write_ttf_file("wine_ttfnames.ttf", ttf_name))
7063 {
7064 skip("Failed to create ttf file for testing\n");
7065 return;
7066 }
7067
7068 if (!write_ttf_file("wine_ttfnames_bold.ttf", ttf_name_bold))
7069 {
7070 skip("Failed to create ttf file for testing\n");
7071 DeleteFileA(ttf_name);
7072 return;
7073 }
7074
7075 ret = AddFontResourceExA(ttf_name, FR_PRIVATE, 0);
7076 ok(ret, "AddFontResourceEx() failed\n");
7077
7078 ret = AddFontResourceExA(ttf_name_bold, FR_PRIVATE, 0);
7079 ok(ret, "AddFontResourceEx() failed\n");
7080
7081 dc = GetDC(NULL);
7082
7083 strcpy(font.lfFaceName, "Wine_TTF_Names_Long_Family1_Con");
7084 memset(&efnd, 0, sizeof(efnd));
7086 ok(efnd.total == 0, "EnumFontFamiliesExA must not find font.\n");
7087
7088 /* Windows doesn't match with Typographic/Preferred Family tags */
7089 strcpy(font.lfFaceName, "Wine TTF Names Long Family1");
7090 memset(&efnd, 0, sizeof(efnd));
7092 ok(efnd.total == 0, "EnumFontFamiliesExA must not find font.\n");
7093
7094 strcpy(font.lfFaceName, "Wine TTF Names Long Family1 Ext");
7095 memset(&efnd, 0, sizeof(efnd));
7097 ok(efnd.total == 2, "EnumFontFamiliesExA found %d fonts, expected 2.\n", efnd.total);
7098
7099 strcpy(font.lfFaceName, "Wine TTF Names Long Family1 Con");
7100 memset(&efnd, 0, sizeof(efnd));
7102 ok(efnd.total == 2, "EnumFontFamiliesExA found %d fonts, expected 2.\n", efnd.total);
7103
7104 handle_font = CreateFontIndirectA(&font);
7105 ok(handle_font != NULL, "CreateFontIndirectA failed\n");
7106 DeleteObject(handle_font);
7107
7108 ret = RemoveFontResourceExA(ttf_name_bold, FR_PRIVATE, 0);
7109 ok(ret, "RemoveFontResourceEx() failed\n");
7110
7111 DeleteFileA(ttf_name_bold);
7112
7113 ret = RemoveFontResourceExA(ttf_name, FR_PRIVATE, 0);
7114 ok(ret, "RemoveFontResourceEx() failed\n");
7115
7116 DeleteFileA(ttf_name);
7117 ReleaseDC(NULL, dc);
7118}

Referenced by START_TEST().

◆ test_vertical_font()

static void test_vertical_font ( void  )
static

Definition at line 6250 of file font.c.

6251{
6252 char ttf_name[MAX_PATH];
6253 int num, i;
6254 BOOL ret, installed, selected;
6255 GLYPHMETRICS gm;
6256 WORD hgi, vgi;
6257 const char* face_list[] = {
6258 "@WineTestVertical", /* has vmtx table */
6259 "@Ume Gothic", /* doesn't have vmtx table */
6260 "@MS UI Gothic", /* has vmtx table, available on native */
6261 };
6262
6263 if (!write_ttf_file("vertical.ttf", ttf_name))
6264 {
6265 skip("Failed to create ttf file for testing\n");
6266 return;
6267 }
6268
6269 num = AddFontResourceExA(ttf_name, FR_PRIVATE, 0);
6270 ok(num == 2, "AddFontResourceExA should add 2 fonts from vertical.ttf\n");
6271
6272 check_vertical_font("WineTestVertical", &installed, &selected, &gm, &hgi);
6273 ok(installed, "WineTestVertical is not installed\n");
6274 ok(selected, "WineTestVertical is not selected\n");
6275 ok(gm.gmBlackBoxX > gm.gmBlackBoxY,
6276 "gmBlackBoxX(%u) should be greater than gmBlackBoxY(%u) if horizontal\n",
6277 gm.gmBlackBoxX, gm.gmBlackBoxY);
6278
6279 check_vertical_font("@WineTestVertical", &installed, &selected, &gm, &vgi);
6280 ok(installed, "@WineTestVertical is not installed\n");
6281 ok(selected, "@WineTestVertical is not selected\n");
6282 ok(gm.gmBlackBoxX > gm.gmBlackBoxY,
6283 "gmBlackBoxX(%u) should be less than gmBlackBoxY(%u) if vertical\n",
6284 gm.gmBlackBoxX, gm.gmBlackBoxY);
6285
6286 ok(hgi != vgi, "same glyph h:%u v:%u\n", hgi, vgi);
6287
6288 for (i = 0; i < ARRAY_SIZE(face_list); i++) {
6289 const char* face = face_list[i];
6291 skip("%s is not installed\n", face);
6292 continue;
6293 }
6295 }
6296
6297 ret = RemoveFontResourceExA(ttf_name, FR_PRIVATE, 0);
6298 ok(ret, "RemoveFontResourceEx() error %ld\n", GetLastError());
6299
6300 DeleteFileA(ttf_name);
6301}
static void check_vertical_metrics(const char *face)
Definition: font.c:6162
static void check_vertical_font(const char *name, BOOL *installed, BOOL *selected, GLYPHMETRICS *gm, WORD *gi)
Definition: font.c:6111

Referenced by START_TEST().

◆ test_vertical_order()

static void test_vertical_order ( void  )
static

Definition at line 6566 of file font.c.

6567{
6568 struct enum_font_data efd;
6569 LOGFONTA lf;
6570 HDC hdc;
6571 int i, j;
6572
6574 ok(hdc != NULL, "CreateCompatibleDC failed\n");
6575
6576 memset(&lf, 0, sizeof(lf));
6579 lf.lfHeight = 16;
6580 lf.lfWidth = 16;
6582 lf.lfItalic = FALSE;
6584 memset( &efd, 0, sizeof(efd) );
6586 for (i = 0; i < efd.total; i++)
6587 {
6588 if (efd.lf[i].lfFaceName[0] != '@') continue;
6589 for (j = 0; j < efd.total; j++)
6590 {
6591 if (!strcmp(efd.lf[i].lfFaceName + 1, efd.lf[j].lfFaceName))
6592 {
6593 ok(i > j,"Found vertical font %s before its horizontal version\n", efd.lf[i].lfFaceName);
6594 break;
6595 }
6596 }
6597 }
6598 free( efd.lf );
6599 DeleteDC( hdc );
6600}

Referenced by START_TEST().

◆ testJustification()

static void testJustification ( const char context,
HDC  hdc,
PCSTR  str,
RECT clientArea 
)
static

Definition at line 2289 of file font.c.

2290{
2291 INT y,
2292 breakCount,
2293 areaWidth = clientArea->right - clientArea->left,
2294 nErrors = 0, e;
2295 const char *pFirstChar, *pLastChar;
2296 SIZE size;
2298 struct err
2299 {
2300 const char *start;
2301 int len;
2302 int GetTextExtentExPointWWidth;
2303 } error[20];
2304
2306 y = clientArea->top;
2307 do {
2308 breakCount = 0;
2309 while (*str == tm.tmBreakChar) str++; /* skip leading break chars */
2310 pFirstChar = str;
2311
2312 do {
2313 pLastChar = str;
2314
2315 /* if not at the end of the string, ... */
2316 if (*str == '\0') break;
2317 /* ... add the next word to the current extent */
2318 while (*str != '\0' && *str++ != tm.tmBreakChar);
2319 breakCount++;
2321 GetTextExtentPoint32A(hdc, pFirstChar, str - pFirstChar - 1, &size);
2322 } while ((int) size.cx < areaWidth);
2323
2324 /* ignore trailing break chars */
2325 breakCount--;
2326 while (*(pLastChar - 1) == tm.tmBreakChar)
2327 {
2328 pLastChar--;
2329 breakCount--;
2330 }
2331
2332 if (*str == '\0' || breakCount <= 0) pLastChar = str;
2333
2335 GetTextExtentPoint32A(hdc, pFirstChar, pLastChar - pFirstChar, &size);
2336
2337 /* do not justify the last extent */
2338 if (*str != '\0' && breakCount > 0)
2339 {
2340 SetTextJustification(hdc, areaWidth - size.cx, breakCount);
2341 GetTextExtentPoint32A(hdc, pFirstChar, pLastChar - pFirstChar, &size);
2342 if (size.cx != areaWidth && nErrors < ARRAY_SIZE(error) - 1)
2343 {
2344 error[nErrors].start = pFirstChar;
2345 error[nErrors].len = pLastChar - pFirstChar;
2346 error[nErrors].GetTextExtentExPointWWidth = size.cx;
2347 nErrors++;
2348 }
2349 }
2350
2351 y += size.cy;
2352 str = pLastChar;
2353 } while (*str && y < clientArea->bottom);
2354
2355 for (e = 0; e < nErrors; e++)
2356 {
2357 /* The width returned by GetTextExtentPoint32() is exactly the same
2358 returned by GetTextExtentExPointW() - see dlls/gdi32/font.c */
2359 ok(error[e].GetTextExtentExPointWWidth == areaWidth ||
2360 broken(abs(areaWidth - error[e].GetTextExtentExPointWWidth) <= 2) /* win10 */,
2361 "%s: GetTextExtentPointW() for \"%.*s\" should have returned a width of %d, not %d.\n",
2362 context, error[e].len, error[e].start, areaWidth, error[e].GetTextExtentExPointWWidth);
2363 }
2364}
GLuint start
Definition: gl.h:1545
GLint GLint bottom
Definition: glext.h:7726
#define e
Definition: ke_i.h:82
#define err(...)
LONG right
Definition: windef.h:108
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106

Referenced by test_SetTextJustification().

◆ write_tmp_file()

static BOOL write_tmp_file ( const void data,
DWORD size,
char tmp_name 
)
static

Definition at line 137 of file font.c.

138{
139 char tmp_path[MAX_PATH];
140 HANDLE hfile;
141 BOOL ret;
142
143 GetTempPathA(MAX_PATH, tmp_path);
144 GetTempFileNameA(tmp_path, "ttf", 0, tmp_name);
145
147 if (hfile == INVALID_HANDLE_VALUE) return FALSE;
148
149 ret = WriteFile(hfile, data, *size, size, NULL);
150
151 CloseHandle(hfile);
152 return ret;
153}
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
#define CREATE_ALWAYS
Definition: disk.h:72
#define GENERIC_WRITE
Definition: nt_native.h:90
static char * tmp_name
Definition: cache.c:24

Referenced by test_height_selection_vdmx(), and write_ttf_file().

◆ write_ttf_file()

static BOOL write_ttf_file ( const char fontname,
char tmp_name 
)
static

Definition at line 155 of file font.c.

156{
157 void *rsrc_data;
158 DWORD rsrc_size;
159
160 rsrc_data = get_res_data( fontname, &rsrc_size );
161 if (!rsrc_data) return FALSE;
162
163 return write_tmp_file( rsrc_data, &rsrc_size, tmp_name );
164}

Referenced by test_AddFontMemResource(), test_CreateScalableFontResource(), test_font_weight(), test_GetGlyphIndices(), test_lang_names(), test_long_names(), test_ttf_names(), and test_vertical_font().

Variable Documentation

◆ DWORD

void *static DWORD *static DWORD *static void SIZE_T *static DWORD

Definition at line 47 of file font.c.

◆ height

Definition at line 42 of file font.c.

◆ hgdi32

HMODULE hgdi32 = 0
static

Definition at line 50 of file font.c.

Referenced by init(), test_gdiis(), and test_margins_default().

◆ lptm

◆ mac_langid_table

const LANGID mac_langid_table[]
static

Definition at line 3594 of file font.c.

◆ mat

const MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} }
static

Definition at line 51 of file font.c.

Referenced by check_vertical_font(), check_vertical_metrics(), compute_texture_matrix(), d3d_draw_quad1(), d3d_material1_GetMaterial(), d3d_material1_SetMaterial(), d3d_material2_GetMaterial(), d3d_material2_SetMaterial(), d3d_material3_GetMaterial(), d3d_material3_SetMaterial(), d3d_viewport_TransformVertices(), d3drm_update_background_material(), D3DXMatrixTest(), D3DXPlaneTest(), D3DXQuaternionTest(), D3DXVector2Test(), D3DXVector3Test(), D3DXVector4Test(), draw_quad2(), dump_D3DMATRIX(), dump_material(), ftGdiGetGlyphOutline(), gen_add_match(), gen_del_match(), gen_matches(), get_identity_matrix(), get_modelview_matrix(), get_normal_matrix(), get_projection_matrix(), get_texture_matrix(), gl_color_shade_vertices(), gl_index_shade_vertices(), gl_set_material(), gl_update_lighting(), ID3DXFontImpl_PreloadGlyphs(), IntExtTextOutW(), MatrixTest(), nvts_bumpenvmat(), process_vertices_strided(), set(), set_bumpmat(), set_bumpmat_arbfp(), set_matrix(), set_states(), Mapdesc::setBboxsize(), Mapdesc::setBmat(), Mapdesc::setCmat(), NurbsTessellator::setnurbsproperty(), Mapdesc::setSmat(), Pen::SetTransform(), shader_glsl_ffp_vertex_texmatrix_uniform(), shader_glsl_load_constants(), test_bitmap_font_metrics(), test_D3DXVec_Array(), test_effect_parameter_block(), test_effect_states(), test_GetCharABCWidths(), test_GetGlyphOutline(), test_GetGlyphOutline_character(), test_GetGlyphOutline_empty_contour(), test_GetGlyphOutline_metric_clipping(), test_ID3DXFont(), test_ID3DXSprite(), test_negative_width(), test_outline_font(), GLUnurbs::transform4d(), transform_texture(), transform_world(), wined3d_device_multiply_transform(), Mapdesc::xformMat(), Mapdesc::xformNonrational(), and Mapdesc::xformRational().

◆ SIZE_T

void *static DWORD *static DWORD *static void SIZE_T *static void SIZE_T

Definition at line 47 of file font.c.

◆ system_lang_id

WORD system_lang_id
static

◆ UINT64

void *static DWORD *static DWORD *static void SIZE_T *static UINT64

Definition at line 48 of file font.c.