I am currently working on a GUI at a Windows 7 64-bit PC. While comparing the visualisation of text in different programs, I recognized, that there are differences in how big text is displayed on my monitor, given the same text style and size.
Does anyone has an idea where this comes from?
I created this behaviour by typing a text in Arial Regular 12pt containing the letter T in a program and scaling the view to 100%. Afterwards I measured the height of the letter T in pixels with the help of a screenshot.
Programs I testet:
MS Word 2010: T is 12 pixels high
LibreOffice Writer 5.2.7.2 (x64): T is 12 pixels high
Scribus 1.4.6: T is 12 pixels high
GIMP 2.8.14: T is 9 pixels high
Java 8 Update 181 (which I use for my own GUI): T is 9 pixels high
pt (point) is a unit for physical sizes, typically 1/72th of an inch.
In order to transfer this to a size in pixels, you need to know how many pixels will be in one inch on your screen. This value is known as Pixels Per Inch (PPI), sometimes somewhat ambiguously called Dots Per Inch (DPI).
Note that this value will usually be different for an application UI and the documents you are working on.
From the values you provided, it looks like MS Word, LibreOffice and Scribus assume 72 PPI (or at least the documents you are working on do), whereas GIMP and Java use 96 PPI.
It's not obvious whether you are referring to the size of text ion the respective applications' UI or documents opened in them, though, so I could be totally off.
I want to create a custom live tile. I just need to display a number with large digits (1 to 4 digits) in the center of the tile, no icon, no text or anything else and it should be possible to update the tile also.
I have tried the default tile, but it displays the number at the up-right corner with small font and cannot pass number 99.Any ideas? (programming in Visual Basic)
I wrote a guide, how to render your own tiles even with transparency, but beware of the memory consumption in background agent. Typically you should render at max only one tile:
Pro Live Tiles for Windows Phone
http://suchan.cz/?p=110
My question is about how font handling needs to be changed in order to work correctly under Windows 7. I'm sure that I've made an assumption about something that was valid before, but is no longer valid. But I don't even know where to begin looking! I'm praying someone can help! Here are the details as I understand them (I've also posted this question on a Microsoft Windows Developers forum, but they're not answering):
Yes, I'm behind the times (heck, I still write WIN32 code in plain C!) I have a 10 yr old DLL I wrote that mimics an even older DOS screen I/O library within the client area of a window. Needless to say, it only allows the use of fixed-width fonts. When some of the programs using the DLL have been moved to Windows 7, there is a strange flickering that appears when a fixed-width TRUE TYPE font is used (bitmap fonts still work perfectly.) We've tracked the problem down to the fact that a single character written with ExtTextOut is wider than it should be. I've checked the measurements three different ways (by using GetTextExtentPoint32 on a 132 character string and dividing by 132, by calling GetTextMetrics and even by using GetCharABCWidths for all 256 characters) and they all agree that the font is the same width. But ExtTextOut is rendering the background rectangle one or two pixels wider than the font width. Either than, or it is beginning the background rendering a pixel or two to the left of the position given in the parameters [I call it like this: ExtTextOut( hdc, r.left, r.top, ETO_OPAQUE, &r, &ch, 1, NULL ).] And remember, this EXACT code worked perfectly under Windows 2000, Windows XP and, with bitmap fonts on Windows 7 -- but it no longer works correctly with fixed-width true type fonts under Windows 7.
For anyone who isn't grasping what I need to do: try to imagine writing one character per square on a piece of graph paper. Every square uses the same font, but may have a different foreground and/or background color. I use TA_TOP|TA_LEFT text alignment, because it is the simplest and any consistently applied alignment should work for a fixed-width font.
What I'm seeing is that ExtTextOut is emitting a larger background rectangle than I've specified in the RECT * parameter. Since the rectangle I'm providing is created from the reported size of the font, this should NEVER happen -- and it never happened on Windows XP and earlier, and doesn't happen with bitmap (i.e. .FON) fonts under Windows 7, either. But it ALWAYS happens with fixed-width TrueType fonts under Windows 7. This is with the EXACT SAME EXECUTABLE running on Windows 2000, Windows XP and Windows 7 (32 & 64.) While I would love to simply say Windows 7 has a bug, I'm more inclined to believe that some fundamental assumption that I've made about font handling under Windows is no longer true (after 20 years of writing software for Windows.)
But I have no idea how or where to discover what that might be! Please, PLEASE help me!
--- ammendment ---
For anyone interested, I've managed to work around what I am considering a bug -- until I find documentation to the contrary. My workaround consists of two changes to my library:
Use the size returned from GetTextExtentPoint32() of an 'X' instead
of data from TEXTMETRICS.
Include the ETO_CLIPPING flag in all ExtTextOut() calls.
Previously, I was using tmHeight+tmExternalLeading for the number of pixels between the tops of consecutive rows of text, as is documented. I discovered that the size.cy value coming back from the GetTextExtentPoint32() wasn't the same and seemed more accurate. The worst example I found was the OCRB true type font. Here's what I saw in the debugger for the OCRB font I'd created (using the system font selection dialog):
ocrbtm.tmHeight = 11
ocrbtm.tmExternalLeading = 7
ocrbsize.cy = 11
So, for some reason that I've yet to discover, Windows is ignoring the external leading value defined for the OCRB font. Using the size value instead of the TM results in nice, neat, close packed text, which is just what I wanted.
The ETO_CLIPPING flag should not be necessary for me because I am setting the rectangle to exactly the dimensions of a single character and using ETO_OPAQUE to fill in the background (and overwrite the previous cell content.) But without the clipping flag, a single character is wider than either the size, text metric, or ABC width would indicate -- at least, that is true based on all of the documentation I've found so far.
I believe that HEIGHT issue has existed for a long time, but the rest was unnecessary until we ran our software under Windows 7. I'm appending this to my question to see if anyone can explain what I obviously don't understand.
-- ammendment 2 --
1: All documentation I can find says that tmHeight+tmExternalLeading should produce single spaced lines of text. Period. But that is not always true and I cannot find documentation indicating how Windows determines the different values that are sometimes returned by GetTextExtentPoint32().
2: under Win7 (maybe Vista) ExtTextOut started filling in a little more background than it should (by adding a couple extra pixels to the right), but only when a true type font is selected. It does this even if the rectangle is double the expected size of the character (in BOTH dimensions.) DPI/Scaling might be a factor, but since my system is set to 100%, it would seem that Windows is having trouble with a 1:1 scaling factor and that would seem to be a bug. The fact that it only affects true type and not bitmap (.FON) fonts also seems to rule out scaling (unless there is a bug in the scaling system), since Windows should attempt to scale all of the text, not just some of it. Also, there's a greyed (but checked) setting "Use Windows XP style DPI scaling" in the "Custom DPI Setting" dialog. Lastly, this entire issue may be a result of my running under the Windows Classic theme instead of one of the Aero or other Win7 native themes.
-- ammendment 3 --
Simply calling SetProcessDPIAware() has no effect on the issue I'm having. Since my problem exists at the 100% DPI setting (scale 1:1), if my problem is DPI-related, then I must have discovered a bug in the DPI virtualization because this is how Microsoft describes the feature:
This feature works by providing "virtualized" system metrics and UI elements to the application, as if it were running at 96 DPI. The application then renders to a 96-DPI off-screen surface, and the Desktop Windows Manager scales the resulting application window to match the DPI setting.
All of my settings show that I'm at 100% scaling, and looking in the custom settings box clearly shows that means 96 DPI. So, if the DPI virtualization from 96 DPI to 96 DPI is not working for my fixed-width true type fonts, then Windows has a problem, right? Or is there some function I need to call (or stop calling?) in order allow the DPI virtualizer to work correctly?
I'm still not convinced that the supposed scaling issue actually has as much to do with the font SIZE as I originally thought. That's because the problem is manifesting in the background rectangle being filled by ExtTextOut() instead of the text character being emitted. The background rectangle gets enlarged a bit when the font is true type. I've also now verified that this problem occurs whether using the Windows Classic theme or the standard Windows Aero theme. Now to build a simplified example so others can experiment with it.
-- ammendment 4 --
I've created a minimal demo program that shows what I'm seeing (and what I'm doing.) The Visual Studio 2010 project/source may be downloaded from http://www.svalli.com/files/fwtt.7z -- I intentionally didn't include executables because I don't want to risk spreading malware. The program has you choose a fixed-width font and then writes two 5x5 character grids to the client area, one created using the GetTextExtentPoint32 size and one using the TEXTMETRIC size as documented by Microsoft. The grids are in a black&white checkerboard pattern with a yellow on red character written last into the center to show the overlap effect (you may need a zoom utility to see it clearly.) The program also draws a string that starts with 5 X's just below the grid, starting at the same left offset, to be used as a comparison for my method of placing individual characters (I match the string.) The menu allows toggling clipping on/off in ExtTextOut and selection of other fonts. There is also a command line option dpiaware (case-sensitive) that causes the program to call SetProcessDPIAware() when it starts up, so that the effect of that call may also be evaluated.
From creating this I've learned that ExtTextOut is filling the correct background rectangle, but the character being rendered with an opaque background may be wider than it should be and may not even begin where ExtTextOut was told to begin drawing! I said "should be" because the character spacing I'm ending up with matches what I get when I have ExtTextOut render a whole string. The overlap may apparently be on either or both sides of the given rectangle, for example, OCRB adds an extra pixel to both the left and right sides of the character cell while the other true type fonts I've checked add two pixels to the right edge.
I really want to do this the "right" way, but I cannot find any documentation that shows what I'm doing wrong or am missing. Well, I am probably missing something for DPI Aware at scales other than 100%, but otherwise, I'm just baffled.
-- ammendment 5 --
Slightly less baffled... the problem is caused by ClearType. Turning off ClearType made all of the fonts work again. Turning ON ClearType under XP causes the same problem. Apparently ClearType can silently (until someone tells me how to detect it) stretch characters horizontally by a couple pixels in order to make space for the shaded pixels it adds to smooth things out.
Is clipping the only way around this problem?
-- ammendment 6 --
Partial answer to my clipping question above: When creating a new font I now do the following (in pseudo code):
CreateFontIndirect
SelectFont
GetTextMetrics
if( (tmPitchAndFamily & TMPF_TRUETYPE) && Win6.x or above )
if( SystemParametersInfo( SPI_GETCLEARTYPE ) )
lfQuality = NONANTIALIASED_QUALITY
DeleteObject( font )
CreateFontIndirect
Without enabling clipping this almost always works with the font sizes I'm using, though I've found a few that still render an extra pixel to the right (or left) of the character cell. Luckily, those appear to be free fonts found on the internet, so their overall quality might be below the standards of professional font foundries.
If anyone can find a better answer, I'd really, REALLY love to hear it! Until then, I think this is as good as it will get. Thanks for reading this far!
Make sure your code is high DPI aware, and then tell the OS that your process is DPI aware.
If you don't tell the OS that you're DPI aware, some of the measurement functions will lie and give you numbers based on the assumption that the display DPI is actually 96 dpi regardless of what it really is. Meanwhile, the drawing functions will try to scale in the other direction. For simple high-level drawing, this approach generally works (though it often leads to fuzzy text). For small measurements and precise placement of individual characters, this often results in round off problems that lead to things like inconsistent font sizes. This behavior was introduced in Windows Vista.
You can see it all the time in Visual Studio 2010+ as the syntax highlighter colors the text and words shift by a couple pixels here and there as you type. Really frickin' annoying.
Regarding the amendment:
tmExternalLeading is simply a recommendation from the font designer as to how much extra space to put between lines of text. MSDN documentation typically says, "the amount of extra leading (space) that the application adds between rows." Well, you're the application, so the "Right Thing To Do" is to add it between rows when you're drawing text yourself, but it really is up to you. (I suspect higher level functions like DrawText will use it.
It is perfectly correct for GetTextExtentPoint32 (and friends) to return a size.cy equal to tmHeight and to ignore tmExternalLeading. As the programmer, it's ultimately your choice how much leading to actually use.
You can see that this with some simply drawing code. Select a font with a non-zero tmExternalLeading (Arial works for me). Draw some text using TextOut and a unique background color. Then measure the text with GetTextExtentPoint32 and draw some lines based on the values you get back. You'll see that the background color rectangle excludes the external leading. External leading is just that: external. It's not in the bounds of the character cell.
// Draw the sample text with an opaque background.
assert(::GetMapMode(ps.hdc) == MM_TEXT);
assert(::GetBkMode(ps.hdc) == OPAQUE);
assert(::GetTextAlign(ps.hdc) == TA_TOP);
COLORREF rgbOld = ::SetBkColor(ps.hdc, RGB(0xC0, 0xFF, 0xC0));
::TextOutW(ps.hdc, x, y, pszText, cchText);
::SetBkColor(ps.hdc, rgbOld);
// This vertical line at the right side of the text shows that opaque
// background is exactly the height returned by GetTextExtentPoint32.
SIZE size = {0};
if (::GetTextExtentPoint32W(ps.hdc, pszText, cchText, &size)) {
::MoveToEx(ps.hdc, x + size.cx, y, NULL);
::LineTo(ps.hdc, x + size.cx, y + size.cy);
}
// These horizontal lines show the normal line spacing, taking into
// account tmExternalLeading.
assert(tm.tmExternalLeading > 0); // ensure it's an interesting case
::MoveToEx(ps.hdc, x, y, NULL);
::LineTo(ps.hdc, x + size.cx, y); // top of this line
const int yNext = y + tm.tmHeight + tm.tmExternalLeading;
::MoveToEx(ps.hdc, x, yNext, NULL);
::LineTo(ps.hdc, x + size.cx, yNext); // top of next line
The gap between the bottom of the colored rectangle and the top of the next line represents the external leading, which is always outside the character cell.
OCR-B is designed for reliable optical character recognition in banking equipment. Having a large external leading (relative to the height of the actual text) may be appropriate for some OCR applications. For this particular font, it's probably not an aesthetic choice.
Which would be the best size for different WP7 controls(like listview items, buttons etc) in order to be "finger friendly"? Is any resource that handle this problem?
According to the UI Design and Interaction Guide for Windows Phone 7 v2.0:
Touch targets should not be smaller than 9 mm or 34 pixels square and
provide at least 2 mm or 8 pixels between touchable controls. In excep-
tional cases, controls can be smaller but never more than 7 mm or 26
pixels square. The on-screen keyboard and hyperlinks in Windows Phone®
Internet Explorer® are an exception because they have differently sized hit
targets.
Im creating pdfs server side with lots of graphics so maximizing real estate is a must but at the same time ensuring users printers can handle the tight margins is a must.
Does anyone have an idea what safe values I can use for the margins when authoring the pdfs. In the past Ive used work and home printers with margins of about one cm with no problems but of course I can't take this as the defacto minimum.
Oh and I don't really want to allow the user to specify the margin (50% lazyness 50% will get complicated.)
Ive googled but couldn't find anything concrete. (average minimum margin printing)
Every printer is different but 0.25" (6.35 mm) is a safe bet.
For every PostScript printer, one part of its driver is an ASCII file called PostScript Printer Description (PPD). PPDs are used in the CUPS printing system on Linux and Mac OS X as well even for non-PostScript printers.
Every PPD MUST, according to the PPD specification written by Adobe, contain definitions of a *ImageableArea (that's a PPD keyword) for each and every media sizes it can handle. That value is given for example as *ImageableArea Folio/8,25x13: "12 12 583 923" for one printer in this office here, and *ImageableArea Folio/8,25x13: "0 0 595 935" for the one sitting in the next room.
These figures mean "Lower left corner is at (12|12), upper right corner is at (583|923)" (where these figures are measured in points; 72pt == 1inch). Can you see that the first printer does print with a margin of 1/6 inch? -- Can you also see that the next one can even print borderless?
What you need to know is this: Even if the printer can do very small margins physically, if the PPD *ImageableArea is set to a wider margin, the print data generated by the driver and sent to the printer will be clipped according to the PPD setting -- not by the printer itself.
These days more and more models appear on the market which can indeed print edge-to-edge. This is especially true for office laser printers. (Don't know about devices for the home use market.) Sometimes you have to enable that borderless mode with a separate switch in the driver settings, sometimes also on the device itself (front panel, or web interface).
Older models, for example HP's, define in their PPDs their margines quite generously, just to be on the supposedly "safe side". Very often HP used 1/3, 1/2 inch or more (like "24 24 588 768" for Letter format). I remember having hacked HP PPDs and tuned them down to "6 6 606 786" (1/12 inch) before the physical boundaries of the device kicked in and enforced a real clipping of the page image.
Now, PCL and other language printers are not that much different in their margin capabilities from PostScript models.
But of course, when it comes to printing of PDF docs, here you can nearly always choose "print to fit" or similarly named options. Even for a file that itself does not use any margins. That "fit" is what the PDF viewer reads from the driver, and the viewer then scales down the page to the *ImageableArea.
As a general rule of thumb, I use 1 cm margins when producing pdfs. I work in the geospatial industry and produce pdf maps that reference a specific geographic scale. Therefore, I do not have the option to 'fit document to printable area,' because this would make the reference scale inaccurate. You must also realize that when you fit to printable area, you are fitting your already existing margins inside the printer margins, so you end up with double margins. Make your margins the right size and your documents will print perfectly. Many modern printers can print with margins less than 3 mm, so 1 cm as a general rule should be sufficient. However, if it is a high profile job, get the specs of the printer you will be printing with and ensure that your margins are adequate. All you need is the brand and model number and you can find spec sheets through a google search.
The margins vary depending on the printer. In Windows GDI, you call the following functions to get the built-in margins, the "no-print zone":
GetDeviceCaps(hdc, PHYSICALWIDTH);
GetDeviceCaps(hdc, PHYSICALHEIGHT);
GetDeviceCaps(hdc, PHYSICALOFFSETX);
GetDeviceCaps(hdc, PHYSICALOFFSETY);
Printing right to the edge is called a "bleed" in the printing industry. The only laser printer I ever knew to print right to the edge was the Xerox 9700: 120 ppm, $500K in 1980.
You shouldn't need to let the users specify the margin on your website - Let them do it on their computer. Print dialogs usually (Adobe and Preview, at least) give you an option to scale and center the output on the printable area of the page:
Adobe
Preview
Of course, this assumes that you have computer literate users, which may or may not be the case.