"d7dd4700f49808541bba99244b7eb5840e0a2439",
"af99228aa4cfbd1f61bd824db046144a3c6c2ed7",
"568f87f0194ca19b69a5b2bcdef795d89c5721ce",
- "50d19fe68b2ab4fdbb5d590cdca6dc84a95bab68",
- "a1fde1094d2c19ddb20871842dae1da73618709e",
+ "a37810f46dee8741fe5adbb3f1f2e87012ffc929",
+ "50a09678c49c208f71d40452daca5411279aa674",
"e462052a03dbe4ec3814db7700e166d00d4d686f",
"a27917d4db49ce77989fae246015aeb2a28520ee",
"657514a4ca1f2b6ca7a125ad58dfed82099a37d1",
"d7dd4700f49808541bba99244b7eb5840e0a2439",
"af99228aa4cfbd1f61bd824db046144a3c6c2ed7",
"568f87f0194ca19b69a5b2bcdef795d89c5721ce",
- "50d19fe68b2ab4fdbb5d590cdca6dc84a95bab68",
- "a1fde1094d2c19ddb20871842dae1da73618709e",
+ "a37810f46dee8741fe5adbb3f1f2e87012ffc929",
+ "50a09678c49c208f71d40452daca5411279aa674",
"0cda6b3297003b3ccd6d5baa17e1ca9bb7c56f08",
"b2c8e1ebb9435031fe068442f479d1304096e79f",
"657514a4ca1f2b6ca7a125ad58dfed82099a37d1",
"86c84cc8306975edecc6d4a89a8aff29f59b55a7",
"af99228aa4cfbd1f61bd824db046144a3c6c2ed7",
"25675c30adfe24d6cae60793b156dfdaa36ac3ba",
- "1cb1810b127f509117b38d62a15b67b2347b9145",
- "f05b3294f25de5fa6d1114104bca97871052ea5a",
+ "849d4abf4b690128a5f70e9b8ac78f20c437de06",
+ "e768fc9f3167ef3144a4cfb1e20126a577f7dd5b",
"87f57a31253a38dbf3dc3070473328fa04b68a48",
"db64cc4d830fc35ed170b53943e722b2342954d4",
"9988ceca44dafbee247aece1f027c06c27c01652",
"fc0c32afb719295f28bcfef22803bef94f798e20",
"36f6db4fbe2a1630a7597d3a446f2902755c96ef",
"d3f08946300e1700865042aed121870e292d1095",
- "467ff4af1e105855874f27fbf84d1d2b0417ab5d",
- "fb0dcff8a67a88313557ee8b588aaa2004fe7b8b",
+ "4782df8e24127e66a434b4e839adebf2dbb223fb",
+ "739707cc85ca63e0580c79618dc0bb8a4a338d95",
"8ea5d7e4bebc40a1d91b04b12e1c11a42c188095",
"317521e576801acaea62c76fe16813cdfe20f4ad",
"ce0fc29bb0281d6c955d64e239254ef9e6dbc06d",
"49341c297a887186bd47d7465d827ab3147f05e3",
"325279e76367200d3fd7194d81c09fd139988ece",
"c3def160a1e847605ff0fc7edd30397fa90635a0",
- "a9c2158329c207638cfd2c82cd8a6218efdb28d2",
- "7f0c4e6874f0c36cee64ff5dec76258ca8822cb2",
+ "2b3e87e0b705b03c7c08f403409ab82cce095ba1",
+ "45c08e11fffc78b2a3574263419e0cb7f8cd9b45",
"aecb242c31f31a90f071b6455ea7d808d4ea22e3",
"77ea86e51a94b11a8081b29696cb4115687843e3",
"d67b897cad72d31e75359094007b1346fd8806ea",
"b25ba91487ec945410deb2b51bc1156890c032a8",
"d347ca5c6c4b6a61389247c3b6f61564033e8c25",
"ee315634ed92da3a32c2675ecd1b369471c60936",
- "6776e0612410e7e200c853721b4ab6ad8b6b81f5",
- "620a5a520d81971a2d9c30b8d836ba696e11b8dd",
+ "099c688a920f606655b485e8f0a433dc811bc976",
+ "9c044a733335bca43766bda2b317249309155079",
"354b92008a8409c62d0fa1dff1532c5943aa37a2",
"8dc9cb7deae5c24d1eae004d53893fa6caf4723c",
"cf311a96d41bd98fdbdfb5dfaac4ba1ba9b7d6da",
"3772003c7fb420003512d0c437b3659d96d89ce4",
"dab47c9dc149e570045d699598b14a613bf319b3",
"2daca4d26a086ed34894693be0b0374402232809",
- "e313ae8f7261b88999757ed0c6f26df85b4f01a5",
- "47d0bab8664ae0aaa927495d07bb3537cce35f16",
+ "904f1d82159bcf5485f323bd12b859dc5e83f8eb",
+ "5bd29f94844351e9a5bd01f25d85608b9b0701b2",
"295ec16530126046790fb734e99f86f5b3b74ed8",
"d98b0561010606b55a1b9b85fbc93640f681d256",
"1c1499051860b7caa25173b328ca9c862f01dd1a",
"f0acb3cfcda62e95bee5f7bc8830ffeb3dd7e5a7",
"07b10c3f191d0a93e5e5694aae37dcad407e10f5",
"f7900e60347029876ba55e8f0c4c02e89deb36b6",
- "7d80b8289da8a65931f03c74a9ef0aff5f8eb551",
- "a7a986097e5b553c71bd93fd0ec6037e6bd0f2d1",
+ "f373a5f37b82e7523c64c08eb509b6191e49b173",
+ "9f0760a05190c9edf9ce2e8be6aaa5557601fe91",
"7587a9c87cab1eca827807f351bb67ca184d1ac5",
"b53ef0b5c674822e784903a9dbdd3b386d9f2350",
"5505d2ed20dc61ffe48832ecf5329162a5ceb734",
"9ae38bb94c7b4c0c6dfebbee23d1de4db9b77488",
"678979a45126a76eb629992cd64734862f53a555",
"2f7ba8803604c032cb1a1228bc021f0f1c03e245",
- "9b1cc7b24f8ce15db2af7f4aa8cde8687784dfa2",
- "cc4a4cea622d825700bccef7d90a5a447d9ca39d",
+ "52e7c2f8b01592898c13f1e7633881e350244209",
+ "d9d5556b77301952b4caf113337720966bc8e1f5",
"e58d9c0acf0219d0839e1dbd162e08a765ed7f0f",
"34ca0f9660e1889f9f2c0deb80535d3c4f349fa4",
"2c07272462c68cf5944b03e2aa049475b99143c5",
"fb63bbb2f944fb63ed2d7399f07b168740c1034b",
"3685c9ae95118a83db3569832c29753276fa1264",
"09640bad951c33e7d70a1fced83b1869f65b3fc5",
- "cb9ea8137eca1450e049879772f5c11a0e11ff0a",
- "a4b04ed35484de0de61832a8a28bbc7def645622",
- "515897610714251dd3b54f54fe76a9ed3fd12c53",
+ "5eb00252664ec39e61359adb1dade4906a87a248",
+ "ee7b9b292ea9fb559ef5ebf6a2a5586d38c7f854",
+ "dcad1a146c1d0ec2c4cc7f64bd4f45c57a604bfe",
"0ca8775d9a61ccc251d1e6f2e3cfd26a24ae24a2",
"17ae603c199a5d6695d198a7f36e6d7263990951",
"1918a33f59d3500204ffc573318a39e9ff754221",
"31e667c2dbb81dcf81d01cb88f794e88ddb90ff2",
"465d9cd0a77ab4fcf035aa67544b2a26269e0b09",
"600d6b2713d5e4c0d90c02660245ed26c7ae3033",
- "d4f3a5ea033adc405c44e1ca137dc908c606dad6",
- "7103d428ec9a959778120fd6f0dc62dd608ddd63",
+ "0025a440866a404523a8a20e79a8891e45a2ff56",
+ "c04d335933895f836f0a28c1e3f7f444352c3b8e",
"bd28d77cd85b20a2384d6b25082cfd884bba683e",
"7e591ec8ae9bb61c3a443c93f071cab2b8978394",
"f81c70b6ee2d4690f9f7c797c66582b176f8dcef",
"df5feb905a31c288008cf5e82d73ac818a160d82",
"d8af3868c66c7d6dac35ec8ee0317b38a6910bb1",
"ec8e2aebfb4a1c28ebcd0e053b9e4d8638b50951",
- "1a23839d71d2379ed4e709a5ae6c14639fbe3ab8",
- "09f8416a780d80be61cbda3d8a05aee418d0ea00",
+ "ccf8d11b1e81895e9781f17c227c821228d8714b",
+ "f751e26578193afe6a727ee2a52318c404c56555",
"28a6b9f7927e99e53cf46f0333d29168cb10e920",
"029552113292cc110fd6b7888e766628950aaeef",
"297f6ad15200bffbf15198324ee8f27a61a6f2d4",
"f8681c09f1abfc38d31e47622cb8798cd896a00e",
"b5ee51cfc73acb59a2f6124509ea236f8fc7f9f7",
"d374d4d92c940ae42a9b42c14d744341b68a8c14",
- "43560b856907f552df3b9dd1f91e1aa8ab9ff17e",
- "8cefa6dcb658487d0715598d5d120677dbfdab42",
+ "06a6a224be0f5cdc51ac4704f9f57fc1f3813d6f",
+ "c47c2dc806b6b8ff28f300949695d013a46c0083",
"ada3b7c34946e584dcdf4203e07cfa3dad02bc63",
"c2f61571b067a44b30f56b4658c9606f0edfc0f3",
"58f400c9bb78e49a879276fb049edfc9c981740a",
static const char *sha1_graphics_1[] =
{
"23366004515f3bc46796ea505d748f8d0f97fbe1",
- "ad674a4104c6a1eacaee8f20effdfe31775b4409",
- "a7cc69f957d7b533a0a330859a143d701daac73c",
- "a955bf088c5edb129289ce65caace48ec95632e4",
- "5316d3c558c254479883133cf58cd07ab521d3f0",
- "fcbfdb5d60716ea05f2d1896fae7a6e7a8249d35",
- "2c140b39cc8d21358fded8959cd655f03d7f0f89",
- "121423a38b4ac4743bd516e0a7e88a3863796313",
- "7c17635c6c7f62dbf8fd4773d0c503358553d2c7",
+ "61ade9054d4477fb89cf830539a5e8b4e45f0688",
+ "ac530c5dbaf837e15b2337347e974184fad73643",
+ "95fdcda26262d5948a9ade77d83fd698e0031050",
+ "1dd5cee06af78d026e5da8bfe3f45e1cf51faa13",
+ "f6b61ecf03ad11752775faca1d4404c6bb5065f5",
+ "d7ad44d6f377598268e9968333ae2cf23a0715ca",
+ "5871339cd7e6cee12d4dc45934a89071c73efe6b",
+ "69e9b85b34caf736069ba91e57a5c3fa7c891653",
"21d5d9e47bb07de2cf7bc99b7725390d03a6cde6",
"f69ee65ea25676429a28eea79b5b9cb9206b8d01",
"39ff81f77ef4ee772367ed1a63785987c060126e",
"88763f8e8fcf4f78fa864325791a9dd35a0bd279",
"013cee26bac8f815eadad4bfc012d9b5d01c3b7f",
"44a28536466dc895feb824b23dfd4a47c6948af8",
- "f0316a5765a0404760e94cd05b7dc956cae07d26",
+ "17468a3789f0a6d65c302bda735a01dc2c1a74d9",
"781d8c5cbc28591fd48fce06f984c502fdc6b363",
"df510792a7790cc699532b1420d43c6d4da2ae2f",
"55c26d22f11d80b73383fa57d0fac552d705b092",
"4842a30dd7fdf38ddc3ddec85c08efe13a0e2e0b",
"cc76db6da5ba1776f20240a5ad97a26a9cdf96b0",
"014f477664a7f4ce4a948d6359a2707119afc8e2",
- "1ee4e951743efc8764249fbc7adecefbfec0428e",
+ "74d01690e344bc22e7a0478e7a09ccd92354c486",
"9ab50a663b74577b656e9849484a909d7ac52eeb",
"128eefd2ee043d59dc37918065f687e378e5ca95",
- "c642abc651f525332d9d635049646d309e877839",
+ "d7e2daab98ce1f698c4bfedfc01c0d79fcb76b8e",
"8d34215487088b5d4ef63062270ce25c2862643d",
- "3dc3075b0c87fdcaabbbae8928303fb2358c15c2",
+ "826562eb11a0d0bba77fa21245f7406a194e9225",
"bbae6f0659e095a42b420082079663f937065813",
- "ca711c69165e1fa5be72993b9a7870ef6d485249",
+ "bbabe686a6955402c90530e7c67f1428868369b3",
NULL
};
static const DWORD ddb_brush_bits[8] = { 0x11112222, 0x33334444, 0x55556666, 0x77778888,
0xaaaaaaaa, 0x00000000, 0x98765432, 0xabcdef00 };
+static const RGBQUAD default_palette_1[2] =
+{
+ { 0x00, 0x00, 0x00 }, { 0xff, 0xff, 0xff }
+};
+
+static const RGBQUAD default_palette_4[16] =
+{
+ { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 },
+ { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x80 },
+ { 0xc0, 0xc0, 0xc0 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff },
+ { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff },
+};
+
+static const RGBQUAD default_palette_8[256] =
+{
+ { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 },
+ { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0xc0, 0xc0, 0xc0 },
+ { 0xc0, 0xdc, 0xc0 }, { 0xf0, 0xca, 0xa6 }, { 0x00, 0x20, 0x40 }, { 0x00, 0x20, 0x60 },
+ { 0x00, 0x20, 0x80 }, { 0x00, 0x20, 0xa0 }, { 0x00, 0x20, 0xc0 }, { 0x00, 0x20, 0xe0 },
+ { 0x00, 0x40, 0x00 }, { 0x00, 0x40, 0x20 }, { 0x00, 0x40, 0x40 }, { 0x00, 0x40, 0x60 },
+ { 0x00, 0x40, 0x80 }, { 0x00, 0x40, 0xa0 }, { 0x00, 0x40, 0xc0 }, { 0x00, 0x40, 0xe0 },
+ { 0x00, 0x60, 0x00 }, { 0x00, 0x60, 0x20 }, { 0x00, 0x60, 0x40 }, { 0x00, 0x60, 0x60 },
+ { 0x00, 0x60, 0x80 }, { 0x00, 0x60, 0xa0 }, { 0x00, 0x60, 0xc0 }, { 0x00, 0x60, 0xe0 },
+ { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x20 }, { 0x00, 0x80, 0x40 }, { 0x00, 0x80, 0x60 },
+ { 0x00, 0x80, 0x80 }, { 0x00, 0x80, 0xa0 }, { 0x00, 0x80, 0xc0 }, { 0x00, 0x80, 0xe0 },
+ { 0x00, 0xa0, 0x00 }, { 0x00, 0xa0, 0x20 }, { 0x00, 0xa0, 0x40 }, { 0x00, 0xa0, 0x60 },
+ { 0x00, 0xa0, 0x80 }, { 0x00, 0xa0, 0xa0 }, { 0x00, 0xa0, 0xc0 }, { 0x00, 0xa0, 0xe0 },
+ { 0x00, 0xc0, 0x00 }, { 0x00, 0xc0, 0x20 }, { 0x00, 0xc0, 0x40 }, { 0x00, 0xc0, 0x60 },
+ { 0x00, 0xc0, 0x80 }, { 0x00, 0xc0, 0xa0 }, { 0x00, 0xc0, 0xc0 }, { 0x00, 0xc0, 0xe0 },
+ { 0x00, 0xe0, 0x00 }, { 0x00, 0xe0, 0x20 }, { 0x00, 0xe0, 0x40 }, { 0x00, 0xe0, 0x60 },
+ { 0x00, 0xe0, 0x80 }, { 0x00, 0xe0, 0xa0 }, { 0x00, 0xe0, 0xc0 }, { 0x00, 0xe0, 0xe0 },
+ { 0x40, 0x00, 0x00 }, { 0x40, 0x00, 0x20 }, { 0x40, 0x00, 0x40 }, { 0x40, 0x00, 0x60 },
+ { 0x40, 0x00, 0x80 }, { 0x40, 0x00, 0xa0 }, { 0x40, 0x00, 0xc0 }, { 0x40, 0x00, 0xe0 },
+ { 0x40, 0x20, 0x00 }, { 0x40, 0x20, 0x20 }, { 0x40, 0x20, 0x40 }, { 0x40, 0x20, 0x60 },
+ { 0x40, 0x20, 0x80 }, { 0x40, 0x20, 0xa0 }, { 0x40, 0x20, 0xc0 }, { 0x40, 0x20, 0xe0 },
+ { 0x40, 0x40, 0x00 }, { 0x40, 0x40, 0x20 }, { 0x40, 0x40, 0x40 }, { 0x40, 0x40, 0x60 },
+ { 0x40, 0x40, 0x80 }, { 0x40, 0x40, 0xa0 }, { 0x40, 0x40, 0xc0 }, { 0x40, 0x40, 0xe0 },
+ { 0x40, 0x60, 0x00 }, { 0x40, 0x60, 0x20 }, { 0x40, 0x60, 0x40 }, { 0x40, 0x60, 0x60 },
+ { 0x40, 0x60, 0x80 }, { 0x40, 0x60, 0xa0 }, { 0x40, 0x60, 0xc0 }, { 0x40, 0x60, 0xe0 },
+ { 0x40, 0x80, 0x00 }, { 0x40, 0x80, 0x20 }, { 0x40, 0x80, 0x40 }, { 0x40, 0x80, 0x60 },
+ { 0x40, 0x80, 0x80 }, { 0x40, 0x80, 0xa0 }, { 0x40, 0x80, 0xc0 }, { 0x40, 0x80, 0xe0 },
+ { 0x40, 0xa0, 0x00 }, { 0x40, 0xa0, 0x20 }, { 0x40, 0xa0, 0x40 }, { 0x40, 0xa0, 0x60 },
+ { 0x40, 0xa0, 0x80 }, { 0x40, 0xa0, 0xa0 }, { 0x40, 0xa0, 0xc0 }, { 0x40, 0xa0, 0xe0 },
+ { 0x40, 0xc0, 0x00 }, { 0x40, 0xc0, 0x20 }, { 0x40, 0xc0, 0x40 }, { 0x40, 0xc0, 0x60 },
+ { 0x40, 0xc0, 0x80 }, { 0x40, 0xc0, 0xa0 }, { 0x40, 0xc0, 0xc0 }, { 0x40, 0xc0, 0xe0 },
+ { 0x40, 0xe0, 0x00 }, { 0x40, 0xe0, 0x20 }, { 0x40, 0xe0, 0x40 }, { 0x40, 0xe0, 0x60 },
+ { 0x40, 0xe0, 0x80 }, { 0x40, 0xe0, 0xa0 }, { 0x40, 0xe0, 0xc0 }, { 0x40, 0xe0, 0xe0 },
+ { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x20 }, { 0x80, 0x00, 0x40 }, { 0x80, 0x00, 0x60 },
+ { 0x80, 0x00, 0x80 }, { 0x80, 0x00, 0xa0 }, { 0x80, 0x00, 0xc0 }, { 0x80, 0x00, 0xe0 },
+ { 0x80, 0x20, 0x00 }, { 0x80, 0x20, 0x20 }, { 0x80, 0x20, 0x40 }, { 0x80, 0x20, 0x60 },
+ { 0x80, 0x20, 0x80 }, { 0x80, 0x20, 0xa0 }, { 0x80, 0x20, 0xc0 }, { 0x80, 0x20, 0xe0 },
+ { 0x80, 0x40, 0x00 }, { 0x80, 0x40, 0x20 }, { 0x80, 0x40, 0x40 }, { 0x80, 0x40, 0x60 },
+ { 0x80, 0x40, 0x80 }, { 0x80, 0x40, 0xa0 }, { 0x80, 0x40, 0xc0 }, { 0x80, 0x40, 0xe0 },
+ { 0x80, 0x60, 0x00 }, { 0x80, 0x60, 0x20 }, { 0x80, 0x60, 0x40 }, { 0x80, 0x60, 0x60 },
+ { 0x80, 0x60, 0x80 }, { 0x80, 0x60, 0xa0 }, { 0x80, 0x60, 0xc0 }, { 0x80, 0x60, 0xe0 },
+ { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x20 }, { 0x80, 0x80, 0x40 }, { 0x80, 0x80, 0x60 },
+ { 0x80, 0x80, 0x80 }, { 0x80, 0x80, 0xa0 }, { 0x80, 0x80, 0xc0 }, { 0x80, 0x80, 0xe0 },
+ { 0x80, 0xa0, 0x00 }, { 0x80, 0xa0, 0x20 }, { 0x80, 0xa0, 0x40 }, { 0x80, 0xa0, 0x60 },
+ { 0x80, 0xa0, 0x80 }, { 0x80, 0xa0, 0xa0 }, { 0x80, 0xa0, 0xc0 }, { 0x80, 0xa0, 0xe0 },
+ { 0x80, 0xc0, 0x00 }, { 0x80, 0xc0, 0x20 }, { 0x80, 0xc0, 0x40 }, { 0x80, 0xc0, 0x60 },
+ { 0x80, 0xc0, 0x80 }, { 0x80, 0xc0, 0xa0 }, { 0x80, 0xc0, 0xc0 }, { 0x80, 0xc0, 0xe0 },
+ { 0x80, 0xe0, 0x00 }, { 0x80, 0xe0, 0x20 }, { 0x80, 0xe0, 0x40 }, { 0x80, 0xe0, 0x60 },
+ { 0x80, 0xe0, 0x80 }, { 0x80, 0xe0, 0xa0 }, { 0x80, 0xe0, 0xc0 }, { 0x80, 0xe0, 0xe0 },
+ { 0xc0, 0x00, 0x00 }, { 0xc0, 0x00, 0x20 }, { 0xc0, 0x00, 0x40 }, { 0xc0, 0x00, 0x60 },
+ { 0xc0, 0x00, 0x80 }, { 0xc0, 0x00, 0xa0 }, { 0xc0, 0x00, 0xc0 }, { 0xc0, 0x00, 0xe0 },
+ { 0xc0, 0x20, 0x00 }, { 0xc0, 0x20, 0x20 }, { 0xc0, 0x20, 0x40 }, { 0xc0, 0x20, 0x60 },
+ { 0xc0, 0x20, 0x80 }, { 0xc0, 0x20, 0xa0 }, { 0xc0, 0x20, 0xc0 }, { 0xc0, 0x20, 0xe0 },
+ { 0xc0, 0x40, 0x00 }, { 0xc0, 0x40, 0x20 }, { 0xc0, 0x40, 0x40 }, { 0xc0, 0x40, 0x60 },
+ { 0xc0, 0x40, 0x80 }, { 0xc0, 0x40, 0xa0 }, { 0xc0, 0x40, 0xc0 }, { 0xc0, 0x40, 0xe0 },
+ { 0xc0, 0x60, 0x00 }, { 0xc0, 0x60, 0x20 }, { 0xc0, 0x60, 0x40 }, { 0xc0, 0x60, 0x60 },
+ { 0xc0, 0x60, 0x80 }, { 0xc0, 0x60, 0xa0 }, { 0xc0, 0x60, 0xc0 }, { 0xc0, 0x60, 0xe0 },
+ { 0xc0, 0x80, 0x00 }, { 0xc0, 0x80, 0x20 }, { 0xc0, 0x80, 0x40 }, { 0xc0, 0x80, 0x60 },
+ { 0xc0, 0x80, 0x80 }, { 0xc0, 0x80, 0xa0 }, { 0xc0, 0x80, 0xc0 }, { 0xc0, 0x80, 0xe0 },
+ { 0xc0, 0xa0, 0x00 }, { 0xc0, 0xa0, 0x20 }, { 0xc0, 0xa0, 0x40 }, { 0xc0, 0xa0, 0x60 },
+ { 0xc0, 0xa0, 0x80 }, { 0xc0, 0xa0, 0xa0 }, { 0xc0, 0xa0, 0xc0 }, { 0xc0, 0xa0, 0xe0 },
+ { 0xc0, 0xc0, 0x00 }, { 0xc0, 0xc0, 0x20 }, { 0xc0, 0xc0, 0x40 }, { 0xc0, 0xc0, 0x60 },
+ { 0xc0, 0xc0, 0x80 }, { 0xc0, 0xc0, 0xa0 }, { 0xf0, 0xfb, 0xff }, { 0xa4, 0xa0, 0xa0 },
+ { 0x80, 0x80, 0x80 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff },
+ { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff }
+};
+
+static HPALETTE create_default_palette( int bpp )
+{
+ char pal_buffer[sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY)];
+ LOGPALETTE *pal = (LOGPALETTE *)pal_buffer;
+ PALETTEENTRY *entries = pal->palPalEntry;
+ int i;
+
+ pal->palVersion = 0x300;
+ pal->palNumEntries = 1 << bpp;
+ switch (bpp)
+ {
+ case 1:
+ for (i = 0; i < 2; i++)
+ {
+ entries[i].peRed = default_palette_1[i].rgbRed;
+ entries[i].peGreen = default_palette_1[i].rgbGreen;
+ entries[i].peBlue = default_palette_1[i].rgbBlue;
+ entries[i].peFlags = 0;
+ }
+ break;
+ case 4:
+ for (i = 0; i < 16; i++)
+ {
+ entries[i].peRed = default_palette_4[i].rgbRed;
+ entries[i].peGreen = default_palette_4[i].rgbGreen;
+ entries[i].peBlue = default_palette_4[i].rgbBlue;
+ entries[i].peFlags = 0;
+ }
+ break;
+ case 8:
+ for (i = 0; i < 256; i++)
+ {
+ entries[i].peRed = default_palette_8[i].rgbRed;
+ entries[i].peGreen = default_palette_8[i].rgbGreen;
+ entries[i].peBlue = default_palette_8[i].rgbBlue;
+ entries[i].peFlags = 0;
+ }
+ break;
+ }
+ return CreatePalette( pal );
+}
+
static inline void solid_patblt( HDC hdc, int x, int y, int width, int height, COLORREF color )
{
HBRUSH brush = CreateSolidBrush( color );
BOOL dib_is_8bpp_gray = (bmi->bmiHeader.biBitCount == 8 && bmi->bmiColors[1].rgbRed == 1);
BLENDFUNCTION blend;
COLORREF old_text, old_bkgnd;
- HPALETTE hpal;
+ HPALETTE hpal, old_hpal;
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
entries[i].peFlags = 0;
}
hpal = CreatePalette( pal );
- SelectPalette( hdc, hpal, FALSE );
+ old_hpal = SelectPalette( hdc, hpal, FALSE );
solid_patblt( hdc, 20, 10, 10, 10, PALETTEINDEX(15) );
Rectangle( hdc, 0, 0, 10, 10 );
SelectObject( hdc, orig_brush );
DeleteObject( dib_brush );
- SelectPalette( hdc, GetStockObject(DEFAULT_PALETTE), FALSE );
+ SelectPalette( hdc, old_hpal, FALSE );
DeleteObject( hpal );
/* NT4 broken for all cases, W2K for 1 bpp only */
SelectObject( hdc, solid_brush );
ret = ExtFloodFill( hdc, 100, 100, RGB( 0, 0xff, 0 ), FLOODFILLSURFACE );
- ok (!ret == !!dib_is_1bpp, "got ret %d\n", ret);
+ ok (ret, "got ret %d\n", ret);
compare_hash(hdc, bmi, bits, "flood fill" );
ExtSelectClipRgn( hdc, NULL, RGN_COPY );
static void draw_text_2( HDC hdc, BITMAPINFO *bmi, BYTE *bits, BOOL aa )
{
DWORD dib_size = get_dib_size(bmi), ret;
- LOGFONT lf;
+ LOGFONTA lf;
HFONT font;
GLYPHMETRICS gm;
BYTE g_buf[10000];
int i, stride, x, y;
static const MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
char *eto_hash = NULL, *diy_hash = NULL;
- static const char *str = "Hello Wine";
+ static const char str[] = "Hello Wine";
POINT origin, g_org;
static const BYTE vals[4] = { 0x00, 0x00, 0x00, 0x00 };
- TEXTMETRIC tm;
+ TEXTMETRICA tm;
COLORREF text_color;
for(i = 0; i < dib_size; i++)
lf.lfHeight = 24;
lf.lfQuality = aa ? ANTIALIASED_QUALITY : NONANTIALIASED_QUALITY;
- font = CreateFontIndirect( &lf );
+ font = CreateFontIndirectA( &lf );
font = SelectObject( hdc, font );
- GetTextMetrics( hdc, &tm );
+ GetTextMetricsA( hdc, &tm );
if (!(tm.tmPitchAndFamily & TMPF_VECTOR))
{
skip( "skipping as a bitmap font has been selected for Tahoma.\n" );
origin.x = 10;
origin.y = 100;
- ExtTextOut( hdc, origin.x, origin.y, 0, NULL, str, strlen(str), NULL );
+ ExtTextOutA( hdc, origin.x, origin.y, 0, NULL, str, strlen(str), NULL );
eto_hash = hash_dib( bmi, bits );
for(i = 0; i < dib_size; i++)
{
DWORD ggo_flags = aa ? GGO_GRAY4_BITMAP : GGO_BITMAP;
- ret = GetGlyphOutline( hdc, str[i], ggo_flags, &gm, 0, NULL, &identity );
+ ret = GetGlyphOutlineA( hdc, str[i], ggo_flags, &gm, 0, NULL, &identity );
if (ret == GDI_ERROR) continue;
- if (ret) GetGlyphOutline( hdc, str[i], ggo_flags, &gm, sizeof(g_buf), g_buf, &identity );
+ if (ret) GetGlyphOutlineA( hdc, str[i], ggo_flags, &gm, sizeof(g_buf), g_buf, &identity );
g_org.x = origin.x + gm.gmptGlyphOrigin.x;
g_org.y = origin.y - gm.gmptGlyphOrigin.y;
BYTE *bits;
HBITMAP dib, orig_bm;
DIBSECTION ds;
+ HPALETTE default_palette, old_hpal;
int i;
mem_dc = CreateCompatibleDC(NULL);
orig_bm = SelectObject(mem_dc, dib);
+ default_palette = create_default_palette( 8 );
+ old_hpal = SelectPalette( mem_dc, default_palette, FALSE );
+
dst_format = "8888";
current_sha1 = sha1_graphics_a8r8g8b8;
draw_graphics(mem_dc, bmi, bits);
ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
orig_bm = SelectObject(mem_dc, dib);
+ SelectPalette( mem_dc, default_palette, FALSE );
dst_format = "8888 - bitfields";
current_sha1 = sha1_graphics_a8r8g8b8_bitfields;
ok(dib != NULL, "ret NULL\n");
orig_bm = SelectObject(mem_dc, dib);
+ DeleteObject( SelectPalette( mem_dc, create_default_palette(4), FALSE ));
dst_format = "4";
current_sha1 = sha1_graphics_4;
ok(dib != NULL, "ret NULL\n");
orig_bm = SelectObject(mem_dc, dib);
+ DeleteObject( SelectPalette( mem_dc, create_default_palette(1), FALSE ));
dst_format = "1";
current_sha1 = sha1_graphics_1;
draw_graphics(mem_dc, bmi, bits);
draw_text(mem_dc, bmi, bits);
+ DeleteObject( SelectPalette( mem_dc, old_hpal, FALSE ));
SelectObject(mem_dc, orig_bm);
DeleteObject(dib);
#include "wine/test.h"
/* Do not allow more than 1 deviation here */
-#define match_off_by_1(a, b) (abs((a) - (b)) <= 1)
+#define match_off_by_1(a, b, exact) (abs((a) - (b)) <= ((exact) ? 0 : 1))
#define near_match(a, b) (abs((a) - (b)) <= 6)
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
static BOOL (WINAPI *pGetCharABCWidthsA)(HDC hdc, UINT first, UINT last, LPABC abc);
static BOOL (WINAPI *pGetCharABCWidthsW)(HDC hdc, UINT first, UINT last, LPABC abc);
static BOOL (WINAPI *pGetCharABCWidthsFloatW)(HDC hdc, UINT first, UINT last, LPABCFLOAT abc);
+static BOOL (WINAPI *pGetCharWidth32A)(HDC hdc, UINT first, UINT last, LPINT buffer);
+static BOOL (WINAPI *pGetCharWidth32W)(HDC hdc, UINT first, UINT last, LPINT buffer);
static DWORD (WINAPI *pGetFontUnicodeRanges)(HDC hdc, LPGLYPHSET lpgs);
static DWORD (WINAPI *pGetGlyphIndicesA)(HDC hdc, LPCSTR lpstr, INT count, LPWORD pgi, DWORD flags);
static DWORD (WINAPI *pGetGlyphIndicesW)(HDC hdc, LPCWSTR lpstr, INT count, LPWORD pgi, DWORD flags);
static BOOL (WINAPI *pGetTextExtentExPointI)(HDC hdc, const WORD *indices, INT count, INT max_ext,
LPINT nfit, LPINT dxs, LPSIZE size );
static BOOL (WINAPI *pGdiRealizationInfo)(HDC hdc, DWORD *);
-static HFONT (WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDV *);
+static HFONT (WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *);
static HANDLE (WINAPI *pAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *);
static BOOL (WINAPI *pRemoveFontMemResourceEx)(HANDLE);
static INT (WINAPI *pAddFontResourceExA)(LPCSTR, DWORD, PVOID);
static const MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} };
static WORD system_lang_id;
+#ifdef WORDS_BIGENDIAN
+#define GET_BE_WORD(x) (x)
+#define GET_BE_DWORD(x) (x)
+#else
+#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)));
+#endif
+
+#define MS_MAKE_TAG(ch0, ch1, ch2, ch3) \
+ ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
+ ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
+#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')
+
static void init(void)
{
hgdi32 = GetModuleHandleA("gdi32.dll");
pGetCharABCWidthsA = (void *)GetProcAddress(hgdi32, "GetCharABCWidthsA");
pGetCharABCWidthsW = (void *)GetProcAddress(hgdi32, "GetCharABCWidthsW");
pGetCharABCWidthsFloatW = (void *)GetProcAddress(hgdi32, "GetCharABCWidthsFloatW");
+ pGetCharWidth32A = (void *)GetProcAddress(hgdi32, "GetCharWidth32A");
+ pGetCharWidth32W = (void *)GetProcAddress(hgdi32, "GetCharWidth32W");
pGetFontUnicodeRanges = (void *)GetProcAddress(hgdi32, "GetFontUnicodeRanges");
pGetGlyphIndicesA = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesA");
pGetGlyphIndicesW = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesW");
system_lang_id = PRIMARYLANGID(GetSystemDefaultLangID());
}
-static INT CALLBACK is_truetype_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+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 ret;
}
-static INT CALLBACK is_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK is_font_installed_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
{
return 0;
}
return ret;
}
+static void *get_res_data(const char *fontname, DWORD *rsrc_size)
+{
+ HRSRC rsrc;
+ void *rsrc_data;
+
+ rsrc = FindResourceA(GetModuleHandleA(NULL), fontname, (LPCSTR)RT_RCDATA);
+ if (!rsrc) return NULL;
+
+ rsrc_data = LockResource(LoadResource(GetModuleHandleA(NULL), rsrc));
+ if (!rsrc_data) return NULL;
+
+ *rsrc_size = SizeofResource(GetModuleHandleA(NULL), rsrc);
+ if (!*rsrc_size) return NULL;
+
+ return rsrc_data;
+}
+
+static BOOL write_tmp_file( const void *data, DWORD *size, char *tmp_name )
+{
+ char tmp_path[MAX_PATH];
+ HANDLE hfile;
+ BOOL ret;
+
+ GetTempPathA(MAX_PATH, tmp_path);
+ GetTempFileNameA(tmp_path, "ttf", 0, tmp_name);
+
+ hfile = CreateFileA(tmp_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+ if (hfile == INVALID_HANDLE_VALUE) return FALSE;
+
+ ret = WriteFile(hfile, data, *size, size, NULL);
+
+ CloseHandle(hfile);
+ return ret;
+}
+
+static BOOL write_ttf_file(const char *fontname, char *tmp_name)
+{
+ void *rsrc_data;
+ DWORD rsrc_size;
+
+ rsrc_data = get_res_data( fontname, &rsrc_size );
+ if (!rsrc_data) return FALSE;
+
+ return write_tmp_file( rsrc_data, &rsrc_size, tmp_name );
+}
+
static void check_font(const char* test, const LOGFONTA* lf, HFONT hfont)
{
LOGFONTA getobj_lf;
if (!hfont)
return;
- ret = GetObject(hfont, sizeof(getobj_lf), &getobj_lf);
+ ret = GetObjectA(hfont, sizeof(getobj_lf), &getobj_lf);
/* NT4 tries to be clever and only returns the minimum length */
while (lf->lfFaceName[minlen] && minlen < LF_FACESIZE-1)
minlen++;
DeleteObject(hfont);
}
-static INT CALLBACK font_enum_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK font_enum_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
{
if (type & RASTER_FONTTYPE)
{
- LOGFONT *lf = (LOGFONT *)lParam;
+ LOGFONTA *lf = (LOGFONTA *)lParam;
*lf = *elf;
return 0; /* stop enumeration */
}
INT scale_x, INT scale_y)
{
LOGFONTA lf;
- OUTLINETEXTMETRIC otm;
+ OUTLINETEXTMETRICA otm;
TEXTMETRICA tm;
SIZE size;
INT width_of_A, cx, cy;
DeleteDC(hdc);
}
-static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK find_font_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
{
- LOGFONT *lf = (LOGFONT *)lParam;
+ LOGFONTA *lf = (LOGFONTA *)lParam;
if (elf->lfHeight == lf->lfHeight && !strcmp(elf->lfFaceName, lf->lfFaceName))
{
};
static const int font_log_pixels[] = { 96, 120 };
HDC hdc;
- LOGFONT lf;
+ LOGFONTA lf;
HFONT hfont, old_hfont;
- TEXTMETRIC tm;
+ TEXTMETRICA tm;
INT ret, i, expected_cs, screen_log_pixels, diff, font_res;
char face_name[LF_FACESIZE];
CHARSETINFO csi;
lf.lfCharSet = csi.ciCharset;
trace("looking for %s height %d charset %d\n", lf.lfFaceName, lf.lfHeight, lf.lfCharSet);
- ret = EnumFontFamiliesEx(hdc, &lf, find_font_proc, (LPARAM)&lf, 0);
+ ret = EnumFontFamiliesExA(hdc, &lf, find_font_proc, (LPARAM)&lf, 0);
if (fd[i].height & FH_SCALE)
ok(ret, "scaled font height %d should not be enumerated\n", height);
else
old_hfont = SelectObject(hdc, hfont);
SetLastError(0xdeadbeef);
- ret = GetTextFace(hdc, sizeof(face_name), face_name);
+ ret = GetTextFaceA(hdc, sizeof(face_name), face_name);
ok(ret, "GetTextFace error %u\n", GetLastError());
- if (lstrcmp(face_name, fd[i].face_name) != 0)
+ if (strcmp(face_name, fd[i].face_name) != 0)
{
ok(ret != ANSI_CHARSET, "font charset should not be ANSI_CHARSET\n");
ok(ret != expected_cs, "font charset %d should not be %d\n", ret, expected_cs);
memset(&gm, 0, sizeof(gm));
SetLastError(0xdeadbeef);
- ret = GetGlyphOutline(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
+ ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
todo_wine {
ok(ret == GDI_ERROR, "GetGlyphOutline should fail for a bitmap font\n");
ok(GetLastError() == ERROR_CAN_NOT_COMPLETE, "expected ERROR_CAN_NOT_COMPLETE, got %u\n", GetLastError());
}
- bRet = GetTextMetrics(hdc, &tm);
+ bRet = GetTextMetricsA(hdc, &tm);
ok(bRet, "GetTextMetrics error %d\n", GetLastError());
SetLastError(0xdeadbeef);
/* Don't run the max char width test on System/ANSI_CHARSET. We have extra characters in our font
that make the max width bigger */
- if(strcmp(lf.lfFaceName, "System") || lf.lfCharSet != ANSI_CHARSET)
+ if ((strcmp(lf.lfFaceName, "System") || lf.lfCharSet != ANSI_CHARSET) && tm.tmDigitizedAspectX == 96)
ok(tm.tmMaxCharWidth == fd[i].max_char_width, "%s(%d): tm.tmMaxCharWidth %d != %d\n", fd[i].face_name, height, tm.tmMaxCharWidth, fd[i].max_char_width);
}
else
hdc = CreateCompatibleDC(NULL);
- GetTextExtentPoint(hdc, szAlphabet, strlen(szAlphabet), &size);
+ GetTextExtentPointA(hdc, szAlphabet, strlen(szAlphabet), &size);
avgwidth = ((size.cx / 26) + 1) / 2;
ret = pGdiGetCharDimensions(hdc, &tm, &height);
DeleteDC(hdc);
}
-static int CALLBACK create_font_proc(const LOGFONT *lpelfe,
- const TEXTMETRIC *lpntme,
+static int CALLBACK create_font_proc(const LOGFONTA *lpelfe,
+ const TEXTMETRICA *lpntme,
DWORD FontType, LPARAM lParam)
{
if (FontType & TRUETYPE_FONTTYPE)
{
HFONT hfont;
- hfont = CreateFontIndirect(lpelfe);
+ hfont = CreateFontIndirectA(lpelfe);
if (hfont)
{
*(HFONT *)lParam = hfont;
return 1;
}
+static void ABCWidths_helper(const char* description, HDC hdc, WORD *glyphs, ABC *base_abci, ABC *base_abcw, ABCFLOAT *base_abcf, INT todo)
+{
+ ABC abc[1];
+ ABCFLOAT abcf[1];
+ BOOL ret = FALSE;
+
+ 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);
+ if (todo) todo_wine ok(abc->abcA * base_abci->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
+ else ok(abc->abcA * base_abci->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
+ if (todo) todo_wine ok(abc->abcC * base_abci->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
+ else 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);
+ if (todo) todo_wine ok(abc->abcA * base_abcw->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
+ else ok(abc->abcA * base_abcw->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
+ if (todo) todo_wine ok(abc->abcC * base_abcw->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
+ else ok(abc->abcC * base_abcw->abcC >= 0, "%s: abcC's 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);
+ if (todo) todo_wine ok(abcf->abcfA * base_abcf->abcfA >= 0.0, "%s: abcfA's sign should be unchanged\n", description);
+ else ok(abcf->abcfA * base_abcf->abcfA >= 0.0, "%s: abcfA's should be unchanged\n", description);
+ if (todo) todo_wine ok(abcf->abcfC * base_abcf->abcfC >= 0.0, "%s: abcfC's sign should be unchanged\n", description);
+ else ok(abcf->abcfC * base_abcf->abcfC >= 0.0, "%s: abcfC's sign should be unchanged\n", description);
+}
+
static void test_GetCharABCWidths(void)
{
- static const WCHAR str[] = {'a',0};
+ static const WCHAR str[] = {'i',0};
BOOL ret;
HDC hdc;
LOGFONTA lf;
HFONT hfont;
ABC abc[1];
+ ABC abcw[1];
ABCFLOAT abcf[1];
WORD glyphs[1];
DWORD nb;
+ HWND hwnd;
static const struct
{
UINT first;
{TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE}},
{HANGEUL_CHARSET, 0x8141, 0xac02,
{TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE}},
- {JOHAB_CHARSET, 0x8446, 0x3135,
- {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE}},
{GB2312_CHARSET, 0x8141, 0x4e04,
{TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE}},
{CHINESEBIG5_CHARSET, 0xa142, 0x3001,
lf.lfFaceName[0] = '\0';
lf.lfCharSet = c[i].cs;
lf.lfPitchAndFamily = 0;
- if (EnumFontFamiliesEx(hdc, &lf, create_font_proc, (LPARAM)&hfont, 0))
+ if (EnumFontFamiliesExA(hdc, &lf, create_font_proc, (LPARAM)&hfont, 0))
{
skip("TrueType font for charset %u is not installed\n", c[i].cs);
continue;
DeleteObject(hfont);
}
+ memset(&lf, 0, sizeof(lf));
+ strcpy(lf.lfFaceName, "Tahoma");
+ lf.lfHeight = 200;
+ hfont = CreateFontIndirectA(&lf);
+
+ /* test empty glyph's metrics */
+ hfont = SelectObject(hdc, hfont);
+ ret = pGetCharABCWidthsFloatW(hdc, ' ', ' ', abcf);
+ ok(ret, "GetCharABCWidthsFloatW should have succeeded\n");
+ ok(abcf[0].abcfB == 1.0, "got %f\n", abcf[0].abcfB);
+ ret = pGetCharABCWidthsW(hdc, ' ', ' ', abcw);
+ ok(ret, "GetCharABCWidthsW should have succeeded\n");
+ ok(abcw[0].abcB == 1, "got %u\n", abcw[0].abcB);
+
+ /* 1) prepare unrotated font metrics */
+ ret = pGetCharABCWidthsW(hdc, 'a', 'a', abcw);
+ ok(ret, "GetCharABCWidthsW should have succeeded\n");
+ DeleteObject(SelectObject(hdc, hfont));
+
+ /* 2) get rotated font metrics */
+ lf.lfEscapement = lf.lfOrientation = 900;
+ hfont = CreateFontIndirectA(&lf);
+ hfont = SelectObject(hdc, hfont);
+ ret = pGetCharABCWidthsW(hdc, 'a', 'a', abc);
+ ok(ret, "GetCharABCWidthsW should have succeeded\n");
+
+ /* 3) compare ABC results */
+ ok(match_off_by_1(abcw[0].abcA, abc[0].abcA, FALSE),
+ "got %d, expected %d (A)\n", abc[0].abcA, abcw[0].abcA);
+ ok(match_off_by_1(abcw[0].abcB, abc[0].abcB, FALSE),
+ "got %d, expected %d (B)\n", abc[0].abcB, abcw[0].abcB);
+ ok(match_off_by_1(abcw[0].abcC, abc[0].abcC, FALSE),
+ "got %d, expected %d (C)\n", abc[0].abcC, abcw[0].abcC);
+
+ DeleteObject(SelectObject(hdc, hfont));
ReleaseDC(NULL, hdc);
+
+ trace("ABC sign test for a variety of transforms:\n");
+ memset(&lf, 0, sizeof(lf));
+ strcpy(lf.lfFaceName, "Tahoma");
+ lf.lfHeight = 20;
+ hfont = CreateFontIndirectA(&lf);
+ hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
+ 0, 0, 0, NULL);
+ hdc = GetDC(hwnd);
+ SetMapMode(hdc, MM_ANISOTROPIC);
+ SelectObject(hdc, hfont);
+
+ nb = pGetGlyphIndicesW(hdc, str, 1, glyphs, 0);
+ ok(nb == 1, "GetGlyphIndicesW should have returned 1\n");
+
+ ret = pGetCharABCWidthsI(hdc, 0, 1, glyphs, abc);
+ ok(ret, "GetCharABCWidthsI should have succeeded\n");
+ ret = pGetCharABCWidthsW(hdc, 'i', 'i', abcw);
+ ok(ret, "GetCharABCWidthsW should have succeeded\n");
+ ret = pGetCharABCWidthsFloatW(hdc, 'i', 'i', abcf);
+ ok(ret, "GetCharABCWidthsFloatW should have succeeded\n");
+
+ ABCWidths_helper("LTR", hdc, glyphs, abc, abcw, abcf, 0);
+ SetWindowExtEx(hdc, -1, -1, NULL);
+ SetGraphicsMode(hdc, GM_COMPATIBLE);
+ ABCWidths_helper("LTR -1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ ABCWidths_helper("LTR -1 advanced", hdc, glyphs, abc, abcw, abcf, 1);
+ SetWindowExtEx(hdc, 1, 1, NULL);
+ SetGraphicsMode(hdc, GM_COMPATIBLE);
+ ABCWidths_helper("LTR 1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ ABCWidths_helper("LTR 1 advanced", hdc, glyphs, abc, abcw, abcf, 0);
+
+ ReleaseDC(hwnd, hdc);
+ DestroyWindow(hwnd);
+
+ trace("RTL layout\n");
+ hwnd = CreateWindowExA(WS_EX_LAYOUTRTL, "static", "", WS_POPUP, 0,0,100,100,
+ 0, 0, 0, NULL);
+ hdc = GetDC(hwnd);
+ SetMapMode(hdc, MM_ANISOTROPIC);
+ SelectObject(hdc, hfont);
+
+ ABCWidths_helper("RTL", hdc, glyphs, abc, abcw, abcf, 0);
+ SetWindowExtEx(hdc, -1, -1, NULL);
+ SetGraphicsMode(hdc, GM_COMPATIBLE);
+ ABCWidths_helper("RTL -1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ ABCWidths_helper("RTL -1 advanced", hdc, glyphs, abc, abcw, abcf, 0);
+ SetWindowExtEx(hdc, 1, 1, NULL);
+ SetGraphicsMode(hdc, GM_COMPATIBLE);
+ ABCWidths_helper("RTL 1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ ABCWidths_helper("RTL 1 advanced", hdc, glyphs, abc, abcw, abcf, 1);
+
+ ReleaseDC(hwnd, hdc);
+ DestroyWindow(hwnd);
+ DeleteObject(hfont);
}
static void test_text_extents(void)
{
static const WCHAR wt[] = {'O','n','e','\n','t','w','o',' ','3',0};
LPINT extents;
- INT i, len, fit1, fit2;
+ INT i, len, fit1, fit2, extents2[3];
LOGFONTA lf;
TEXTMETRICA tm;
HDC hdc;
GetTextExtentExPointW(hdc, wt, 2, 0, NULL, NULL, &sz1);
ok(sz1.cx == sz2.cx && sz1.cy == sz2.cy,
"GetTextExtentExPointW with lpnFit and alpDx both NULL returns incorrect results\n");
- HeapFree(GetProcessHeap(), 0, extents);
/* extents functions fail with -ve counts (the interesting case being -1) */
ret = GetTextExtentPointA(hdc, "o", -1, &sz);
hfont = SelectObject(hdc, hfont);
DeleteObject(hfont);
+
+ /* non-MM_TEXT mapping mode */
+ lf.lfHeight = 2000;
+ hfont = CreateFontIndirectA(&lf);
+ hfont = SelectObject(hdc, hfont);
+
+ SetMapMode( hdc, MM_HIMETRIC );
+ ret = GetTextExtentExPointW(hdc, wt, 3, 0, NULL, extents, &sz);
+ ok(ret, "got %d\n", ret);
+ ok(sz.cx == extents[2], "got %d vs %d\n", sz.cx, extents[2]);
+
+ ret = GetTextExtentExPointW(hdc, wt, 3, extents[1], &fit1, extents2, &sz2);
+ ok(ret, "got %d\n", ret);
+ ok(fit1 == 2, "got %d\n", fit1);
+ ok(sz2.cx == sz.cx, "got %d vs %d\n", sz2.cx, sz.cx);
+ for(i = 0; i < 2; i++)
+ ok(extents2[i] == extents[i], "%d: %d, %d\n", i, extents2[i], extents[i]);
+
+ hfont = SelectObject(hdc, hfont);
+ DeleteObject(hfont);
+ HeapFree(GetProcessHeap(), 0, extents);
ReleaseDC(NULL, hdc);
}
DWORD flags = 0;
WCHAR testtext[] = {'T','e','s','t',0xffff,0};
WORD glyphs[(sizeof(testtext)/2)-1];
- TEXTMETRIC textm;
+ TEXTMETRICA textm;
HFONT hOldFont;
if (!pGetGlyphIndicesW) {
hfont = CreateFontIndirectA(&lf);
ok(hfont != 0, "CreateFontIndirectEx failed\n");
- ok(GetTextMetrics(hdc, &textm), "GetTextMetric failed\n");
+ ok(GetTextMetricsA(hdc, &textm), "GetTextMetric failed\n");
if (textm.tmCharSet == ANSI_CHARSET)
{
flags |= GGI_MARK_NONEXISTING_GLYPHS;
hfont = CreateFontIndirectA(&lf);
hOldFont = SelectObject(hdc, hfont);
- ok(GetTextMetrics(hdc, &textm), "GetTextMetric failed\n");
+ ok(GetTextMetricsA(hdc, &textm), "GetTextMetric failed\n");
flags |= GGI_MARK_NONEXISTING_GLYPHS;
charcount = pGetGlyphIndicesW(hdc, testtext, (sizeof(testtext)/2)-1, glyphs, flags);
ok(charcount == 5, "GetGlyphIndicesW count of glyphs should = 5 not %d\n", charcount);
}
#endif
};
- LOGFONT lf;
+ LOGFONTA lf;
HFONT hfont, hfont_old;
KERNINGPAIR *kern_pair;
HDC hdc;
memset(&lf, 0, sizeof(lf));
strcpy(lf.lfFaceName, kd[i].face_name);
lf.lfHeight = kd[i].height;
- hfont = CreateFontIndirect(&lf);
+ hfont = CreateFontIndirectA(&lf);
assert(hfont != 0);
hfont_old = SelectObject(hdc, hfont);
uiRet = GetOutlineTextMetricsW(hdc, sizeof(otm), &otm);
ok(uiRet == sizeof(otm), "GetOutlineTextMetricsW error %d\n", GetLastError());
- ok(match_off_by_1(kd[i].tmHeight, otm.otmTextMetrics.tmHeight), "expected %d, got %d\n",
+ ok(match_off_by_1(kd[i].tmHeight, otm.otmTextMetrics.tmHeight, FALSE), "expected %d, got %d\n",
kd[i].tmHeight, otm.otmTextMetrics.tmHeight);
- ok(match_off_by_1(kd[i].tmAscent, otm.otmTextMetrics.tmAscent), "expected %d, got %d\n",
+ ok(match_off_by_1(kd[i].tmAscent, otm.otmTextMetrics.tmAscent, FALSE), "expected %d, got %d\n",
kd[i].tmAscent, otm.otmTextMetrics.tmAscent);
ok(kd[i].tmDescent == otm.otmTextMetrics.tmDescent, "expected %d, got %d\n",
kd[i].tmDescent, otm.otmTextMetrics.tmDescent);
ReleaseDC(0, hdc);
}
-static void test_height_selection(void)
+struct font_data
{
- static const struct font_data
- {
- const char face_name[LF_FACESIZE];
- int requested_height;
- int weight, height, ascent, descent, int_leading, ext_leading, dpi;
- } fd[] =
- {
- {"Tahoma", -12, FW_NORMAL, 14, 12, 2, 2, 0, 96 },
- {"Tahoma", -24, FW_NORMAL, 29, 24, 5, 5, 0, 96 },
- {"Tahoma", -48, FW_NORMAL, 58, 48, 10, 10, 0, 96 },
- {"Tahoma", -96, FW_NORMAL, 116, 96, 20, 20, 0, 96 },
- {"Tahoma", -192, FW_NORMAL, 232, 192, 40, 40, 0, 96 },
- {"Tahoma", 12, FW_NORMAL, 12, 10, 2, 2, 0, 96 },
- {"Tahoma", 24, FW_NORMAL, 24, 20, 4, 4, 0, 96 },
- {"Tahoma", 48, FW_NORMAL, 48, 40, 8, 8, 0, 96 },
- {"Tahoma", 96, FW_NORMAL, 96, 80, 16, 17, 0, 96 },
- {"Tahoma", 192, FW_NORMAL, 192, 159, 33, 33, 0, 96 }
- };
- HDC hdc;
- LOGFONT lf;
+ const char face_name[LF_FACESIZE];
+ int requested_height;
+ int weight, height, ascent, descent, int_leading, ext_leading, dpi;
+ BOOL exact;
+};
+
+static void test_height( HDC hdc, const struct font_data *fd )
+{
+ LOGFONTA lf;
HFONT hfont, old_hfont;
- TEXTMETRIC tm;
+ TEXTMETRICA tm;
INT ret, i;
- hdc = CreateCompatibleDC(0);
- assert(hdc);
-
- for (i = 0; i < sizeof(fd)/sizeof(fd[0]); i++)
+ for (i = 0; fd[i].face_name[0]; i++)
{
if (!is_truetype_font_installed(fd[i].face_name))
{
lf.lfWeight = fd[i].weight;
strcpy(lf.lfFaceName, fd[i].face_name);
- hfont = CreateFontIndirect(&lf);
+ hfont = CreateFontIndirectA(&lf);
assert(hfont);
old_hfont = SelectObject(hdc, hfont);
- ret = GetTextMetrics(hdc, &tm);
+ ret = GetTextMetricsA(hdc, &tm);
ok(ret, "GetTextMetrics error %d\n", GetLastError());
if(fd[i].dpi == tm.tmDigitizedAspectX)
{
trace("found font %s, height %d charset %x dpi %d\n", lf.lfFaceName, lf.lfHeight, lf.lfCharSet, fd[i].dpi);
ok(tm.tmWeight == fd[i].weight, "%s(%d): tm.tmWeight %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmWeight, fd[i].weight);
- ok(match_off_by_1(tm.tmHeight, fd[i].height), "%s(%d): tm.tmHeight %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmHeight, fd[i].height);
- ok(match_off_by_1(tm.tmAscent, fd[i].ascent), "%s(%d): tm.tmAscent %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmAscent, fd[i].ascent);
- ok(match_off_by_1(tm.tmDescent, fd[i].descent), "%s(%d): tm.tmDescent %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmDescent, fd[i].descent);
-#if 0 /* FIXME: calculation of tmInternalLeading in Wine doesn't match what Windows does */
- ok(tm.tmInternalLeading == fd[i].int_leading, "%s(%d): tm.tmInternalLeading %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmInternalLeading, fd[i].int_leading);
-#endif
+ ok(match_off_by_1(tm.tmHeight, fd[i].height, fd[i].exact), "%s(%d): tm.tmHeight %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmHeight, fd[i].height);
+ ok(match_off_by_1(tm.tmAscent, fd[i].ascent, fd[i].exact), "%s(%d): tm.tmAscent %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmAscent, fd[i].ascent);
+ ok(match_off_by_1(tm.tmDescent, fd[i].descent, fd[i].exact), "%s(%d): tm.tmDescent %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmDescent, fd[i].descent);
+ ok(match_off_by_1(tm.tmInternalLeading, fd[i].int_leading, fd[i].exact), "%s(%d): tm.tmInternalLeading %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmInternalLeading, fd[i].int_leading);
ok(tm.tmExternalLeading == fd[i].ext_leading, "%s(%d): tm.tmExternalLeading %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmExternalLeading, fd[i].ext_leading);
}
SelectObject(hdc, old_hfont);
DeleteObject(hfont);
}
+}
+
+static void *find_ttf_table( void *ttf, DWORD size, DWORD tag )
+{
+ WORD i, num_tables = GET_BE_WORD(*((WORD *)ttf + 2));
+ DWORD *table = (DWORD *)ttf + 3;
+
+ for (i = 0; i < num_tables; i++)
+ {
+ if (table[0] == tag)
+ return (BYTE *)ttf + GET_BE_DWORD(table[2]);
+ table += 4;
+ }
+ return NULL;
+}
+
+static void test_height_selection_vdmx( HDC hdc )
+{
+ static const struct font_data charset_0[] = /* doesn't use VDMX */
+ {
+ { "wine_vdmx", 10, FW_NORMAL, 10, 8, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", 11, FW_NORMAL, 11, 9, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", 12, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", 13, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", 14, FW_NORMAL, 14, 12, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", 15, FW_NORMAL, 15, 12, 3, 3, 0, 96, FALSE },
+ { "wine_vdmx", 16, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
+ { "wine_vdmx", 17, FW_NORMAL, 17, 14, 3, 3, 0, 96, TRUE },
+ { "wine_vdmx", 18, FW_NORMAL, 18, 15, 3, 3, 0, 96, TRUE },
+ { "wine_vdmx", 19, FW_NORMAL, 19, 16, 3, 3, 0, 96, TRUE },
+ { "wine_vdmx", 20, FW_NORMAL, 20, 17, 3, 4, 0, 96, FALSE },
+ { "wine_vdmx", 21, FW_NORMAL, 21, 17, 4, 4, 0, 96, TRUE },
+ { "wine_vdmx", 22, FW_NORMAL, 22, 18, 4, 4, 0, 96, TRUE },
+ { "wine_vdmx", 23, FW_NORMAL, 23, 19, 4, 4, 0, 96, TRUE },
+ { "wine_vdmx", 24, FW_NORMAL, 24, 20, 4, 4, 0, 96, TRUE },
+ { "wine_vdmx", 25, FW_NORMAL, 25, 21, 4, 4, 0, 96, TRUE },
+ { "wine_vdmx", 26, FW_NORMAL, 26, 22, 4, 5, 0, 96, FALSE },
+ { "wine_vdmx", 27, FW_NORMAL, 27, 22, 5, 5, 0, 96, TRUE },
+ { "wine_vdmx", 28, FW_NORMAL, 28, 23, 5, 5, 0, 96, TRUE },
+ { "wine_vdmx", 29, FW_NORMAL, 29, 24, 5, 5, 0, 96, TRUE },
+ { "wine_vdmx", 30, FW_NORMAL, 30, 25, 5, 5, 0, 96, TRUE },
+ { "wine_vdmx", 31, FW_NORMAL, 31, 26, 5, 5, 0, 96, TRUE },
+ { "wine_vdmx", 32, FW_NORMAL, 32, 27, 5, 6, 0, 96, FALSE },
+ { "wine_vdmx", 48, FW_NORMAL, 48, 40, 8, 8, 0, 96, TRUE },
+ { "wine_vdmx", 64, FW_NORMAL, 64, 53, 11, 11, 0, 96, TRUE },
+ { "wine_vdmx", 96, FW_NORMAL, 96, 80, 16, 17, 0, 96, FALSE },
+ { "wine_vdmx", -10, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", -11, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", -12, FW_NORMAL, 14, 12, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", -13, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
+ { "wine_vdmx", -14, FW_NORMAL, 17, 14, 3, 3, 0, 96, TRUE },
+ { "wine_vdmx", -15, FW_NORMAL, 18, 15, 3, 3, 0, 96, TRUE },
+ { "wine_vdmx", -16, FW_NORMAL, 19, 16, 3, 3, 0, 96, TRUE },
+ { "wine_vdmx", -17, FW_NORMAL, 21, 17, 4, 4, 0, 96, TRUE },
+ { "wine_vdmx", -18, FW_NORMAL, 22, 18, 4, 4, 0, 96, TRUE },
+ { "wine_vdmx", -19, FW_NORMAL, 23, 19, 4, 4, 0, 96, TRUE },
+ { "wine_vdmx", -20, FW_NORMAL, 24, 20, 4, 4, 0, 96, TRUE },
+ { "wine_vdmx", -21, FW_NORMAL, 25, 21, 4, 4, 0, 96, TRUE },
+ { "wine_vdmx", -22, FW_NORMAL, 27, 22, 5, 5, 0, 96, TRUE },
+ { "wine_vdmx", -23, FW_NORMAL, 28, 23, 5, 5, 0, 96, TRUE },
+ { "wine_vdmx", -24, FW_NORMAL, 29, 24, 5, 5, 0, 96, TRUE },
+ { "wine_vdmx", -25, FW_NORMAL, 30, 25, 5, 5, 0, 96, TRUE },
+ { "wine_vdmx", -26, FW_NORMAL, 31, 26, 5, 5, 0, 96, TRUE },
+ { "wine_vdmx", -27, FW_NORMAL, 33, 27, 6, 6, 0, 96, TRUE },
+ { "wine_vdmx", -28, FW_NORMAL, 34, 28, 6, 6, 0, 96, TRUE },
+ { "wine_vdmx", -29, FW_NORMAL, 35, 29, 6, 6, 0, 96, TRUE },
+ { "wine_vdmx", -30, FW_NORMAL, 36, 30, 6, 6, 0, 96, TRUE },
+ { "wine_vdmx", -31, FW_NORMAL, 37, 31, 6, 6, 0, 96, TRUE },
+ { "wine_vdmx", -32, FW_NORMAL, 39, 32, 7, 7, 0, 96, TRUE },
+ { "wine_vdmx", -48, FW_NORMAL, 58, 48, 10, 10, 0, 96, TRUE },
+ { "wine_vdmx", -64, FW_NORMAL, 77, 64, 13, 13, 0, 96, TRUE },
+ { "wine_vdmx", -96, FW_NORMAL, 116, 96, 20, 20, 0, 96, TRUE },
+ { "", 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ };
+
+ static const struct font_data charset_1[] = /* Uses VDMX */
+ {
+ { "wine_vdmx", 10, FW_NORMAL, 10, 8, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", 11, FW_NORMAL, 11, 9, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", 12, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", 13, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", 14, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", 15, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", 16, FW_NORMAL, 16, 13, 3, 4, 0, 96, TRUE },
+ { "wine_vdmx", 17, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
+ { "wine_vdmx", 18, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
+ { "wine_vdmx", 19, FW_NORMAL, 19, 15, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", 20, FW_NORMAL, 20, 16, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", 21, FW_NORMAL, 21, 17, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", 22, FW_NORMAL, 22, 18, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", 23, FW_NORMAL, 23, 19, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", 24, FW_NORMAL, 23, 19, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", 25, FW_NORMAL, 25, 21, 4, 6, 0, 96, TRUE },
+ { "wine_vdmx", 26, FW_NORMAL, 26, 22, 4, 6, 0, 96, TRUE },
+ { "wine_vdmx", 27, FW_NORMAL, 27, 23, 4, 6, 0, 96, TRUE },
+ { "wine_vdmx", 28, FW_NORMAL, 27, 23, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", 29, FW_NORMAL, 29, 24, 5, 6, 0, 96, TRUE },
+ { "wine_vdmx", 30, FW_NORMAL, 29, 24, 5, 6, 0, 96, TRUE },
+ { "wine_vdmx", 31, FW_NORMAL, 29, 24, 5, 6, 0, 96, TRUE },
+ { "wine_vdmx", 32, FW_NORMAL, 32, 26, 6, 8, 0, 96, TRUE },
+ { "wine_vdmx", 48, FW_NORMAL, 48, 40, 8, 10, 0, 96, TRUE },
+ { "wine_vdmx", 64, FW_NORMAL, 64, 54, 10, 13, 0, 96, TRUE },
+ { "wine_vdmx", 96, FW_NORMAL, 95, 79, 16, 18, 0, 96, TRUE },
+ { "wine_vdmx", -10, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", -11, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
+ { "wine_vdmx", -12, FW_NORMAL, 16, 13, 3, 4, 0, 96, TRUE },
+ { "wine_vdmx", -13, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
+ { "wine_vdmx", -14, FW_NORMAL, 19, 15, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", -15, FW_NORMAL, 20, 16, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", -16, FW_NORMAL, 21, 17, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", -17, FW_NORMAL, 22, 18, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", -18, FW_NORMAL, 23, 19, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", -19, FW_NORMAL, 25, 21, 4, 6, 0, 96, TRUE },
+ { "wine_vdmx", -20, FW_NORMAL, 26, 22, 4, 6, 0, 96, TRUE },
+ { "wine_vdmx", -21, FW_NORMAL, 27, 23, 4, 6, 0, 96, TRUE },
+ { "wine_vdmx", -22, FW_NORMAL, 27, 23, 4, 5, 0, 96, TRUE },
+ { "wine_vdmx", -23, FW_NORMAL, 29, 24, 5, 6, 0, 96, TRUE },
+ { "wine_vdmx", -24, FW_NORMAL, 32, 26, 6, 8, 0, 96, TRUE },
+ { "wine_vdmx", -25, FW_NORMAL, 32, 26, 6, 7, 0, 96, TRUE },
+ { "wine_vdmx", -26, FW_NORMAL, 33, 27, 6, 7, 0, 96, TRUE },
+ { "wine_vdmx", -27, FW_NORMAL, 35, 29, 6, 8, 0, 96, TRUE },
+ { "wine_vdmx", -28, FW_NORMAL, 36, 30, 6, 8, 0, 96, TRUE },
+ { "wine_vdmx", -29, FW_NORMAL, 36, 30, 6, 7, 0, 96, TRUE },
+ { "wine_vdmx", -30, FW_NORMAL, 38, 32, 6, 8, 0, 96, TRUE },
+ { "wine_vdmx", -31, FW_NORMAL, 39, 33, 6, 8, 0, 96, TRUE },
+ { "wine_vdmx", -32, FW_NORMAL, 40, 33, 7, 8, 0, 96, TRUE },
+ { "wine_vdmx", -48, FW_NORMAL, 60, 50, 10, 12, 0, 96, TRUE },
+ { "wine_vdmx", -64, FW_NORMAL, 81, 67, 14, 17, 0, 96, TRUE },
+ { "wine_vdmx", -96, FW_NORMAL, 119, 99, 20, 23, 0, 96, TRUE },
+ { "", 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ };
+
+ static const struct vdmx_data
+ {
+ WORD version;
+ BYTE bCharSet;
+ const struct font_data *fd;
+ } data[] =
+ {
+ { 0, 0, charset_0 },
+ { 0, 1, charset_1 },
+ { 1, 0, charset_0 },
+ { 1, 1, charset_1 }
+ };
+ int i;
+ DWORD size, num;
+ WORD *vdmx_header;
+ BYTE *ratio_rec;
+ char ttf_name[MAX_PATH];
+ void *res, *copy;
+
+ if (!pAddFontResourceExA)
+ {
+ win_skip("AddFontResourceExA unavailable\n");
+ return;
+ }
+
+ for (i = 0; i < sizeof(data) / sizeof(data[0]); i++)
+ {
+ res = get_res_data( "wine_vdmx.ttf", &size );
+
+ copy = HeapAlloc( GetProcessHeap(), 0, size );
+ memcpy( copy, res, size );
+ vdmx_header = find_ttf_table( copy, size, MS_MAKE_TAG('V','D','M','X') );
+ vdmx_header[0] = GET_BE_WORD( data[i].version );
+ ok( GET_BE_WORD( vdmx_header[1] ) == 1, "got %04x\n", GET_BE_WORD( vdmx_header[1] ) );
+ ok( GET_BE_WORD( vdmx_header[2] ) == 1, "got %04x\n", GET_BE_WORD( vdmx_header[2] ) );
+ ratio_rec = (BYTE *)&vdmx_header[3];
+ ratio_rec[0] = data[i].bCharSet;
+
+ write_tmp_file( copy, &size, ttf_name );
+ HeapFree( GetProcessHeap(), 0, copy );
+
+ ok( !is_truetype_font_installed("wine_vdmx"), "Already installed\n" );
+ num = pAddFontResourceExA( ttf_name, FR_PRIVATE, 0 );
+ if (!num) win_skip("Unable to add ttf font resource\n");
+ else
+ {
+ ok( is_truetype_font_installed("wine_vdmx"), "Not installed\n" );
+ test_height( hdc, data[i].fd );
+ pRemoveFontResourceExA( ttf_name, FR_PRIVATE, 0 );
+ }
+ DeleteFileA( ttf_name );
+ }
+}
+
+static void test_height_selection(void)
+{
+ static const struct font_data tahoma[] =
+ {
+ {"Tahoma", -12, FW_NORMAL, 14, 12, 2, 2, 0, 96, TRUE },
+ {"Tahoma", -24, FW_NORMAL, 29, 24, 5, 5, 0, 96, TRUE },
+ {"Tahoma", -48, FW_NORMAL, 58, 48, 10, 10, 0, 96, TRUE },
+ {"Tahoma", -96, FW_NORMAL, 116, 96, 20, 20, 0, 96, TRUE },
+ {"Tahoma", -192, FW_NORMAL, 232, 192, 40, 40, 0, 96, TRUE },
+ {"Tahoma", 12, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
+ {"Tahoma", 24, FW_NORMAL, 24, 20, 4, 4, 0, 96, TRUE },
+ {"Tahoma", 48, FW_NORMAL, 48, 40, 8, 8, 0, 96, TRUE },
+ {"Tahoma", 96, FW_NORMAL, 96, 80, 16, 17, 0, 96, FALSE },
+ {"Tahoma", 192, FW_NORMAL, 192, 159, 33, 33, 0, 96, TRUE },
+ {"", 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ };
+ HDC hdc = CreateCompatibleDC(0);
+ assert(hdc);
+
+ test_height( hdc, tahoma );
+ test_height_selection_vdmx( hdc );
DeleteDC(hdc);
}
static void test_GetOutlineTextMetrics(void)
{
- OUTLINETEXTMETRIC *otm;
- LOGFONT lf;
+ OUTLINETEXTMETRICA *otm;
+ LOGFONTA lf;
HFONT hfont, hfont_old;
HDC hdc;
DWORD ret, otm_size;
lf.lfWeight = FW_NORMAL;
lf.lfPitchAndFamily = DEFAULT_PITCH;
lf.lfQuality = PROOF_QUALITY;
- hfont = CreateFontIndirect(&lf);
+ hfont = CreateFontIndirectA(&lf);
assert(hfont != 0);
hfont_old = SelectObject(hdc, hfont);
- otm_size = GetOutlineTextMetrics(hdc, 0, NULL);
+ otm_size = GetOutlineTextMetricsA(hdc, 0, NULL);
trace("otm buffer size %u (0x%x)\n", otm_size, otm_size);
otm = HeapAlloc(GetProcessHeap(), 0, otm_size);
memset(otm, 0xAA, otm_size);
SetLastError(0xdeadbeef);
otm->otmSize = sizeof(*otm); /* just in case for Win9x compatibility */
- ret = GetOutlineTextMetrics(hdc, otm->otmSize, otm);
+ ret = GetOutlineTextMetricsA(hdc, otm->otmSize, otm);
ok(ret == 1 /* Win9x */ ||
ret == otm->otmSize /* XP*/,
"expected %u, got %u, error %d\n", otm->otmSize, ret, GetLastError());
memset(otm, 0xAA, otm_size);
SetLastError(0xdeadbeef);
otm->otmSize = otm_size; /* just in case for Win9x compatibility */
- ret = GetOutlineTextMetrics(hdc, otm->otmSize, otm);
+ ret = GetOutlineTextMetricsA(hdc, otm->otmSize, otm);
ok(ret == 1 /* Win9x */ ||
ret == otm->otmSize /* XP*/,
"expected %u, got %u, error %d\n", otm->otmSize, ret, GetLastError());
memset(&unset_ptr, 0xAA, sizeof(unset_ptr));
SetLastError(0xdeadbeef);
otm->otmSize = sizeof(*otm) - sizeof(LPSTR); /* just in case for Win9x compatibility */
- ret = GetOutlineTextMetrics(hdc, otm->otmSize, otm);
+ ret = GetOutlineTextMetricsA(hdc, otm->otmSize, otm);
ok(ret == 1 /* Win9x */ ||
ret == otm->otmSize /* XP*/,
"expected %u, got %u, error %d\n", otm->otmSize, ret, GetLastError());
ReleaseDC(0, hdc);
}
-static void testJustification(HDC hdc, PSTR str, RECT *clientArea)
+static void testJustification(HDC hdc, PCSTR str, RECT *clientArea)
{
INT y,
breakCount,
areaWidth = clientArea->right - clientArea->left,
nErrors = 0, e;
- PSTR pFirstChar, pLastChar;
+ const char *pFirstChar, *pLastChar;
SIZE size;
TEXTMETRICA tm;
struct err
{
- char *start;
+ const char *start;
int len;
int GetTextExtentExPointWWidth;
} error[20];
while (*str != '\0' && *str++ != tm.tmBreakChar);
breakCount++;
SetTextJustification(hdc, 0, 0);
- GetTextExtentPoint32(hdc, pFirstChar, str - pFirstChar - 1, &size);
+ GetTextExtentPoint32A(hdc, pFirstChar, str - pFirstChar - 1, &size);
} while ((int) size.cx < areaWidth);
/* ignore trailing break chars */
if (*str == '\0' || breakCount <= 0) pLastChar = str;
SetTextJustification(hdc, 0, 0);
- GetTextExtentPoint32(hdc, pFirstChar, pLastChar - pFirstChar, &size);
+ GetTextExtentPoint32A(hdc, pFirstChar, pLastChar - pFirstChar, &size);
/* do not justify the last extent */
if (*str != '\0' && breakCount > 0)
{
SetTextJustification(hdc, areaWidth - size.cx, breakCount);
- GetTextExtentPoint32(hdc, pFirstChar, pLastChar - pFirstChar, &size);
+ GetTextExtentPoint32A(hdc, pFirstChar, pLastChar - pFirstChar, &size);
if (size.cx != areaWidth && nErrors < sizeof(error)/sizeof(error[0]) - 1)
{
error[nErrors].start = pFirstChar;
SIZE size, expect;
int i;
WORD indices[2];
- static char testText[] =
+ static const char testText[] =
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut "
"enim ad minim veniam, quis nostrud exercitation ullamco laboris "
GetClientRect( hwnd, &clientArea );
hdc = GetDC( hwnd );
+ if (!is_font_installed("Times New Roman"))
+ {
+ skip("Times New Roman is not installed\n");
+ return;
+ }
+
memset(&lf, 0, sizeof lf);
lf.lfCharSet = ANSI_CHARSET;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
pGetGlyphIndicesA( hdc, "A ", 2, indices, 0 );
SetTextJustification(hdc, 0, 0);
- GetTextExtentPoint32(hdc, " ", 1, &expect);
- GetTextExtentPoint32(hdc, " ", 3, &size);
+ GetTextExtentPoint32A(hdc, " ", 1, &expect);
+ GetTextExtentPoint32A(hdc, " ", 3, &size);
ok( size.cx == 3 * expect.cx, "wrong size %d/%d\n", size.cx, expect.cx );
SetTextJustification(hdc, 4, 1);
- GetTextExtentPoint32(hdc, " ", 1, &size);
+ GetTextExtentPoint32A(hdc, " ", 1, &size);
ok( size.cx == expect.cx + 4, "wrong size %d/%d\n", size.cx, expect.cx );
SetTextJustification(hdc, 9, 2);
- GetTextExtentPoint32(hdc, " ", 2, &size);
+ GetTextExtentPoint32A(hdc, " ", 2, &size);
ok( size.cx == 2 * expect.cx + 9, "wrong size %d/%d\n", size.cx, expect.cx );
SetTextJustification(hdc, 7, 3);
- GetTextExtentPoint32(hdc, " ", 3, &size);
+ GetTextExtentPoint32A(hdc, " ", 3, &size);
ok( size.cx == 3 * expect.cx + 7, "wrong size %d/%d\n", size.cx, expect.cx );
SetTextJustification(hdc, 7, 3);
SetTextCharacterExtra(hdc, 2 );
- GetTextExtentPoint32(hdc, " ", 3, &size);
+ GetTextExtentPoint32A(hdc, " ", 3, &size);
ok( size.cx == 3 * (expect.cx + 2) + 7, "wrong size %d/%d\n", size.cx, expect.cx );
SetTextJustification(hdc, 0, 0);
SetTextCharacterExtra(hdc, 0);
size.cx = size.cy = 1234;
- GetTextExtentPoint32(hdc, " ", 0, &size);
+ GetTextExtentPoint32A(hdc, " ", 0, &size);
ok( size.cx == 0 && size.cy == 0, "wrong size %d,%d\n", size.cx, size.cy );
pGetTextExtentExPointI(hdc, indices, 2, -1, NULL, NULL, &expect);
SetTextJustification(hdc, 5, 1);
DPtoLP( hdc, (POINT *)&clientArea, 2 );
testJustification(hdc, testText, &clientArea);
- GetTextExtentPoint32(hdc, "A", 1, &expect);
+ GetTextExtentPoint32A(hdc, "A", 1, &expect);
for (i = 0; i < 10; i++)
{
SetTextCharacterExtra(hdc, i);
- GetTextExtentPoint32(hdc, "A", 1, &size);
+ GetTextExtentPoint32A(hdc, "A", 1, &size);
ok( size.cx == expect.cx + i, "wrong size %d/%d+%d\n", size.cx, expect.cx, i );
}
SetTextCharacterExtra(hdc, 0);
DPtoLP( hdc, (POINT *)&clientArea, 2 );
testJustification(hdc, testText, &clientArea);
- GetTextExtentPoint32(hdc, "A", 1, &expect);
+ GetTextExtentPoint32A(hdc, "A", 1, &expect);
for (i = 0; i < 10; i++)
{
SetTextCharacterExtra(hdc, i);
- GetTextExtentPoint32(hdc, "A", 1, &size);
+ GetTextExtentPoint32A(hdc, "A", 1, &size);
ok( size.cx == expect.cx + i, "wrong size %d/%d+%d\n", size.cx, expect.cx, i );
}
{ 950, "PMingLiU", ANSI_CHARSET, 950},
};
HDC hdc;
- LOGFONT lf;
+ LOGFONTA lf;
HFONT hfont;
UINT charset, acp;
DWORD codepage;
struct enum_font_data
{
int total;
- LOGFONT lf[MAX_ENUM_FONTS];
+ LOGFONTA lf[MAX_ENUM_FONTS];
};
struct enum_fullname_data
{
int total;
- ENUMLOGFONT elf[MAX_ENUM_FONTS];
+ ENUMLOGFONTA elf[MAX_ENUM_FONTS];
};
struct enum_font_dataW
LOGFONTW lf[MAX_ENUM_FONTS];
};
-static INT CALLBACK arial_enum_proc(const LOGFONT *lf, const TEXTMETRIC *tm, DWORD type, LPARAM lParam)
+static INT CALLBACK arial_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
{
struct enum_font_data *efd = (struct enum_font_data *)lParam;
- const NEWTEXTMETRIC *ntm = (const NEWTEXTMETRIC *)tm;
+ const NEWTEXTMETRICA *ntm = (const NEWTEXTMETRICA *)tm;
ok(lf->lfHeight == tm->tmHeight, "lfHeight %d != tmHeight %d\n", lf->lfHeight, tm->tmHeight);
ok(lf->lfHeight > 0 && lf->lfHeight < 200, "enumerated font height %d\n", lf->lfHeight);
{
struct enum_font_data efd;
struct enum_font_dataW efdw;
- LOGFONT lf;
+ LOGFONTA lf;
HDC hdc;
int i, ret, ansi_charset, symbol_charset, russian_charset;
efd.total = 0;
SetLastError(0xdeadbeef);
- ret = EnumFontFamilies(hdc, font_name, arial_enum_proc, (LPARAM)&efd);
+ ret = EnumFontFamiliesA(hdc, font_name, arial_enum_proc, (LPARAM)&efd);
ok(ret, "EnumFontFamilies error %u\n", GetLastError());
get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
trace("enumerated ansi %d, symbol %d, russian %d fonts for %s\n",
}
else
ok(efd.lf[i].lfCharSet == font_charset, "%d: got charset %d\n", i, efd.lf[i].lfCharSet);
- ok(!lstrcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
+ ok(!strcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
font_name, efd.lf[i].lfFaceName);
}
memset(&lf, 0, sizeof(lf));
lf.lfCharSet = ANSI_CHARSET;
- lstrcpy(lf.lfFaceName, font_name);
+ strcpy(lf.lfFaceName, font_name);
efd.total = 0;
SetLastError(0xdeadbeef);
- ret = EnumFontFamiliesEx(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
+ ret = EnumFontFamiliesExA(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
ok(ret, "EnumFontFamiliesEx error %u\n", GetLastError());
get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
trace("enumerated ansi %d, symbol %d, russian %d fonts for %s ANSI_CHARSET\n",
{
ok(efd.lf[i].lfCharSet == ANSI_CHARSET, "%d: got charset %d\n", i, efd.lf[i].lfCharSet);
if (*font_name)
- ok(!lstrcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
+ ok(!strcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
font_name, efd.lf[i].lfFaceName);
}
}
/* DEFAULT_CHARSET should enumerate all available charsets */
memset(&lf, 0, sizeof(lf));
lf.lfCharSet = DEFAULT_CHARSET;
- lstrcpy(lf.lfFaceName, font_name);
+ strcpy(lf.lfFaceName, font_name);
efd.total = 0;
SetLastError(0xdeadbeef);
- EnumFontFamiliesEx(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
+ EnumFontFamiliesExA(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
ok(ret, "EnumFontFamiliesEx error %u\n", GetLastError());
get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
trace("enumerated ansi %d, symbol %d, russian %d fonts for %s DEFAULT_CHARSET\n",
for (i = 0; i < efd.total; i++)
{
if (*font_name)
- ok(!lstrcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
+ ok(!strcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
font_name, efd.lf[i].lfFaceName);
}
if (*font_name)
memset(&lf, 0, sizeof(lf));
lf.lfCharSet = SYMBOL_CHARSET;
- lstrcpy(lf.lfFaceName, font_name);
+ strcpy(lf.lfFaceName, font_name);
efd.total = 0;
SetLastError(0xdeadbeef);
- EnumFontFamiliesEx(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
+ EnumFontFamiliesExA(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
ok(ret, "EnumFontFamiliesEx error %u\n", GetLastError());
get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
trace("enumerated ansi %d, symbol %d, russian %d fonts for %s SYMBOL_CHARSET\n",
{
ok(efd.lf[i].lfCharSet == SYMBOL_CHARSET, "%d: got charset %d\n", i, efd.lf[i].lfCharSet);
if (*font_name)
- ok(!lstrcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
+ ok(!strcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
font_name, efd.lf[i].lfFaceName);
}
ReleaseDC(0, hdc);
}
-static INT CALLBACK enum_font_data_proc(const LOGFONT *lf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK enum_multi_charset_font_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
+{
+ const NEWTEXTMETRICEXA *ntm = (const NEWTEXTMETRICEXA *)tm;
+ LOGFONTA *target = (LOGFONTA *)lParam;
+ const DWORD valid_bits = 0x003f01ff;
+ CHARSETINFO csi;
+ DWORD fs;
+
+ if (type != TRUETYPE_FONTTYPE) return TRUE;
+
+ if (TranslateCharsetInfo(ULongToPtr(target->lfCharSet), &csi, TCI_SRCCHARSET)) {
+ fs = ntm->ntmFontSig.fsCsb[0] & valid_bits;
+ if ((fs & csi.fs.fsCsb[0]) && (fs & ~csi.fs.fsCsb[0]) && (fs & FS_LATIN1)) {
+ *target = *lf;
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+static INT CALLBACK enum_font_data_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
{
struct enum_font_data *efd = (struct enum_font_data *)lParam;
return 1;
}
-static INT CALLBACK enum_fullname_data_proc(const LOGFONT *lf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK enum_fullname_data_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
{
struct enum_fullname_data *efnd = (struct enum_fullname_data *)lParam;
if (type != TRUETYPE_FONTTYPE) return 1;
if (efnd->total < MAX_ENUM_FONTS)
- efnd->elf[efnd->total++] = *(ENUMLOGFONT*)lf;
+ efnd->elf[efnd->total++] = *(ENUMLOGFONTA *)lf;
else
trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS);
static void test_EnumFontFamiliesEx_default_charset(void)
{
struct enum_font_data efd;
- LOGFONT gui_font, enum_font;
- DWORD ret;
+ LOGFONTA target, enum_font;
+ UINT acp;
HDC hdc;
+ CHARSETINFO csi;
+
+ acp = GetACP();
+ if (!TranslateCharsetInfo(ULongToPtr(acp), &csi, TCI_SRCCODEPAGE)) {
+ skip("TranslateCharsetInfo failed for code page %u.\n", acp);
+ return;
+ }
- ret = GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(gui_font), &gui_font);
- ok(ret, "GetObject failed.\n");
- if (!ret)
+ hdc = GetDC(0);
+ memset(&enum_font, 0, sizeof(enum_font));
+ enum_font.lfCharSet = csi.ciCharset;
+ target.lfFaceName[0] = '\0';
+ target.lfCharSet = csi.ciCharset;
+ EnumFontFamiliesExA(hdc, &enum_font, enum_multi_charset_font_proc, (LPARAM)&target, 0);
+ if (target.lfFaceName[0] == '\0') {
+ skip("suitable font isn't found for charset %d.\n", enum_font.lfCharSet);
return;
+ }
+ if (acp == 874 || acp == 1255 || acp == 1256) {
+ /* these codepage use complex script, expecting ANSI_CHARSET here. */
+ target.lfCharSet = ANSI_CHARSET;
+ }
efd.total = 0;
-
- hdc = GetDC(0);
memset(&enum_font, 0, sizeof(enum_font));
- lstrcpy(enum_font.lfFaceName, gui_font.lfFaceName);
+ strcpy(enum_font.lfFaceName, target.lfFaceName);
enum_font.lfCharSet = DEFAULT_CHARSET;
- EnumFontFamiliesEx(hdc, &enum_font, enum_font_data_proc, (LPARAM)&efd, 0);
+ EnumFontFamiliesExA(hdc, &enum_font, enum_font_data_proc, (LPARAM)&efd, 0);
ReleaseDC(0, hdc);
- if (efd.total == 0) {
- skip("'%s' is not found or not a TrueType font.\n", gui_font.lfFaceName);
+ trace("'%s' has %d charsets.\n", target.lfFaceName, efd.total);
+ if (efd.total < 2) {
+ ok(0, "EnumFontFamilies is broken. Expected >= 2, got %d.\n", efd.total);
return;
}
- trace("'%s' has %d charsets.\n", gui_font.lfFaceName, efd.total);
- ok(efd.lf[0].lfCharSet == gui_font.lfCharSet || broken(system_lang_id == LANG_ARABIC),
+ ok(efd.lf[0].lfCharSet == target.lfCharSet,
"(%s) got charset %d expected %d\n",
- efd.lf[0].lfFaceName, efd.lf[0].lfCharSet, gui_font.lfCharSet);
+ efd.lf[0].lfFaceName, efd.lf[0].lfCharSet, target.lfCharSet);
return;
}
} TT_OS2_V2;
#include "poppack.h"
-#ifdef WORDS_BIGENDIAN
-#define GET_BE_WORD(x) (x)
-#define GET_BE_DWORD(x) (x)
-#else
-#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)));
-#endif
-
-#define MS_MAKE_TAG(ch0, ch1, ch2, ch3) \
- ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
- ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
-#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')
-
typedef struct
{
USHORT version;
return r;
}
-static void test_text_metrics(const LOGFONT *lf, const NEWTEXTMETRIC *ntm)
+static void test_text_metrics(const LOGFONTA *lf, const NEWTEXTMETRICA *ntm)
{
HDC hdc;
HFONT hfont, hfont_old;
ret = GetFontData(hdc, MS_OS2_TAG, 0, &tt_os2, size);
ok(ret == size, "GetFontData should return %u not %u\n", size, ret);
- ascent = GET_BE_WORD(tt_os2.usWinAscent);
- descent = GET_BE_WORD(tt_os2.usWinDescent);
- cell_height = ascent + descent;
- ok(ntm->ntmCellHeight == cell_height, "%s: ntmCellHeight %u != %u, os2.usWinAscent/os2.usWinDescent %u/%u\n",
- font_name, ntm->ntmCellHeight, cell_height, ascent, descent);
-
SetLastError(0xdeadbeef);
ret = GetTextMetricsA(hdc, &tmA);
ok(ret, "GetTextMetricsA error %u\n", GetLastError());
if(!get_first_last_from_cmap(hdc, &cmap_first, &cmap_last, &cmap_type))
{
- skip("Unable to retrieve first and last glyphs from cmap\n");
+ skip("%s is not a Windows font, OS/2 metrics may be invalid.\n",font_name);
}
else
{
USHORT version;
TEXTMETRICW tmW;
+ ascent = GET_BE_WORD(tt_os2.usWinAscent);
+ descent = GET_BE_WORD(tt_os2.usWinDescent);
+ cell_height = ascent + descent;
+ ok(ntm->ntmCellHeight == cell_height, "%s: ntmCellHeight %u != %u, os2.usWinAscent/os2.usWinDescent %u/%u\n",
+ font_name, ntm->ntmCellHeight, cell_height, ascent, descent);
+
version = GET_BE_WORD(tt_os2.version);
os2_first_char = GET_BE_WORD(tt_os2.usFirstCharIndex);
ReleaseDC(0, hdc);
}
-static INT CALLBACK enum_truetype_font_proc(const LOGFONT *lf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK enum_truetype_font_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
{
INT *enumed = (INT *)lParam;
if (type == TRUETYPE_FONTTYPE)
{
(*enumed)++;
- test_text_metrics(lf, (const NEWTEXTMETRIC *)ntm);
+ test_text_metrics(lf, (const NEWTEXTMETRICA *)ntm);
}
return 1;
}
DeleteDC(hdc);
}
-static int CALLBACK create_fixed_pitch_font_proc(const LOGFONT *lpelfe,
- const TEXTMETRIC *lpntme,
+static int CALLBACK create_fixed_pitch_font_proc(const LOGFONTA *lpelfe,
+ const TEXTMETRICA *lpntme,
DWORD FontType, LPARAM lParam)
{
- const NEWTEXTMETRICEX *lpntmex = (const NEWTEXTMETRICEX *)lpntme;
+ const NEWTEXTMETRICEXA *lpntmex = (const NEWTEXTMETRICEXA *)lpntme;
CHARSETINFO csi;
- LOGFONT lf = *lpelfe;
+ LOGFONTA lf = *lpelfe;
HFONT hfont;
+ DWORD found_subset;
/* skip bitmap, proportional or vertical font */
if ((FontType & TRUETYPE_FONTTYPE) == 0 ||
(lpntmex->ntmFontSig.fsCsb[0] & csi.fs.fsCsb[0]) == 0)
return 1;
+ /* skip linked font, like SimSun-ExtB */
+ switch (lpelfe->lfCharSet) {
+ case SHIFTJIS_CHARSET:
+ found_subset = lpntmex->ntmFontSig.fsUsb[1] & (1 << 17); /* Hiragana */
+ break;
+ case GB2312_CHARSET:
+ case CHINESEBIG5_CHARSET:
+ found_subset = lpntmex->ntmFontSig.fsUsb[1] & (1 << 16); /* CJK Symbols And Punctuation */
+ break;
+ case HANGEUL_CHARSET:
+ found_subset = lpntmex->ntmFontSig.fsUsb[1] & (1 << 24); /* Hangul Syllables */
+ break;
+ default:
+ found_subset = lpntmex->ntmFontSig.fsUsb[0] & (1 << 0); /* Basic Latin */
+ break;
+ }
+ if (!found_subset)
+ return 1;
+
/* test with an odd height */
lf.lfHeight = -19;
lf.lfWidth = 0;
- hfont = CreateFontIndirect(&lf);
+ hfont = CreateFontIndirectA(&lf);
if (hfont)
{
*(HFONT *)lParam = hfont;
LOGFONTA lf;
HFONT hfont, old_hfont;
INT ret, ret2;
+ const UINT fmt[] = { GGO_METRICS, GGO_BITMAP, GGO_GRAY2_BITMAP,
+ GGO_GRAY4_BITMAP, GGO_GRAY8_BITMAP };
static const struct
{
UINT cs;
{ANSI_CHARSET, 0x30, 0x30},
{SHIFTJIS_CHARSET, 0x82a0, 0x3042},
{HANGEUL_CHARSET, 0x8141, 0xac02},
- {JOHAB_CHARSET, 0x8446, 0x3135},
{GB2312_CHARSET, 0x8141, 0x4e04},
{CHINESEBIG5_CHARSET, 0xa142, 0x3001}
};
ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
}
+ for (i = 0; i < sizeof(fmt) / sizeof(fmt[0]); ++i)
+ {
+ DWORD dummy;
+
+ memset(&gm, 0xab, sizeof(gm));
+ SetLastError(0xdeadbeef);
+ ret = GetGlyphOutlineW(hdc, ' ', fmt[i], &gm, 0, NULL, &mat);
+ if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ {
+ if (fmt[i] == GGO_METRICS)
+ ok(ret != GDI_ERROR, "%2d:GetGlyphOutlineW should succeed, got %d\n", fmt[i], ret);
+ else
+ ok(ret == 0, "%2d:GetGlyphOutlineW should return 0, got %d\n", fmt[i], ret);
+ ok(gm.gmBlackBoxX == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxX);
+ ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
+ }
+
+ memset(&gm, 0xab, sizeof(gm));
+ SetLastError(0xdeadbeef);
+ ret = GetGlyphOutlineW(hdc, ' ', fmt[i], &gm, 0, &dummy, &mat);
+ if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ {
+ if (fmt[i] == GGO_METRICS)
+ ok(ret != GDI_ERROR, "%2d:GetGlyphOutlineW should succeed, got %d\n", fmt[i], ret);
+ else
+ ok(ret == 0, "%2d:GetGlyphOutlineW should return 0, got %d\n", fmt[i], ret);
+ ok(gm.gmBlackBoxX == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxX);
+ ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
+ }
+
+ memset(&gm, 0xab, sizeof(gm));
+ SetLastError(0xdeadbeef);
+ ret = GetGlyphOutlineW(hdc, ' ', fmt[i], &gm, sizeof(dummy), NULL, &mat);
+ if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ {
+ if (fmt[i] == GGO_METRICS)
+ ok(ret != GDI_ERROR, "%2d:GetGlyphOutlineW should succeed, got %d\n", fmt[i], ret);
+ else
+ ok(ret == 0, "%2d:GetGlyphOutlineW should return 0, got %d\n", fmt[i], ret);
+ ok(gm.gmBlackBoxX == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxX);
+ ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
+ }
+
+ memset(&gm, 0xab, sizeof(gm));
+ SetLastError(0xdeadbeef);
+ ret = GetGlyphOutlineW(hdc, ' ', fmt[i], &gm, sizeof(dummy), &dummy, &mat);
+ if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+ {
+ if (fmt[i] == GGO_METRICS) {
+ ok(ret != GDI_ERROR, "%2d:GetGlyphOutlineW should succeed, got %d\n", fmt[i], ret);
+ ok(gm.gmBlackBoxX == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxX);
+ ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
+ }
+ else
+ {
+ ok(ret == GDI_ERROR, "%2d:GetGlyphOutlineW should return GDI_ERROR, got %d\n", fmt[i], ret);
+ memset(&gm2, 0xab, sizeof(gm2));
+ ok(memcmp(&gm, &gm2, sizeof(GLYPHMETRICS)) == 0,
+ "%2d:GLYPHMETRICS shouldn't be touched on error\n", fmt[i]);
+ }
+ }
+ }
+
SelectObject(hdc, old_hfont);
DeleteObject(hfont);
for (i = 0; i < sizeof c / sizeof c[0]; ++i)
{
static const MAT2 rotate_mat = {{0, 0}, {0, -1}, {0, 1}, {0, 0}};
+ TEXTMETRICA tm;
lf.lfFaceName[0] = '\0';
lf.lfCharSet = c[i].cs;
lf.lfPitchAndFamily = 0;
- if (EnumFontFamiliesEx(hdc, &lf, create_font_proc, (LPARAM)&hfont, 0))
+ if (EnumFontFamiliesExA(hdc, &lf, create_font_proc, (LPARAM)&hfont, 0))
{
skip("TrueType font for charset %u is not installed\n", c[i].cs);
continue;
ret2 = GetGlyphOutlineW(hdc, c[i].w, GGO_BITMAP, &gm2, 0, NULL, &mat);
ok(ret == ret2 && memcmp(&gm, &gm2, sizeof gm) == 0, "%d %d\n", ret, ret2);
- if (EnumFontFamiliesEx(hdc, &lf, create_fixed_pitch_font_proc, (LPARAM)&hfont, 0))
+ if (EnumFontFamiliesExA(hdc, &lf, create_fixed_pitch_font_proc, (LPARAM)&hfont, 0))
{
skip("Fixed-pitch TrueType font for charset %u is not available\n", c[i].cs);
continue;
continue;
}
- ret = GetObject(hfont, sizeof lf, &lf);
+ ret = GetObjectA(hfont, sizeof lf, &lf);
ok(ret > 0, "GetObject error %u\n", GetLastError());
- ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
- ok(ret != GDI_ERROR, "GetGlyphOutlineA error %u\n", GetLastError());
+ ret = GetTextMetricsA(hdc, &tm);
+ ok(ret, "GetTextMetrics error %u\n", GetLastError());
ret = GetGlyphOutlineA(hdc, c[i].a, GGO_METRICS, &gm2, 0, NULL, &mat);
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %u\n", GetLastError());
- trace("Tests with height=%d,half=%d,full=%d,face=%s,charset=%d\n",
- -lf.lfHeight, gm.gmCellIncX, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
- ok(gm2.gmCellIncX == gm.gmCellIncX * 2 || broken(gm2.gmCellIncX == -lf.lfHeight),
+ trace("Tests with height=%d,avg=%d,full=%d,face=%s,charset=%d\n",
+ -lf.lfHeight, tm.tmAveCharWidth, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
+ ok(gm2.gmCellIncX == tm.tmAveCharWidth * 2 || broken(gm2.gmCellIncX == -lf.lfHeight),
"expected %d, got %d (%s:%d)\n",
- gm.gmCellIncX * 2, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
+ tm.tmAveCharWidth * 2, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
ret = GetGlyphOutlineA(hdc, c[i].a, GGO_METRICS, &gm2, 0, NULL, &rotate_mat);
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %u\n", GetLastError());
-lf.lfHeight, gm2.gmCellIncY, lf.lfFaceName, lf.lfCharSet);
lf.lfItalic = TRUE;
- hfont = CreateFontIndirect(&lf);
+ hfont = CreateFontIndirectA(&lf);
ok(hfont != NULL, "CreateFontIndirect error %u\n", GetLastError());
DeleteObject(SelectObject(hdc, hfont));
- ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
- ok(ret != GDI_ERROR, "GetGlyphOutlineA error %u\n", GetLastError());
+ ret = GetTextMetricsA(hdc, &tm);
+ ok(ret, "GetTextMetrics error %u\n", GetLastError());
ret = GetGlyphOutlineA(hdc, c[i].a, GGO_METRICS, &gm2, 0, NULL, &mat);
ok(ret != GDI_ERROR, "GetGlyphOutlineA error %u\n", GetLastError());
- ok(gm2.gmCellIncX == gm.gmCellIncX * 2 || broken(gm2.gmCellIncX == -lf.lfHeight),
+ ok(gm2.gmCellIncX == tm.tmAveCharWidth * 2 || broken(gm2.gmCellIncX == -lf.lfHeight),
"expected %d, got %d (%s:%d)\n",
- gm.gmCellIncX * 2, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
+ tm.tmAveCharWidth * 2, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
lf.lfItalic = FALSE;
lf.lfEscapement = lf.lfOrientation = 2700;
- hfont = CreateFontIndirect(&lf);
+ hfont = CreateFontIndirectA(&lf);
ok(hfont != NULL, "CreateFontIndirect error %u\n", GetLastError());
DeleteObject(SelectObject(hdc, hfont));
ret = GetGlyphOutlineA(hdc, c[i].a, GGO_METRICS, &gm2, 0, NULL, &mat);
for (width = ave_width * 2; /* nothing*/; width += ave_width)
{
- hf = CreateFont(height, width, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
+ hf = CreateFontA(height, width, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
DEFAULT_CHARSET, OUT_TT_PRECIS, CLIP_LH_ANGLES,
DEFAULT_QUALITY, VARIABLE_PITCH, fontname);
ok(hf != 0, "CreateFont failed\n");
of = SelectObject(hdc, hf);
- ret = GetTextMetrics(hdc, &tm);
+ ret = GetTextMetricsA(hdc, &tm);
ok(ret, "GetTextMetrics error %u\n", GetLastError());
SelectObject(hdc, of);
DeleteObject(hf);
- if (match_off_by_1(tm.tmAveCharWidth, ave_width) || width / height > 200)
+ if (match_off_by_1(tm.tmAveCharWidth, ave_width, FALSE) || width / height > 200)
break;
}
hfont = CreateFontIndirectA(&lf);
ok(hfont != 0, "CreateFontIndirectA failed\n");
SetLastError(0xdeadbeef);
- ret = GetObject(hfont, sizeof(getobj_lf), &getobj_lf);
+ ret = GetObjectA(hfont, sizeof(getobj_lf), &getobj_lf);
ok(ret, "GetObject failed: %d\n", GetLastError());
ok(lf.lfItalic == getobj_lf.lfItalic, "lfItalic: expect %02x got %02x\n", lf.lfItalic, getobj_lf.lfItalic);
ok(lf.lfWeight == getobj_lf.lfWeight ||
HANDLE file, mapping;
void *font;
- if (!GetWindowsDirectory(file_name, sizeof(file_name))) return NULL;
+ if (!GetWindowsDirectoryA(file_name, sizeof(file_name))) return NULL;
strcat(file_name, "\\fonts\\");
strcat(file_name, font_name);
- file = CreateFile(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
+ file = CreateFileA(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
if (file == INVALID_HANDLE_VALUE) return NULL;
*font_size = GetFileSize(file, NULL);
- mapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
+ mapping = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL);
if (!mapping)
{
CloseHandle(file);
free_font(font);
}
-static INT CALLBACK enum_fonts_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lparam)
+static INT CALLBACK enum_fonts_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
{
- LOGFONT *lf;
+ LOGFONTA *lf;
if (type != TRUETYPE_FONTTYPE) return 1;
ok(ntm->tmWeight == elf->lfWeight, "expected %d got %d\n", ntm->tmWeight, elf->lfWeight);
- lf = (LOGFONT *)lparam;
+ lf = (LOGFONTA *)lparam;
*lf = *elf;
return 0;
}
-static INT CALLBACK enum_all_fonts_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lparam)
+static INT CALLBACK enum_all_fonts_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
{
int ret;
- LOGFONT *lf;
+ LOGFONTA *lf;
if (type != TRUETYPE_FONTTYPE) return 1;
- lf = (LOGFONT *)lparam;
+ lf = (LOGFONTA *)lparam;
ret = strcmp(lf->lfFaceName, elf->lfFaceName);
if(ret == 0)
{
return 1;
}
-static INT CALLBACK enum_with_magic_retval_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lparam)
+static INT CALLBACK enum_with_magic_retval_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
{
return lparam;
}
static void test_EnumFonts(void)
{
int ret;
- LOGFONT lf;
+ LOGFONTA lf;
HDC hdc;
if (!is_truetype_font_installed("Arial"))
hdc = CreateCompatibleDC(0);
/* check that the enumproc's retval is returned */
- ret = EnumFontFamilies(hdc, NULL, enum_with_magic_retval_proc, 0xcafe);
+ ret = EnumFontFamiliesA(hdc, NULL, enum_with_magic_retval_proc, 0xcafe);
ok(ret == 0xcafe, "got %08x\n", ret);
- ret = EnumFontFamilies(hdc, "Arial", enum_fonts_proc, (LPARAM)&lf);
+ ret = EnumFontFamiliesA(hdc, "Arial", enum_fonts_proc, (LPARAM)&lf);
ok(!ret, "font Arial is not enumerated\n");
ret = strcmp(lf.lfFaceName, "Arial");
ok(!ret, "expected Arial got %s\n", lf.lfFaceName);
ok(lf.lfWeight == FW_NORMAL, "expected FW_NORMAL got %d\n", lf.lfWeight);
- lstrcpy(lf.lfFaceName, "Arial");
- ret = EnumFontFamilies(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
+ strcpy(lf.lfFaceName, "Arial");
+ ret = EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
ok(!ret, "font Arial is not enumerated\n");
ret = strcmp(lf.lfFaceName, "Arial");
ok(!ret, "expected Arial got %s\n", lf.lfFaceName);
ok(lf.lfWeight == FW_NORMAL, "expected FW_NORMAL got %d\n", lf.lfWeight);
- ret = EnumFontFamilies(hdc, "Arial Bold", enum_fonts_proc, (LPARAM)&lf);
+ ret = EnumFontFamiliesA(hdc, "Arial Bold", enum_fonts_proc, (LPARAM)&lf);
ok(!ret, "font Arial Bold is not enumerated\n");
ret = strcmp(lf.lfFaceName, "Arial");
ok(!ret, "expected Arial got %s\n", lf.lfFaceName);
ok(lf.lfWeight == FW_BOLD, "expected FW_BOLD got %d\n", lf.lfWeight);
- lstrcpy(lf.lfFaceName, "Arial Bold");
- ret = EnumFontFamilies(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
+ strcpy(lf.lfFaceName, "Arial Bold");
+ ret = EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
ok(ret, "font Arial Bold should not be enumerated\n");
- ret = EnumFontFamilies(hdc, "Arial Bold Italic", enum_fonts_proc, (LPARAM)&lf);
+ ret = EnumFontFamiliesA(hdc, "Arial Bold Italic", enum_fonts_proc, (LPARAM)&lf);
ok(!ret, "font Arial Bold Italic is not enumerated\n");
ret = strcmp(lf.lfFaceName, "Arial");
ok(!ret, "expected Arial got %s\n", lf.lfFaceName);
ok(lf.lfWeight == FW_BOLD, "expected FW_BOLD got %d\n", lf.lfWeight);
- lstrcpy(lf.lfFaceName, "Arial Bold Italic");
- ret = EnumFontFamilies(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
+ strcpy(lf.lfFaceName, "Arial Bold Italic");
+ ret = EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
ok(ret, "font Arial Bold Italic should not be enumerated\n");
- ret = EnumFontFamilies(hdc, "Arial Italic Bold", enum_fonts_proc, (LPARAM)&lf);
+ ret = EnumFontFamiliesA(hdc, "Arial Italic Bold", enum_fonts_proc, (LPARAM)&lf);
ok(ret, "font Arial Italic Bold should not be enumerated\n");
- lstrcpy(lf.lfFaceName, "Arial Italic Bold");
- ret = EnumFontFamilies(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
+ strcpy(lf.lfFaceName, "Arial Italic Bold");
+ ret = EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
ok(ret, "font Arial Italic Bold should not be enumerated\n");
DeleteDC(hdc);
}
-static INT CALLBACK is_font_installed_fullname_proc(const LOGFONT *lf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK is_font_installed_fullname_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
{
- const ENUMLOGFONT *elf = (const ENUMLOGFONT *)lf;
+ const ENUMLOGFONTA *elf = (const ENUMLOGFONTA *)lf;
const char *fullname = (const char *)lParam;
if (!strcmp((const char *)elf->elfFullName, fullname)) return 0;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfItalic = FALSE;
lf.lfWeight = FW_DONTCARE;
- lstrcpy(lf.lfFaceName, Family);
+ strcpy(lf.lfFaceName, Family);
efnd.total = 0;
EnumFontFamiliesExA(hdc, &lf, enum_fullname_data_proc, (LPARAM)&efnd, 0);
if (efnd.total == 0)
otm_size = GetOutlineTextMetricsA(hdc, 0, NULL);
otm = HeapAlloc(GetProcessHeap(), 0, otm_size);
memset(otm, 0, otm_size);
- ret = GetOutlineTextMetrics(hdc, otm_size, otm);
+ ret = GetOutlineTextMetricsA(hdc, otm_size, otm);
ok(ret != 0, "GetOutlineTextMetrics fails!\n");
if (ret == 0) continue;
}
-static BOOL write_ttf_file(const char *fontname, char *tmp_name)
-{
- char tmp_path[MAX_PATH];
- HRSRC rsrc;
- void *rsrc_data;
- DWORD rsrc_size;
- HANDLE hfile;
- BOOL ret;
-
- SetLastError(0xdeadbeef);
- rsrc = FindResource(GetModuleHandle(0), fontname, RT_RCDATA);
- ok(rsrc != 0, "FindResource error %d\n", GetLastError());
- if (!rsrc) return FALSE;
- SetLastError(0xdeadbeef);
- rsrc_data = LockResource(LoadResource(GetModuleHandle(0), rsrc));
- ok(rsrc_data != 0, "LockResource error %d\n", GetLastError());
- if (!rsrc_data) return FALSE;
- SetLastError(0xdeadbeef);
- rsrc_size = SizeofResource(GetModuleHandle(0), rsrc);
- ok(rsrc_size != 0, "SizeofResource error %d\n", GetLastError());
- if (!rsrc_size) return FALSE;
-
- SetLastError(0xdeadbeef);
- ret = GetTempPath(MAX_PATH, tmp_path);
- ok(ret, "GetTempPath() error %d\n", GetLastError());
- SetLastError(0xdeadbeef);
- ret = GetTempFileName(tmp_path, "ttf", 0, tmp_name);
- ok(ret, "GetTempFileName() error %d\n", GetLastError());
-
- SetLastError(0xdeadbeef);
- hfile = CreateFile(tmp_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
- ok(hfile != INVALID_HANDLE_VALUE, "CreateFile() error %d\n", GetLastError());
- if (hfile == INVALID_HANDLE_VALUE) return FALSE;
-
- SetLastError(0xdeadbeef);
- ret = WriteFile(hfile, rsrc_data, rsrc_size, &rsrc_size, NULL);
- ok(ret, "WriteFile() error %d\n", GetLastError());
-
- CloseHandle(hfile);
- return ret;
-}
-
static void test_GetGlyphOutline_empty_contour(void)
{
HDC hdc;
ReleaseDC(NULL, hdc);
}
+static void test_GetGlyphOutline_metric_clipping(void)
+{
+ HDC hdc;
+ LOGFONTA lf;
+ HFONT hfont, hfont_prev;
+ GLYPHMETRICS gm;
+ TEXTMETRICA tm;
+ DWORD ret;
+
+ memset(&lf, 0, sizeof(lf));
+ lf.lfHeight = 72;
+ lstrcpyA(lf.lfFaceName, "wine_test");
+
+ SetLastError(0xdeadbeef);
+ hfont = CreateFontIndirectA(&lf);
+ ok(hfont != 0, "CreateFontIndirectA error %u\n", GetLastError());
+
+ hdc = GetDC(NULL);
+
+ hfont_prev = SelectObject(hdc, hfont);
+ ok(hfont_prev != NULL, "SelectObject failed\n");
+
+ SetLastError(0xdeadbeef);
+ ret = GetTextMetricsA(hdc, &tm);
+ ok(ret, "GetTextMetrics error %u\n", GetLastError());
+
+ GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
+ ok(gm.gmptGlyphOrigin.y <= tm.tmAscent,
+ "Glyph top(%d) exceeds ascent(%d)\n",
+ gm.gmptGlyphOrigin.y, tm.tmAscent);
+ GetGlyphOutlineA(hdc, 'D', GGO_METRICS, &gm, 0, NULL, &mat);
+ ok(gm.gmptGlyphOrigin.y - gm.gmBlackBoxY >= -tm.tmDescent,
+ "Glyph bottom(%d) exceeds descent(%d)\n",
+ gm.gmptGlyphOrigin.y - gm.gmBlackBoxY, -tm.tmDescent);
+
+ SelectObject(hdc, hfont_prev);
+ DeleteObject(hfont);
+ ReleaseDC(NULL, hdc);
+}
+
static void test_CreateScalableFontResource(void)
{
char ttf_name[MAX_PATH];
ret = is_truetype_font_installed("wine_test");
ok(!ret, "font wine_test should not be enumerated\n");
- ret = GetTempPath(MAX_PATH, tmp_path);
+ ret = GetTempPathA(MAX_PATH, tmp_path);
ok(ret, "GetTempPath() error %d\n", GetLastError());
- ret = GetTempFileName(tmp_path, "fot", 0, fot_name);
+ ret = GetTempFileNameA(tmp_path, "fot", 0, fot_name);
ok(ret, "GetTempFileName() error %d\n", GetLastError());
- ret = GetFileAttributes(fot_name);
+ ret = GetFileAttributesA(fot_name);
ok(ret != INVALID_FILE_ATTRIBUTES, "file %s does not exist\n", fot_name);
SetLastError(0xdeadbeef);
- ret = CreateScalableFontResource(0, fot_name, ttf_name, NULL);
+ ret = CreateScalableFontResourceA(0, fot_name, ttf_name, NULL);
ok(!ret, "CreateScalableFontResource() should fail\n");
ok(GetLastError() == ERROR_FILE_EXISTS, "not expected error %d\n", GetLastError());
SetLastError(0xdeadbeef);
- ret = CreateScalableFontResource(0, fot_name, ttf_name, "");
+ ret = CreateScalableFontResourceA(0, fot_name, ttf_name, "");
ok(!ret, "CreateScalableFontResource() should fail\n");
ok(GetLastError() == ERROR_FILE_EXISTS, "not expected error %d\n", GetLastError());
file_part = strrchr(ttf_name, '\\');
SetLastError(0xdeadbeef);
- ret = CreateScalableFontResource(0, fot_name, file_part, tmp_path);
+ ret = CreateScalableFontResourceA(0, fot_name, file_part, tmp_path);
ok(!ret, "CreateScalableFontResource() should fail\n");
ok(GetLastError() == ERROR_FILE_EXISTS, "not expected error %d\n", GetLastError());
SetLastError(0xdeadbeef);
- ret = CreateScalableFontResource(0, fot_name, "random file name", tmp_path);
+ ret = CreateScalableFontResourceA(0, fot_name, "random file name", tmp_path);
ok(!ret, "CreateScalableFontResource() should fail\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "not expected error %d\n", GetLastError());
SetLastError(0xdeadbeef);
- ret = CreateScalableFontResource(0, fot_name, NULL, ttf_name);
+ ret = CreateScalableFontResourceA(0, fot_name, NULL, ttf_name);
ok(!ret, "CreateScalableFontResource() should fail\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "not expected error %d\n", GetLastError());
- ret = DeleteFile(fot_name);
+ ret = DeleteFileA(fot_name);
ok(ret, "DeleteFile() error %d\n", GetLastError());
ret = pRemoveFontResourceExA(fot_name, 0, 0);
/* test public font resource */
SetLastError(0xdeadbeef);
- ret = CreateScalableFontResource(0, fot_name, ttf_name, NULL);
+ ret = CreateScalableFontResourceA(0, fot_name, ttf_name, NULL);
ok(ret, "CreateScalableFontResource() error %d\n", GetLastError());
ret = is_truetype_font_installed("wine_test");
ok(ret, "font wine_test should be enumerated\n");
test_GetGlyphOutline_empty_contour();
+ test_GetGlyphOutline_metric_clipping();
ret = pRemoveFontResourceExA(fot_name, FR_PRIVATE, 0);
ok(!ret, "RemoveFontResourceEx() with not matching flags should fail\n");
ret = pRemoveFontResourceExA(fot_name, 0, 0);
ok(!ret, "RemoveFontResourceEx() should fail\n");
- DeleteFile(fot_name);
+ DeleteFileA(fot_name);
/* test hidden font resource */
SetLastError(0xdeadbeef);
- ret = CreateScalableFontResource(1, fot_name, ttf_name, NULL);
+ ret = CreateScalableFontResourceA(1, fot_name, ttf_name, NULL);
ok(ret, "CreateScalableFontResource() error %d\n", GetLastError());
ret = is_truetype_font_installed("wine_test");
ret = pRemoveFontResourceExA(fot_name, 0, 0);
ok(!ret, "RemoveFontResourceEx() should fail\n");
- DeleteFile(fot_name);
- DeleteFile(ttf_name);
+ DeleteFileA(fot_name);
+ DeleteFileA(ttf_name);
}
static void check_vertical_font(const char *name, BOOL *installed, BOOL *selected, GLYPHMETRICS *gm, WORD *gi)
ReleaseDC(NULL, hdc);
}
+static void check_vertical_metrics(const char *face)
+{
+ LOGFONTA lf;
+ HFONT hfont, hfont_prev;
+ HDC hdc;
+ DWORD ret;
+ GLYPHMETRICS rgm, vgm;
+ const UINT code = 0x5EAD, height = 1000;
+ WORD idx;
+ ABC abc;
+ OUTLINETEXTMETRICA otm;
+ USHORT numOfLongVerMetrics;
+
+ hdc = GetDC(NULL);
+
+ memset(&lf, 0, sizeof(lf));
+ strcpy(lf.lfFaceName, face);
+ lf.lfHeight = -height;
+ lf.lfCharSet = DEFAULT_CHARSET;
+ lf.lfEscapement = lf.lfOrientation = 900;
+ hfont = CreateFontIndirectA(&lf);
+ hfont_prev = SelectObject(hdc, hfont);
+ ret = GetGlyphOutlineW(hdc, code, GGO_METRICS, &rgm, 0, NULL, &mat);
+ ok(ret != GDI_ERROR, "GetGlyphOutlineW failed\n");
+ ret = GetCharABCWidthsW(hdc, code, code, &abc);
+ ok(ret, "GetCharABCWidthsW failed\n");
+ DeleteObject(SelectObject(hdc, hfont_prev));
+
+ memset(&lf, 0, sizeof(lf));
+ strcpy(lf.lfFaceName, "@");
+ strcat(lf.lfFaceName, face);
+ lf.lfHeight = -height;
+ lf.lfCharSet = DEFAULT_CHARSET;
+ hfont = CreateFontIndirectA(&lf);
+ hfont_prev = SelectObject(hdc, hfont);
+ ret = GetGlyphOutlineW(hdc, code, GGO_METRICS, &vgm, 0, NULL, &mat);
+ ok(ret != GDI_ERROR, "GetGlyphOutlineW failed\n");
+
+ memset(&otm, 0, sizeof(otm));
+ otm.otmSize = sizeof(otm);
+ ret = GetOutlineTextMetricsA(hdc, sizeof(otm), &otm);
+ ok(ret != 0, "GetOutlineTextMetricsA failed\n");
+
+ if (GetFontData(hdc, MS_MAKE_TAG('v','h','e','a'), sizeof(SHORT) * 17,
+ &numOfLongVerMetrics, sizeof(numOfLongVerMetrics)) != GDI_ERROR) {
+ int offset;
+ SHORT topSideBearing;
+
+ if (!pGetGlyphIndicesW) {
+ win_skip("GetGlyphIndices is not available on this platform\n");
+ }
+ else {
+ ret = pGetGlyphIndicesW(hdc, (LPCWSTR)&code, 1, &idx, 0);
+ ok(ret != 0, "GetGlyphIndicesW failed\n");
+ numOfLongVerMetrics = GET_BE_WORD(numOfLongVerMetrics);
+ if (numOfLongVerMetrics > idx)
+ offset = idx * 2 + 1;
+ else
+ offset = numOfLongVerMetrics * 2 + (idx - numOfLongVerMetrics);
+ ret = GetFontData(hdc, MS_MAKE_TAG('v','m','t','x'), offset * sizeof(SHORT),
+ &topSideBearing, sizeof(SHORT));
+ ok(ret != GDI_ERROR, "GetFontData(vmtx) failed\n");
+ topSideBearing = GET_BE_WORD(topSideBearing);
+ ok(match_off_by_1(vgm.gmptGlyphOrigin.x,
+ MulDiv(topSideBearing, height, otm.otmEMSquare), FALSE),
+ "expected %d, got %d\n",
+ MulDiv(topSideBearing, height, otm.otmEMSquare), vgm.gmptGlyphOrigin.x);
+ }
+ }
+ else
+ {
+ ok(vgm.gmptGlyphOrigin.x == rgm.gmptGlyphOrigin.x + vgm.gmCellIncX + otm.otmDescent,
+ "got %d, expected rgm.origin.x(%d) + vgm.cellIncX(%d) + descent(%d)\n",
+ vgm.gmptGlyphOrigin.x, rgm.gmptGlyphOrigin.x, vgm.gmCellIncX, otm.otmDescent);
+ }
+
+ ok(vgm.gmptGlyphOrigin.y == abc.abcA + abc.abcB + otm.otmDescent ||
+ broken(vgm.gmptGlyphOrigin.y == abc.abcA + abc.abcB - otm.otmTextMetrics.tmDescent) /* win2k */,
+ "got %d, expected abcA(%d) + abcB(%u) + descent(%d)\n",
+ (INT)vgm.gmptGlyphOrigin.y, abc.abcA, abc.abcB, otm.otmDescent);
+
+ DeleteObject(SelectObject(hdc, hfont_prev));
+ ReleaseDC(NULL, hdc);
+}
+
static void test_vertical_font(void)
{
char ttf_name[MAX_PATH];
- int num;
+ int num, i;
BOOL ret, installed, selected;
GLYPHMETRICS gm;
WORD hgi, vgi;
+ const char* face_list[] = {
+ "@WineTestVertical", /* has vmtx table */
+ "@Ume Gothic", /* doesn't have vmtx table */
+ "@MS UI Gothic", /* has vmtx table, available on native */
+ };
if (!pAddFontResourceExA || !pRemoveFontResourceExA || !pGetGlyphIndicesW)
{
num = pAddFontResourceExA(ttf_name, FR_PRIVATE, 0);
ok(num == 2, "AddFontResourceExA should add 2 fonts from vertical.ttf\n");
- check_vertical_font("@WineTestVertical", &installed, &selected, &gm, &hgi);
- ok(installed, "@WineTestVertical is not installed\n");
- ok(selected, "@WineTestVertical is not selected\n");
+ check_vertical_font("WineTestVertical", &installed, &selected, &gm, &hgi);
+ ok(installed, "WineTestVertical is not installed\n");
+ ok(selected, "WineTestVertical is not selected\n");
ok(gm.gmBlackBoxX > gm.gmBlackBoxY,
"gmBlackBoxX(%u) should be greater than gmBlackBoxY(%u) if horizontal\n",
gm.gmBlackBoxX, gm.gmBlackBoxY);
- check_vertical_font("@@WineTestVertical", &installed, &selected, &gm, &vgi);
- ok(installed, "@@WineTestVertical is not installed\n");
- ok(selected, "@@WineTestVertical is not selected\n");
- ok(gm.gmBlackBoxX < gm.gmBlackBoxY,
+ check_vertical_font("@WineTestVertical", &installed, &selected, &gm, &vgi);
+ ok(installed, "@WineTestVertical is not installed\n");
+ ok(selected, "@WineTestVertical is not selected\n");
+ ok(gm.gmBlackBoxX > gm.gmBlackBoxY,
"gmBlackBoxX(%u) should be less than gmBlackBoxY(%u) if vertical\n",
gm.gmBlackBoxX, gm.gmBlackBoxY);
- ok(hgi == vgi, "different glyph h:%u v:%u\n", hgi, vgi);
+ ok(hgi != vgi, "same glyph h:%u v:%u\n", hgi, vgi);
+
+ for (i = 0; i < sizeof(face_list)/sizeof(face_list[0]); i++) {
+ const char* face = face_list[i];
+ if (!is_truetype_font_installed(face)) {
+ skip("%s is not installed\n", face);
+ continue;
+ }
+ trace("Testing %s...\n", face);
+ check_vertical_metrics(&face[1]);
+ }
ret = pRemoveFontResourceExA(ttf_name, FR_PRIVATE, 0);
ok(ret, "RemoveFontResourceEx() error %d\n", GetLastError());
- DeleteFile(ttf_name);
+ DeleteFileA(ttf_name);
}
-static INT CALLBACK has_vertical_font_proc(const LOGFONT *lf, const TEXTMETRIC *ntm,
+static INT CALLBACK has_vertical_font_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm,
DWORD type, LPARAM lParam)
{
if (lf->lfFaceName[0] == '@') {
lf.lfFaceName[0] = '\0';
lf.lfCharSet = charset[i];
- if (EnumFontFamiliesEx(hdc, &lf, has_vertical_font_proc, 0, 0))
+ if (EnumFontFamiliesExA(hdc, &lf, has_vertical_font_proc, 0, 0))
{
skip("Vertical font for charset %u is not installed\n", charset[i]);
continue;
ReleaseDC(NULL, hdc);
}
-static int get_font_dpi(const LOGFONT *lf)
+static int get_font_dpi(const LOGFONTA *lf, int *height)
{
HDC hdc = CreateCompatibleDC(0);
HFONT hfont;
- TEXTMETRIC tm;
+ TEXTMETRICA tm;
int ret;
- hfont = CreateFontIndirect(lf);
+ hfont = CreateFontIndirectA(lf);
ok(hfont != 0, "CreateFontIndirect failed\n");
SelectObject(hdc, hfont);
- ret = GetTextMetrics(hdc, &tm);
+ ret = GetTextMetricsA(hdc, &tm);
ok(ret, "GetTextMetrics failed\n");
ret = tm.tmDigitizedAspectX;
+ if (height) *height = tm.tmHeight;
DeleteDC(hdc);
DeleteObject(hfont);
};
static const struct test_data
{
- int charset, weight, height, dpi;
+ int charset, weight, height, height_pixels, dpi;
const char face_name[LF_FACESIZE];
} td[][11] =
{
{ /* ANSI_FIXED_FONT */
- { DEFAULT_CHARSET, FW_NORMAL, 12, 96, "Courier" },
- { DEFAULT_CHARSET, FW_NORMAL, 12, 120, "Courier" },
+ { DEFAULT_CHARSET, FW_NORMAL, 12, 13, 96, "Courier" },
+ { DEFAULT_CHARSET, FW_NORMAL, 12, 13, 120, "Courier" },
{ 0 }
},
{ /* ANSI_VAR_FONT */
- { DEFAULT_CHARSET, FW_NORMAL, 12, 96, "MS Sans Serif" },
- { DEFAULT_CHARSET, FW_NORMAL, 12, 120, "MS Sans Serif" },
+ { DEFAULT_CHARSET, FW_NORMAL, 12, 13, 96, "MS Sans Serif" },
+ { DEFAULT_CHARSET, FW_NORMAL, 12, 13, 120, "MS Sans Serif" },
{ 0 }
},
{ /* SYSTEM_FONT */
- { SHIFTJIS_CHARSET, FW_NORMAL, 18, 96, "System" },
- { SHIFTJIS_CHARSET, FW_NORMAL, 22, 120, "System" },
- { HANGEUL_CHARSET, FW_NORMAL, 16, 96, "System" },
- { HANGEUL_CHARSET, FW_NORMAL, 20, 120, "System" },
- { DEFAULT_CHARSET, FW_BOLD, 16, 96, "System" },
- { DEFAULT_CHARSET, FW_BOLD, 20, 120, "System" },
+ { SHIFTJIS_CHARSET, FW_NORMAL, 18, 18, 96, "System" },
+ { SHIFTJIS_CHARSET, FW_NORMAL, 22, 22, 120, "System" },
+ { HANGEUL_CHARSET, FW_NORMAL, 16, 16, 96, "System" },
+ { HANGEUL_CHARSET, FW_NORMAL, 20, 20, 120, "System" },
+ { DEFAULT_CHARSET, FW_BOLD, 16, 16, 96, "System" },
+ { DEFAULT_CHARSET, FW_BOLD, 20, 20, 120, "System" },
{ 0 }
},
{ /* DEVICE_DEFAULT_FONT */
- { SHIFTJIS_CHARSET, FW_NORMAL, 18, 96, "System" },
- { SHIFTJIS_CHARSET, FW_NORMAL, 22, 120, "System" },
- { HANGEUL_CHARSET, FW_NORMAL, 16, 96, "System" },
- { HANGEUL_CHARSET, FW_NORMAL, 20, 120, "System" },
- { DEFAULT_CHARSET, FW_BOLD, 16, 96, "System" },
- { DEFAULT_CHARSET, FW_BOLD, 20, 120, "System" },
+ { SHIFTJIS_CHARSET, FW_NORMAL, 18, 18, 96, "System" },
+ { SHIFTJIS_CHARSET, FW_NORMAL, 22, 22, 120, "System" },
+ { HANGEUL_CHARSET, FW_NORMAL, 16, 16, 96, "System" },
+ { HANGEUL_CHARSET, FW_NORMAL, 20, 20, 120, "System" },
+ { DEFAULT_CHARSET, FW_BOLD, 16, 16, 96, "System" },
+ { DEFAULT_CHARSET, FW_BOLD, 20, 20, 120, "System" },
{ 0 }
},
{ /* DEFAULT_GUI_FONT */
- { SHIFTJIS_CHARSET, FW_NORMAL, -12, 96, "?MS UI Gothic" },
- { SHIFTJIS_CHARSET, FW_NORMAL, -15, 120, "?MS UI Gothic" },
- { HANGEUL_CHARSET, FW_NORMAL, -12, 96, "?Gulim" },
- { HANGEUL_CHARSET, FW_NORMAL, -15, 120, "?Gulim" },
- { GB2312_CHARSET, FW_NORMAL, -12, 96, "?SimHei" },
- { GB2312_CHARSET, FW_NORMAL, -15, 120, "?SimHei" },
- { CHINESEBIG5_CHARSET, FW_NORMAL, -12, 96, "?MingLiU" },
- { CHINESEBIG5_CHARSET, FW_NORMAL, -15, 120, "?MingLiU" },
- { DEFAULT_CHARSET, FW_NORMAL, -11, 96, "MS Shell Dlg" },
- { DEFAULT_CHARSET, FW_NORMAL, -13, 120, "MS Shell Dlg" },
+ { SHIFTJIS_CHARSET, FW_NORMAL, -12, 15, 96, "?MS UI Gothic" },
+ { SHIFTJIS_CHARSET, FW_NORMAL, -15, 18, 120, "?MS UI Gothic" },
+ { HANGEUL_CHARSET, FW_NORMAL, -12, 15, 96, "?Gulim" },
+ { HANGEUL_CHARSET, FW_NORMAL, -15, 18, 120, "?Gulim" },
+ { GB2312_CHARSET, FW_NORMAL, -12, 15, 96, "?SimHei" },
+ { GB2312_CHARSET, FW_NORMAL, -15, 18, 120, "?SimHei" },
+ { CHINESEBIG5_CHARSET, FW_NORMAL, -12, 15, 96, "?MingLiU" },
+ { CHINESEBIG5_CHARSET, FW_NORMAL, -15, 18, 120, "?MingLiU" },
+ { DEFAULT_CHARSET, FW_NORMAL, -11, 13, 96, "MS Shell Dlg" },
+ { DEFAULT_CHARSET, FW_NORMAL, -13, 16, 120, "MS Shell Dlg" },
{ 0 }
}
};
for (i = 0; i < sizeof(font)/sizeof(font[0]); i++)
{
HFONT hfont;
- LOGFONT lf;
- int ret;
+ LOGFONTA lf;
+ int ret, height;
hfont = GetStockObject(font[i]);
ok(hfont != 0, "%d: GetStockObject(%d) failed\n", i, font[i]);
- ret = GetObject(hfont, sizeof(lf), &lf);
+ ret = GetObjectA(hfont, sizeof(lf), &lf);
if (ret != sizeof(lf))
{
/* NT4 */
continue;
}
- ret = get_font_dpi(&lf);
+ ret = get_font_dpi(&lf, &height);
if (ret != td[i][j].dpi)
{
trace("%d(%d): font %s %d dpi doesn't match test data %d\n",
continue;
}
+ /* FIXME: Remove once Wine is fixed */
+ if (td[i][j].dpi != 96 &&
+ /* MS Sans Serif for 120 dpi and higher should include 12 pixel bitmap set */
+ ((!strcmp(td[i][j].face_name, "MS Sans Serif") && td[i][j].height == 12) ||
+ /* System for 120 dpi and higher should include 20 pixel bitmap set */
+ (!strcmp(td[i][j].face_name, "System") && td[i][j].height > 16)))
+ todo_wine
+ ok(height == td[i][j].height_pixels, "%d(%d): expected height %d, got %d\n", i, j, td[i][j].height_pixels, height);
+ else
+ ok(height == td[i][j].height_pixels, "%d(%d): expected height %d, got %d\n", i, j, td[i][j].height_pixels, height);
+
ok(td[i][j].weight == lf.lfWeight, "%d(%d): expected lfWeight %d, got %d\n", i, j, td[i][j].weight, lf.lfWeight);
ok(td[i][j].height == lf.lfHeight, "%d(%d): expected lfHeight %d, got %d\n", i, j, td[i][j].height, lf.lfHeight);
if (td[i][j].face_name[0] == '?')
}
else
{
- ok(!lstrcmp(td[i][j].face_name, lf.lfFaceName), "%d(%d): expected lfFaceName %s, got %s\n", i, j, td[i][j].face_name, lf.lfFaceName);
+ 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);
}
break;
}
}
}
+static void test_max_height(void)
+{
+ HDC hdc;
+ LOGFONTA lf;
+ HFONT hfont, hfont_old;
+ TEXTMETRICA tm1, tm;
+ BOOL r;
+ LONG invalid_height[] = { -65536, -123456, 123456 };
+ size_t i;
+
+ memset(&tm1, 0, sizeof(tm1));
+ memset(&lf, 0, sizeof(lf));
+ strcpy(lf.lfFaceName, "Tahoma");
+ lf.lfHeight = -1;
+
+ hdc = GetDC(NULL);
+
+ /* get 1 ppem value */
+ hfont = CreateFontIndirectA(&lf);
+ hfont_old = SelectObject(hdc, hfont);
+ r = GetTextMetricsA(hdc, &tm1);
+ ok(r, "GetTextMetrics failed\n");
+ ok(tm1.tmHeight > 0, "expected a positive value, got %d\n", tm1.tmHeight);
+ ok(tm1.tmAveCharWidth > 0, "expected a positive value, got %d\n", tm1.tmHeight);
+ DeleteObject(SelectObject(hdc, hfont_old));
+
+ /* test the largest value */
+ lf.lfHeight = -((1 << 16) - 1);
+ hfont = CreateFontIndirectA(&lf);
+ hfont_old = SelectObject(hdc, hfont);
+ memset(&tm, 0, sizeof(tm));
+ r = GetTextMetricsA(hdc, &tm);
+ ok(r, "GetTextMetrics failed\n");
+ ok(tm.tmHeight > tm1.tmHeight,
+ "expected greater than 1 ppem value (%d), got %d\n", tm1.tmHeight, tm.tmHeight);
+ ok(tm.tmAveCharWidth > tm1.tmAveCharWidth,
+ "expected greater than 1 ppem value (%d), got %d\n", tm1.tmAveCharWidth, tm.tmAveCharWidth);
+ DeleteObject(SelectObject(hdc, hfont_old));
+
+ /* test an invalid value */
+ for (i = 0; i < sizeof(invalid_height)/sizeof(invalid_height[0]); i++) {
+ lf.lfHeight = invalid_height[i];
+ hfont = CreateFontIndirectA(&lf);
+ hfont_old = SelectObject(hdc, hfont);
+ memset(&tm, 0, sizeof(tm));
+ r = GetTextMetricsA(hdc, &tm);
+ ok(r, "GetTextMetrics failed\n");
+ ok(tm.tmHeight == tm1.tmHeight,
+ "expected 1 ppem value (%d), got %d\n", tm1.tmHeight, tm.tmHeight);
+ ok(tm.tmAveCharWidth == tm1.tmAveCharWidth,
+ "expected 1 ppem value (%d), got %d\n", tm1.tmAveCharWidth, tm.tmAveCharWidth);
+ DeleteObject(SelectObject(hdc, hfont_old));
+ }
+
+ ReleaseDC(NULL, hdc);
+ return;
+}
+
+static void test_vertical_order(void)
+{
+ struct enum_font_data efd;
+ LOGFONTA lf;
+ HDC hdc;
+ int i, j;
+
+ hdc = CreateCompatibleDC(0);
+ ok(hdc != NULL, "CreateCompatibleDC failed\n");
+
+ memset(&lf, 0, sizeof(lf));
+ lf.lfCharSet = DEFAULT_CHARSET;
+ lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ lf.lfHeight = 16;
+ lf.lfWidth = 16;
+ lf.lfQuality = DEFAULT_QUALITY;
+ lf.lfItalic = FALSE;
+ lf.lfWeight = FW_DONTCARE;
+ efd.total = 0;
+ EnumFontFamiliesExA(hdc, &lf, enum_font_data_proc, (LPARAM)&efd, 0);
+ for (i = 0; i < efd.total; i++)
+ {
+ if (efd.lf[i].lfFaceName[0] != '@') continue;
+ for (j = 0; j < efd.total; j++)
+ {
+ if (!strcmp(efd.lf[i].lfFaceName + 1, efd.lf[j].lfFaceName))
+ {
+ ok(i > j,"Found vertical font %s before its horizontal version\n", efd.lf[i].lfFaceName);
+ break;
+ }
+ }
+ }
+ DeleteDC( hdc );
+}
+
+static void test_GetCharWidth32(void)
+{
+ BOOL ret;
+ HDC hdc;
+ LOGFONTA lf;
+ HFONT hfont;
+ INT bufferA;
+ INT bufferW;
+ HWND hwnd;
+
+ if (!pGetCharWidth32A || !pGetCharWidth32W)
+ {
+ win_skip("GetCharWidth32A/W not available on this platform\n");
+ return;
+ }
+
+ memset(&lf, 0, sizeof(lf));
+ strcpy(lf.lfFaceName, "System");
+ lf.lfHeight = 20;
+
+ hfont = CreateFontIndirectA(&lf);
+ hdc = GetDC(0);
+ hfont = SelectObject(hdc, hfont);
+
+ ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+ ok(ret, "GetCharWidth32W should have succeeded\n");
+ ret = pGetCharWidth32A(hdc, 'a', 'a', &bufferA);
+ ok(ret, "GetCharWidth32A should have succeeded\n");
+ ok (bufferA == bufferW, "Widths should be the same\n");
+ ok (bufferA > 0," Width should be greater than zero\n");
+
+ hfont = SelectObject(hdc, hfont);
+ DeleteObject(hfont);
+ ReleaseDC(NULL, hdc);
+
+ memset(&lf, 0, sizeof(lf));
+ strcpy(lf.lfFaceName, "Tahoma");
+ lf.lfHeight = 20;
+
+ hfont = CreateFontIndirectA(&lf);
+ hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
+ 0, 0, 0, NULL);
+ hdc = GetDC(hwnd);
+ SetMapMode( hdc, MM_ANISOTROPIC );
+ SelectObject(hdc, hfont);
+
+ ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+ ok(ret, "GetCharWidth32W should have succeeded\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);
+ ok(ret, "GetCharWidth32W should have succeeded\n");
+ ok (bufferW > 0," Width should be greater than zero\n");
+ 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");
+ SetWindowExtEx(hdc, 1,1,NULL);
+ SetGraphicsMode(hdc, GM_COMPATIBLE);
+ ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+ ok(ret, "GetCharWidth32W should have succeeded\n");
+ ok (bufferW > 0," Width should be greater than zero\n");
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+ ok(ret, "GetCharWidth32W should have succeeded\n");
+ ok (bufferW > 0," Width should be greater than zero\n");
+
+ ReleaseDC(hwnd, hdc);
+ DestroyWindow(hwnd);
+
+ hwnd = CreateWindowExA(WS_EX_LAYOUTRTL, "static", "", WS_POPUP, 0,0,100,100,
+ 0, 0, 0, NULL);
+ hdc = GetDC(hwnd);
+ SetMapMode( hdc, MM_ANISOTROPIC );
+ SelectObject(hdc, hfont);
+
+ ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+ ok(ret, "GetCharWidth32W should have succeeded\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);
+ ok(ret, "GetCharWidth32W should have succeeded\n");
+ ok (bufferW > 0," Width should be greater than zero\n");
+ SetGraphicsMode(hdc, GM_ADVANCED);
+ ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+ ok(ret, "GetCharWidth32W should have succeeded\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);
+ ok(ret, "GetCharWidth32W should have succeeded\n");
+ ok (bufferW > 0," Width should be greater than zero\n");
+ 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");
+
+ ReleaseDC(hwnd, hdc);
+ DestroyWindow(hwnd);
+ DeleteObject(hfont);
+}
+
+static void test_fake_bold_font(void)
+{
+ HDC hdc;
+ HFONT hfont, hfont_old;
+ LOGFONTA lf;
+ BOOL ret;
+ TEXTMETRICA tm[2];
+ ABC abc[2];
+ INT w[2];
+
+ if (!pGetCharWidth32A || !pGetCharABCWidthsA) {
+ win_skip("GetCharWidth32A/GetCharABCWidthA is not available on this platform\n");
+ return;
+ }
+
+ /* Test outline font */
+ memset(&lf, 0, sizeof(lf));
+ strcpy(lf.lfFaceName, "Wingdings");
+ lf.lfWeight = FW_NORMAL;
+ lf.lfCharSet = SYMBOL_CHARSET;
+ hfont = CreateFontIndirectA(&lf);
+
+ hdc = GetDC(NULL);
+ hfont_old = SelectObject(hdc, hfont);
+
+ /* base metrics */
+ ret = GetTextMetricsA(hdc, &tm[0]);
+ ok(ret, "got %d\n", ret);
+ ret = pGetCharABCWidthsA(hdc, 0x76, 0x76, &abc[0]);
+ ok(ret, "got %d\n", ret);
+
+ lf.lfWeight = FW_BOLD;
+ hfont = CreateFontIndirectA(&lf);
+ DeleteObject(SelectObject(hdc, hfont));
+
+ /* bold metrics */
+ ret = GetTextMetricsA(hdc, &tm[1]);
+ ok(ret, "got %d\n", ret);
+ ret = pGetCharABCWidthsA(hdc, 0x76, 0x76, &abc[1]);
+ ok(ret, "got %d\n", ret);
+
+ DeleteObject(SelectObject(hdc, hfont_old));
+ ReleaseDC(NULL, hdc);
+
+ /* compare results (outline) */
+ ok(tm[0].tmHeight == tm[1].tmHeight, "expected %d, got %d\n", tm[0].tmHeight, tm[1].tmHeight);
+ ok(tm[0].tmAscent == tm[1].tmAscent, "expected %d, got %d\n", tm[0].tmAscent, tm[1].tmAscent);
+ ok(tm[0].tmDescent == tm[1].tmDescent, "expected %d, got %d\n", tm[0].tmDescent, tm[1].tmDescent);
+ ok((tm[0].tmAveCharWidth + 1) == tm[1].tmAveCharWidth,
+ "expected %d, got %d\n", tm[0].tmAveCharWidth + 1, tm[1].tmAveCharWidth);
+ ok((tm[0].tmMaxCharWidth + 1) == tm[1].tmMaxCharWidth,
+ "expected %d, got %d\n", tm[0].tmMaxCharWidth + 1, tm[1].tmMaxCharWidth);
+ ok(tm[0].tmOverhang == tm[1].tmOverhang, "expected %d, got %d\n", tm[0].tmOverhang, tm[1].tmOverhang);
+ w[0] = abc[0].abcA + abc[0].abcB + abc[0].abcC;
+ w[1] = abc[1].abcA + abc[1].abcB + abc[1].abcC;
+ ok((w[0] + 1) == w[1], "expected %d, got %d\n", w[0] + 1, w[1]);
+
+}
+
+static void test_bitmap_font_glyph_index(void)
+{
+ const WCHAR text[] = {'#','!','/','b','i','n','/','s','h',0};
+ const struct {
+ LPCSTR face;
+ BYTE charset;
+ } bitmap_font_list[] = {
+ { "Courier", ANSI_CHARSET },
+ { "Small Fonts", ANSI_CHARSET },
+ { "Fixedsys", DEFAULT_CHARSET },
+ { "System", DEFAULT_CHARSET }
+ };
+ HDC hdc;
+ LOGFONTA lf;
+ HFONT hFont;
+ CHAR facename[LF_FACESIZE];
+ BITMAPINFO bmi;
+ HBITMAP hBmp[2];
+ void *pixels[2];
+ int i, j;
+ DWORD ret;
+ BITMAP bmp;
+ TEXTMETRICA tm;
+ CHARSETINFO ci;
+ BYTE chr = '\xA9';
+
+ if (!pGetGlyphIndicesW || !pGetGlyphIndicesA) {
+ win_skip("GetGlyphIndices is unavailable\n");
+ return;
+ }
+
+ hdc = CreateCompatibleDC(0);
+ ok(hdc != NULL, "CreateCompatibleDC failed\n");
+
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biWidth = 128;
+ bmi.bmiHeader.biHeight = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+
+ for (i = 0; i < sizeof(bitmap_font_list)/sizeof(bitmap_font_list[0]); i++) {
+ memset(&lf, 0, sizeof(lf));
+ lf.lfCharSet = bitmap_font_list[i].charset;
+ strcpy(lf.lfFaceName, bitmap_font_list[i].face);
+ hFont = CreateFontIndirectA(&lf);
+ ok(hFont != NULL, "Can't create font (%s:%d)\n", lf.lfFaceName, lf.lfCharSet);
+ hFont = SelectObject(hdc, hFont);
+ ret = GetTextMetricsA(hdc, &tm);
+ ok(ret, "GetTextMetric failed\n");
+ ret = GetTextFaceA(hdc, sizeof(facename), facename);
+ ok(ret, "GetTextFace failed\n");
+ if (tm.tmPitchAndFamily & TMPF_TRUETYPE) {
+ skip("TrueType font (%s) was selected for \"%s\"\n", facename, bitmap_font_list[i].face);
+ continue;
+ }
+ if (lstrcmpiA(facename, lf.lfFaceName) != 0) {
+ skip("expected %s, got %s\n", lf.lfFaceName, facename);
+ continue;
+ }
+
+ for (j = 0; j < 2; j++) {
+ HBITMAP hBmpPrev;
+ hBmp[j] = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &pixels[j], NULL, 0);
+ ok(hBmp[j] != NULL, "Can't create DIB\n");
+ hBmpPrev = SelectObject(hdc, hBmp[j]);
+ switch (j) {
+ case 0:
+ ret = ExtTextOutW(hdc, 0, 0, 0, NULL, text, lstrlenW(text), NULL);
+ break;
+ case 1:
+ {
+ int len = lstrlenW(text);
+ LPWORD indices = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WORD));
+ ret = pGetGlyphIndicesW(hdc, text, len, indices, 0);
+ ok(ret, "GetGlyphIndices failed\n");
+ ok(memcmp(indices, text, sizeof(WORD) * len) == 0,
+ "Glyph indices and text are different for %s:%d\n", lf.lfFaceName, tm.tmCharSet);
+ ret = ExtTextOutW(hdc, 0, 0, ETO_GLYPH_INDEX, NULL, indices, len, NULL);
+ HeapFree(GetProcessHeap(), 0, indices);
+ break;
+ }
+ }
+ ok(ret, "ExtTextOutW failed\n");
+ SelectObject(hdc, hBmpPrev);
+ }
+
+ GetObjectA(hBmp[0], sizeof(bmp), &bmp);
+ ok(memcmp(pixels[0], pixels[1], bmp.bmHeight * bmp.bmWidthBytes) == 0,
+ "Images are different (%s:%d)\n", lf.lfFaceName, tm.tmCharSet);
+
+ ret = TranslateCharsetInfo((LPDWORD)(DWORD_PTR)tm.tmCharSet, &ci, TCI_SRCCHARSET);
+ if (!ret) {
+ skip("Can't get charset info for (%s:%d)\n", lf.lfFaceName, tm.tmCharSet);
+ goto next;
+ }
+ if (IsDBCSLeadByteEx(ci.ciACP, chr)) {
+ skip("High-ascii character is not defined in codepage %d\n", ci.ciACP);
+ goto next;
+ }
+
+ for (j = 0; j < 2; j++) {
+ HBITMAP hBmpPrev;
+ WORD code;
+ hBmpPrev = SelectObject(hdc, hBmp[j]);
+ switch (j) {
+ case 0:
+ ret = ExtTextOutA(hdc, 100, 0, 0, NULL, (LPCSTR)&chr, 1, NULL);
+ break;
+ case 1:
+ ret = pGetGlyphIndicesA(hdc, (LPCSTR)&chr, 1, &code, 0);
+ ok(ret, "GetGlyphIndices failed\n");
+ ok(code == chr, "expected %02x, got %02x (%s:%d)\n", chr, code, lf.lfFaceName, tm.tmCharSet);
+ ret = ExtTextOutA(hdc, 100, 0, ETO_GLYPH_INDEX, NULL, (LPCSTR)&code, 1, NULL);
+ break;
+ }
+ ok(ret, "ExtTextOutA failed\n");
+ SelectObject(hdc, hBmpPrev);
+ }
+
+ ok(memcmp(pixels[0], pixels[1], bmp.bmHeight * bmp.bmWidthBytes) == 0,
+ "Images are different (%s:%d)\n", lf.lfFaceName, tm.tmCharSet);
+ next:
+ for (j = 0; j < 2; j++)
+ DeleteObject(hBmp[j]);
+ hFont = SelectObject(hdc, hFont);
+ DeleteObject(hFont);
+ }
+
+ DeleteDC(hdc);
+}
+
START_TEST(font)
{
init();
test_fullname();
test_fullname2();
test_east_asian_font_selection();
+ test_max_height();
+ test_vertical_order();
+ test_GetCharWidth32();
+ test_fake_bold_font();
+ test_bitmap_font_glyph_index();
/* These tests should be last test until RemoveFontResource
* is properly implemented.