{"id":608,"date":"2010-04-20T20:10:07","date_gmt":"2010-04-20T19:10:07","guid":{"rendered":"http:\/\/blog.m-ri.de\/?p=608"},"modified":"2010-04-20T10:35:47","modified_gmt":"2010-04-20T09:35:47","slug":"achtung-die-festen-mapping-modes-des-gdi-basieren-nicht-auf-logpixelsx-und-logpixelsy","status":"publish","type":"post","link":"http:\/\/blog.m-ri.de\/index.php\/2010\/04\/20\/achtung-die-festen-mapping-modes-des-gdi-basieren-nicht-auf-logpixelsx-und-logpixelsy\/","title":{"rendered":"Achtung: Die festen Mapping Modes des GDI basieren nicht auf LOGPIXELSX und LOGPIXELSY!"},"content":{"rendered":"<p>Jeder der mit Fontgr\u00f6\u00dfen und Darstellungsgr\u00f6\u00dfen herumspielt, oder wer selber in Fenstern zeichnet kennt <em>LOGPIXELSX<\/em> und <em>LOGPIXELSY<\/em>, die durch <a href=\"http:\/\/msdn.microsoft.com\/de-de\/library\/0h8e85be(VS.80).aspx\">GetDevCaps<\/a> geliefert werden. Diese Werte dienen auch <em>CFont::CreatePointFont <\/em>und anderen Funktionen bei der Umrechnung von &#8222;realen&#8220; Ma\u00dfen auf die Devicepoints, die man dann ben\u00f6tigt. Alles kein Hexenwerk und \u00fcberall im Netz beschrieben.<br \/>\nAuf diesem Weg kann man mit etwas <em>MulDiv<\/em> Arithmetik schnell umrechnen wie viele Punkte man ben\u00f6tigt um etwas von 10mm Gr\u00f6\u00dfe auf einem Device darzustellen.<\/p>\n<p>Der nachfolgende Code wandelt Einheiten von 1mm entsprechend der Aufl\u00f6sung eines Devices in Pixel um.<\/p>\n<pre lang=\"cpp\">pDC-&gt;SetMapMode(MM_TEXT);\r\n\/\/ Convert mm to with LOGPIXELSX\r\nCSize sizeLogPixel(pDC-&gt;GetDeviceCaps(LOGPIXELSX),\r\n            pDC-&gt;GetDeviceCaps(LOGPIXELSY));\r\nrect.top = ::MulDiv(rect.top,sizeLogPixel.cy*10,254);\r\nrect.bottom = ::MulDiv(rect.bottom,sizeLogPixel.cy*10,254);\r\nrect.left = ::MulDiv(rect.left,sizeLogPixel.cx*10,254);\r\nrect.right = ::MulDiv(rect.right,sizeLogPixel.cx*10,254);<\/pre>\n<p>Die Aufl\u00f6sung von 0,1mm je Einheit ist die Metrik des Mappingmodes <em>MM_LOMETRIC<\/em>. Man sollte also meinen, dass die Verwendung von <em>MM_LOMETRIC<\/em> mit einem Faktor 10, der obigen Umrechnung gleich kommt.<\/p>\n<pre lang=\"cpp\">pDC-&gt;SetMapMode(MM_LOMETRIC);\r\n\/\/ Convert mm to 0.1mm\r\nrect.top *= -10;\r\nrect.bottom *= -10;\r\nrect.left *= 10;\r\nrect.right *= 10;<\/pre>\n<p>Probiert man dies aus, so stellt man \u00fcberrascht fest, dass die Gr\u00f6\u00dfen nicht \u00fcbereinstimmen.<br \/>\nDer Dokumentation nach m\u00fcsste man es aber denken.<\/p>\n<p>Mit einem bisschen experimentieren bin ich letztlich auf den Grund gekommen.<br \/>\nKeiner der Mappingmodes <em>MM_LOENGLISH, MM_HIENGLICH, MM_LOMETRIC <\/em>oder <em>MM_HIMETRIC <\/em>verwendet <em>LOGPIXELSX<\/em> oder <em>LOGPIXELSY<\/em>. Diese Mappingmodes verwenden die Werte <em>HORZRES<\/em> und <em>VERTRES<\/em> in dem Viewport-Extent und die Werte <em>HORZSIZE<\/em> und <em>VERTSIZE<\/em> im Window-Extent.<\/p>\n<p>D.h. der Viewport-Extent bekommt die Gr\u00f6\u00dfe des Bildschirmes in Pixeln zugewiesen und das Window-Extent bekommt die Gr\u00f6\u00dfe des Devices in mm zugewiesen. Nun ist diese Gr\u00f6\u00dfe (<em>HORZSIZE\/VERTSIZE<\/em>) bei Bildschirmen nicht die reale Gr\u00f6\u00dfe sondern eine Gr\u00f6\u00dfe, die der Hersteller festlegt. (Anmerkung: Bei Druckern stimmt dieser Wert)<\/p>\n<p>Nun w\u00e4re noch alles OK, wenn sich aus den Werten von <em>VERT\/HORZSIZE<\/em> und <em>VERT\/HORZRES<\/em> nun der Quotient <em>LOGPIXELSX\/SY<\/em> ermitteln lie\u00dfe. Das ist aber nicht der Fall! <em>LOGPIXELSX\/SY <\/em>sind Skalierungswerte die bei Bildschirmen unabh\u00e4ngig von der realen Aufl\u00f6sung angegeben werden und die z.B. dazu Dienen Schriftgr\u00f6\u00dfen grunds\u00e4tzlich gr\u00f6\u00dfer oder kleiner anzeigen zu lassen (siehe auch <em>High DPI Mode<\/em>).<\/p>\n<p>Die Konsequenz daraus ist, dass die Mappingmodes ein relativ exotisches Einzelleben f\u00fchren, weil die meisten Entwickler eben korrekterweise auf <em>LOGPIXELSX\/SY<\/em> zur\u00fcckgreifen. Noch mal sei hier bemerkt, dass f\u00fcr Drucker DCs hier in mir bekannten F\u00e4llen kein Unterschied existiert und auch das ist gut so.<\/p>\n<p>Die L\u00f6sung die sich anbietet, ist nicht weiter schwierig und sie auch der Grund warum ich erst jetzt auf diesen gesamten Umstand gesto\u00dfen bin. Ich habe niemals die <em>MM_LO\u2026\/MM_HI\u2026 <\/em>Mappingmodes verwendet. Entweder pur <em>MM_TEXT <\/em>und wenn ich was anderes ben\u00f6tigt habe einfach <em>MM_ANISOTROPIC<\/em>, und in der entsprechenden Skalierung habe ich dann meistens die Werte aus <em>LOGPIXELSX\/SY<\/em> verwendet. Also musste es passen.<\/p>\n<p><em>MM_ANISOTROPIC <\/em>ist sowieso der Mappingmode der Wahl, wenn es um skalierbare Darstellungen und Zoomfaktoren geht, aber dazu vielleicht mehr in einem Artikel demn\u00e4chst.<\/p>\n<p>Ich habe ein kleines MFC-Programm gebaut (<a href=\"http:\/\/blog.m-ri.de\/wp-content\/uploads\/2010\/04\/MappingModeTest.zip\">MappingModeTest<\/a>), dass diese Konflikte aufzeigt. Ich zeichne dort ein Rechteck auf den Koordinaten 20mm,10mm mit der Gr\u00f6\u00dfe 60mm,40mm. Damit die verschiedenen Rechtecke alle sichtbar werden verwende ich immer einen Versatz von 1mm und zeichne die Rechtecke in unterschiedlichen Farben.<br \/>\nIn der Debugausgabe kann man wundersch\u00f6n sehen wie Extents mit den Werten aus <em>GetDeviceCaps<\/em> zusammenh\u00e4ngen.<\/p>\n<p>Dieser Artikel basiert auf zwei Anfragen in microsoft.public.de.vc die dieses unterschiedliche Verhalten aufzeigten und diskutieren:<br \/>\n<a href=\"http:\/\/groups.google.de\/group\/microsoft.public.de.vc\/browse_thread\/thread\/23467a5e95051291\/7c66c01b8295eaab\">http:\/\/groups.google.de\/group\/microsoft.public.de.vc\/browse_thread\/thread\/23467a5e95051291\/7c66c01b8295eaab<\/a><br \/>\n<a href=\"http:\/\/groups.google.de\/group\/microsoft.public.de.vc\/browse_thread\/thread\/201719d23a411256\/17b41c09844bf105\">http:\/\/groups.google.de\/group\/microsoft.public.de.vc\/browse_thread\/thread\/201719d23a411256\/17b41c09844bf105<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Jeder der mit Fontgr\u00f6\u00dfen und Darstellungsgr\u00f6\u00dfen herumspielt, oder wer selber in Fenstern zeichnet kennt LOGPIXELSX und LOGPIXELSY, die durch GetDevCaps geliefert werden. Diese Werte dienen auch CFont::CreatePointFont und anderen Funktionen bei der Umrechnung von &#8222;realen&#8220; Ma\u00dfen auf die Devicepoints, die man dann ben\u00f6tigt. Alles kein Hexenwerk und \u00fcberall im Netz beschrieben. Auf diesem Weg kann &hellip; <a href=\"http:\/\/blog.m-ri.de\/index.php\/2010\/04\/20\/achtung-die-festen-mapping-modes-des-gdi-basieren-nicht-auf-logpixelsx-und-logpixelsy\/\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eAchtung: Die festen Mapping Modes des GDI basieren nicht auf LOGPIXELSX und LOGPIXELSY!\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[30,3,2],"tags":[370,117,227,61],"class_list":["post-608","post","type-post","status-publish","format-standard","hentry","category-c","category-programmieren","category-windows-api","tag-c","tag-gdi","tag-graphics","tag-winapi"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/608","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/comments?post=608"}],"version-history":[{"count":1,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/608\/revisions"}],"predecessor-version":[{"id":613,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/608\/revisions\/613"}],"wp:attachment":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/media?parent=608"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/categories?post=608"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/tags?post=608"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}