* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "precomp.h"
+#include <stdarg.h>
+#include <assert.h>
-#include <winnls.h>
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winnls.h"
+
+#include "wine/heap.h"
+#include "wine/test.h"
static inline BOOL match_off_by_n(int a, int b, unsigned int n)
{
system_lang_id = PRIMARYLANGID(GetSystemDefaultLangID());
}
-static inline void* __WINE_ALLOC_SIZE(1) heap_alloc(size_t size)
-{
- return HeapAlloc(GetProcessHeap(), 0, size);
-}
-
-static inline void* __WINE_ALLOC_SIZE(2) heap_realloc(void *mem, size_t size)
-{
- if (!mem) return heap_alloc(size);
- return HeapReAlloc(GetProcessHeap(), 0, mem, size);
-}
-
-static inline BOOL heap_free(void *mem)
-{
- return HeapFree(GetProcessHeap(), 0, mem);
-}
-
static INT CALLBACK is_truetype_font_installed_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
{
if (type != TRUETYPE_FONTTYPE) return 1;
return 1;
}
-static void ABCWidths_helper(const char* description, HDC hdc, WORD *glyphs, ABC *base_abci, ABC *base_abcw, ABCFLOAT *base_abcf, INT todo)
+static void ABCWidths_helper(const char* description, HDC hdc, WORD *glyphs, const ABC *base_abci, const ABC *base_abcw, const ABCFLOAT *base_abcf)
{
ABC abc[1];
ABCFLOAT abcf[1];
ret = pGetCharABCWidthsI(hdc, 0, 1, glyphs, abc);
ok(ret, "%s: GetCharABCWidthsI should have succeeded\n", description);
ok ((INT)abc->abcB > 0, "%s: abcB should be positive\n", description);
- todo_wine_if (todo)
- ok(abc->abcA * base_abci->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
- todo_wine_if (todo)
- ok(abc->abcC * base_abci->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
+ ok(abc->abcA * base_abci->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
+ ok(abc->abcC * base_abci->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
ret = pGetCharABCWidthsW(hdc, 'i', 'i', abc);
ok(ret, "%s: GetCharABCWidthsW should have succeeded\n", description);
ok ((INT)abc->abcB > 0, "%s: abcB should be positive\n", description);
- todo_wine_if (todo)
- ok(abc->abcA * base_abcw->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
- todo_wine_if (todo)
- ok(abc->abcC * base_abcw->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
+ ok(abc->abcA * base_abcw->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
+ ok(abc->abcC * base_abcw->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
ret = pGetCharABCWidthsFloatW(hdc, 'i', 'i', abcf);
ok(ret, "%s: GetCharABCWidthsFloatW should have succeeded\n", description);
ok (abcf->abcfB > 0.0, "%s: abcfB should be positive\n", description);
- todo_wine_if (todo)
- ok(abcf->abcfA * base_abcf->abcfA >= 0.0, "%s: abcfA's sign should be unchanged\n", description);
- todo_wine_if (todo)
- ok(abcf->abcfC * base_abcf->abcfC >= 0.0, "%s: abcfC's sign should be unchanged\n", description);
+ ok(abcf->abcfA * base_abcf->abcfA >= 0.0, "%s: abcfA's sign should be unchanged\n", description);
+ ok(abcf->abcfC * base_abcf->abcfC >= 0.0, "%s: abcfC's sign should be unchanged\n", description);
}
static void test_GetCharABCWidths(void)
"got %d, expected %d (C)\n", abc[0].abcC, abcw[0].abcC);
DeleteObject(SelectObject(hdc, hfont));
+
+ /* test abcA == gmptGlyphOrigin.x && abcB == gmBlackBoxX
+ in various widths. */
+ for (i = 1; i <= 2; i++)
+ {
+ UINT j;
+ UINT code;
+
+ memset(&lf, 0, sizeof(lf));
+ lf.lfHeight = 20;
+ switch(i)
+ {
+ case 1:
+ strcpy(lf.lfFaceName, "Tahoma");
+ code = 'a';
+ break;
+ case 2:
+ strcpy(lf.lfFaceName, "Times New Roman");
+ lf.lfItalic = TRUE;
+ code = 'f';
+ break;
+ }
+ if (!is_truetype_font_installed(lf.lfFaceName))
+ {
+ skip("%s is not installed\n", lf.lfFaceName);
+ continue;
+ }
+ for (j = 1; j <= 80; j++)
+ {
+ GLYPHMETRICS gm;
+
+ lf.lfWidth = j;
+ hfont = CreateFontIndirectA(&lf);
+ hfont = SelectObject(hdc, hfont);
+
+ nb = GetGlyphOutlineA(hdc, code, GGO_METRICS, &gm, 0, NULL, &mat);
+ ok(nb, "GetGlyphOutlineA should have succeeded at width %d\n", i);
+
+ ret = GetCharABCWidthsA(hdc, code, code, abc);
+ ok(ret, "GetCharABCWidthsA should have succeeded at width %d\n", i);
+
+ ok(abc[0].abcA == gm.gmptGlyphOrigin.x,
+ "abcA(%d) and gmptGlyphOrigin.x(%d) values are different at width %d\n",
+ abc[0].abcA, gm.gmptGlyphOrigin.x, i);
+ ok(abc[0].abcB == gm.gmBlackBoxX,
+ "abcB(%d) and gmBlackBoxX(%d) values are different at width %d\n",
+ abc[0].abcB, gm.gmBlackBoxX, i);
+ DeleteObject(SelectObject(hdc, hfont));
+ }
+ }
ReleaseDC(NULL, hdc);
trace("ABC sign test for a variety of transforms:\n");
ret = pGetCharABCWidthsFloatW(hdc, 'i', 'i', abcf);
ok(ret, "GetCharABCWidthsFloatW should have succeeded\n");
- ABCWidths_helper("LTR", hdc, glyphs, abc, abcw, abcf, 0);
+ ABCWidths_helper("LTR", hdc, glyphs, abc, abcw, abcf);
SetWindowExtEx(hdc, -1, -1, NULL);
SetGraphicsMode(hdc, GM_COMPATIBLE);
- ABCWidths_helper("LTR -1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+ ABCWidths_helper("LTR -1 compatible", hdc, glyphs, abc, abcw, abcf);
SetGraphicsMode(hdc, GM_ADVANCED);
- ABCWidths_helper("LTR -1 advanced", hdc, glyphs, abc, abcw, abcf, 1);
+ ABCWidths_helper("LTR -1 advanced", hdc, glyphs, abc, abcw, abcf);
SetWindowExtEx(hdc, 1, 1, NULL);
SetGraphicsMode(hdc, GM_COMPATIBLE);
- ABCWidths_helper("LTR 1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+ ABCWidths_helper("LTR 1 compatible", hdc, glyphs, abc, abcw, abcf);
SetGraphicsMode(hdc, GM_ADVANCED);
- ABCWidths_helper("LTR 1 advanced", hdc, glyphs, abc, abcw, abcf, 0);
+ ABCWidths_helper("LTR 1 advanced", hdc, glyphs, abc, abcw, abcf);
ReleaseDC(hwnd, hdc);
DestroyWindow(hwnd);
SetMapMode(hdc, MM_ANISOTROPIC);
SelectObject(hdc, hfont);
- ABCWidths_helper("RTL", hdc, glyphs, abc, abcw, abcf, 0);
+ ABCWidths_helper("RTL", hdc, glyphs, abc, abcw, abcf);
SetWindowExtEx(hdc, -1, -1, NULL);
SetGraphicsMode(hdc, GM_COMPATIBLE);
- ABCWidths_helper("RTL -1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+ ABCWidths_helper("RTL -1 compatible", hdc, glyphs, abc, abcw, abcf);
SetGraphicsMode(hdc, GM_ADVANCED);
- ABCWidths_helper("RTL -1 advanced", hdc, glyphs, abc, abcw, abcf, 0);
+ ABCWidths_helper("RTL -1 advanced", hdc, glyphs, abc, abcw, abcf);
SetWindowExtEx(hdc, 1, 1, NULL);
SetGraphicsMode(hdc, GM_COMPATIBLE);
- ABCWidths_helper("RTL 1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+ ABCWidths_helper("RTL 1 compatible", hdc, glyphs, abc, abcw, abcf);
SetGraphicsMode(hdc, GM_ADVANCED);
- ABCWidths_helper("RTL 1 advanced", hdc, glyphs, abc, abcw, abcf, 1);
+ ABCWidths_helper("RTL 1 advanced", hdc, glyphs, abc, abcw, abcf);
ReleaseDC(hwnd, hdc);
DestroyWindow(hwnd);
kd[i].otmMacDescent, otm.otmMacDescent);
ok(near_match(kd[i].otmMacAscent, otm.otmMacAscent), "expected %d, got %d\n",
kd[i].otmMacAscent, otm.otmMacAscent);
-todo_wine {
+todo_wine
ok(kd[i].otmsCapEmHeight == otm.otmsCapEmHeight, "expected %u, got %u\n",
kd[i].otmsCapEmHeight, otm.otmsCapEmHeight);
+todo_wine
ok(kd[i].otmsXHeight == otm.otmsXHeight, "expected %u, got %u\n",
kd[i].otmsXHeight, otm.otmsXHeight);
- /* FIXME: this one sometimes succeeds due to expected 0, enable it when removing todo */
- if (0) ok(kd[i].otmMacLineGap == otm.otmMacLineGap, "expected %u, got %u\n",
+ ok(kd[i].otmMacLineGap == otm.otmMacLineGap, "expected %u, got %u\n",
kd[i].otmMacLineGap, otm.otmMacLineGap);
+todo_wine
ok(kd[i].otmusMinimumPPEM == otm.otmusMinimumPPEM, "expected %u, got %u\n",
kd[i].otmusMinimumPPEM, otm.otmusMinimumPPEM);
-}
total_kern_pairs = GetKerningPairsW(hdc, 0, NULL);
trace("total_kern_pairs %u\n", total_kern_pairs);
GLYPHMETRICS rgm, vgm;
const UINT code = 0x5EAD, height = 1000;
WORD idx;
- ABC abc;
+ ABC abc, vabc;
OUTLINETEXTMETRICA otm;
USHORT numOfLongVerMetrics;
hfont_prev = SelectObject(hdc, hfont);
ret = GetGlyphOutlineW(hdc, code, GGO_METRICS, &vgm, 0, NULL, &mat);
ok(ret != GDI_ERROR, "GetGlyphOutlineW failed\n");
+ ret = GetCharABCWidthsW(hdc, code, code, &vabc);
+ ok(ret, "GetCharABCWidthsW failed\n");
+ ok(vabc.abcA == vgm.gmptGlyphOrigin.x, "expected %d, got %d\n",
+ vabc.abcA, vgm.gmptGlyphOrigin.x);
+ ok(vabc.abcB == vgm.gmBlackBoxX, "expected %d, got %d\n",
+ vabc.abcB, vgm.gmBlackBoxX);
+ ok(vabc.abcA + vabc.abcB + vabc.abcC == vgm.gmCellIncX,
+ "expected %d, got %d\n",
+ vabc.abcA + vabc.abcB + vabc.abcC, vgm.gmCellIncX);
memset(&otm, 0, sizeof(otm));
otm.otmSize = sizeof(otm);
SetGraphicsMode(hdc, GM_ADVANCED);
ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
ok(ret, "GetCharWidth32W should have succeeded\n");
- todo_wine ok (bufferW > 0," Width should be greater than zero\n");
+ ok (bufferW > 0," Width should be greater than zero\n");
SetWindowExtEx(hdc, 1,1,NULL);
SetGraphicsMode(hdc, GM_COMPATIBLE);
ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
SetGraphicsMode(hdc, GM_ADVANCED);
ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
ok(ret, "GetCharWidth32W should have succeeded\n");
- todo_wine ok (bufferW > 0," Width should be greater than zero\n");
+ ok (bufferW > 0," Width should be greater than zero\n");
ReleaseDC(hwnd, hdc);
DestroyWindow(hwnd);
ABC abc;
INT w;
GLYPHMETRICS gm;
- } data[2];
+ } data[4];
int i;
DWORD r;
"expected %d, got %d\n", data[0].gm.gmCellIncX + 1, data[1].gm.gmCellIncX);
ok(data[0].gm.gmCellIncY == data[1].gm.gmCellIncY,
"expected %d, got %d\n", data[0].gm.gmCellIncY, data[1].gm.gmCellIncY);
+
+ /* Test bitmap font */
+ memset(&data, 0xaa, sizeof(data));
+ memset(&lf, 0, sizeof(lf));
+ strcpy(lf.lfFaceName, "Courier");
+ lf.lfCharSet = ANSI_CHARSET;
+
+ hdc = GetDC(NULL);
+
+ for (i = 0; i < 4; i++)
+ {
+ HFONT hfont, hfont_old;
+
+ lf.lfWeight = (i % 2) ? FW_BOLD : FW_NORMAL;
+ lf.lfHeight = (i > 1) ? data[0].tm.tmHeight * x2_mat.eM11.value : 0;
+ hfont = CreateFontIndirectA(&lf);
+ hfont_old = SelectObject(hdc, hfont);
+
+ ret = GetTextMetricsA(hdc, &data[i].tm);
+ ok(ret, "got %d\n", ret);
+ ret = pGetCharWidth32A(hdc, 0x76, 0x76, &data[i].w);
+ ok(ret, "got %d\n", ret);
+
+ SelectObject(hdc, hfont_old);
+ DeleteObject(hfont);
+ }
+ ReleaseDC(NULL, hdc);
+
+ /* compare results (bitmap) */
+ for (i = 0; i < 4; i+=2)
+ {
+ int diff = (i > 1) ? x2_mat.eM11.value : 1;
+ if (data[i].tm.tmPitchAndFamily & TMPF_TRUETYPE)
+ {
+ skip("TrueType font is selected (expected a bitmap one)\n");
+ continue;
+ }
+ ok(data[i].tm.tmHeight == data[i+1].tm.tmHeight,
+ "expected %d, got %d\n", data[i].tm.tmHeight, data[i+1].tm.tmHeight);
+ ok(data[i].tm.tmAscent == data[i+1].tm.tmAscent,
+ "expected %d, got %d\n", data[i].tm.tmAscent, data[i+1].tm.tmAscent);
+ ok(data[i].tm.tmDescent == data[i+1].tm.tmDescent,
+ "expected %d, got %d\n", data[i].tm.tmDescent, data[i+1].tm.tmDescent);
+ ok(data[i+1].tm.tmAveCharWidth - data[i].tm.tmAveCharWidth == diff,
+ "expected %d, got %d\n", diff, data[i+1].tm.tmAveCharWidth - data[i].tm.tmAveCharWidth);
+ ok(data[i+1].tm.tmMaxCharWidth - data[i].tm.tmMaxCharWidth == diff,
+ "expected %d, got %d\n", diff, data[i+1].tm.tmMaxCharWidth - data[i].tm.tmMaxCharWidth);
+ ok(data[i].tm.tmOverhang == 0,
+ "expected 0, got %d\n", data[i].tm.tmOverhang);
+ ok(data[i+1].tm.tmOverhang == 1,
+ "expected 1, got %d\n", data[i+1].tm.tmOverhang);
+ ok(data[i].w + 1 == data[i+1].w,
+ "expected %d, got %d\n", data[i].w + 1, data[i+1].w);
+ }
}
static void test_bitmap_font_glyph_index(void)
ReleaseDC(0, hdc);
}
+static INT CALLBACK long_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lparam)
+{
+ BOOL *found_font = (BOOL *)lparam;
+ *found_font = TRUE;
+ return 1;
+}
+
+static void test_long_names(void)
+{
+ char ttf_name[MAX_PATH];
+ LOGFONTA font = {0};
+ HFONT handle_font;
+ BOOL found_font;
+ int ret;
+ HDC dc;
+
+ if (!write_ttf_file("wine_longname.ttf", ttf_name))
+ {
+ skip("Failed to create ttf file for testing\n");
+ return;
+ }
+
+ dc = GetDC(NULL);
+
+ ret = AddFontResourceExA(ttf_name, FR_PRIVATE, 0);
+ ok(ret, "AddFontResourceEx() failed\n");
+
+ strcpy(font.lfFaceName, "wine_3_this_is_a_very_long_name");
+ found_font = FALSE;
+ EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0);
+ ok(found_font == TRUE, "EnumFontFamiliesExA didn't find font.\n");
+
+ strcpy(font.lfFaceName, "wine_2_this_is_a_very_long_name");
+ found_font = FALSE;
+ EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0);
+ ok(found_font == TRUE, "EnumFontFamiliesExA didn't find font.\n");
+
+ strcpy(font.lfFaceName, "wine_1_this_is_a_very_long_name");
+ found_font = FALSE;
+ EnumFontFamiliesExA(dc, &font, long_enum_proc, (LPARAM)&found_font, 0);
+ ok(found_font == FALSE, "EnumFontFamiliesExA must not find font.\n");
+
+ handle_font = CreateFontIndirectA(&font);
+ ok(handle_font != NULL, "CreateFontIndirectA failed\n");
+ DeleteObject(handle_font);
+
+ ret = RemoveFontResourceExA(ttf_name, FR_PRIVATE, 0);
+ ok(ret, "RemoveFontResourceEx() failed\n");
+
+ DeleteFileA(ttf_name);
+ ReleaseDC(NULL, dc);
+}
+
START_TEST(font)
{
init();
test_fake_bold_font();
test_bitmap_font_glyph_index();
test_GetCharWidthI();
+ test_long_names();
/* These tests should be last test until RemoveFontResource
* is properly implemented.