From: NadCixelsyd on 1 Apr 2010 16:33 I'm using VB5. If I set FORM1.FONT = "Courier New" FORM1.FONTSIZE = 10 TEXT = "A" real_variable = FORM1.FONTSIZE PRINT real_variable, SCREEN.TwipsPerPixelX, SCREEN.TwipsPerPixelY, TextHeight(TEXT), TextWidth(TEXT) it prints 9.75 15 15 240 120 Why did it change my font size from 10 to 9.75. My hunch is that 10 points is 200 twips which is 13.333 pixels, whereas 9.75 points is 195 twips which is a exactly 13 pixels. In other words, regardless of the fontsize that I specify, VB will change it to the nearest(?) size such that it is an integral number of pixels. Like FONTSIZE, I assume that TextHeight and TextWidth are also always a intergral number of pixels (i.e. a multiple of 15 twips on my monitor) (in this case, 16 pixels high and 8 pixels wide). I tried an assortment of font sizes between 9 and 12. If I set fontsize between 9.00 and 9.34, VB resets it to 8.25 (which is 11 pixels high) If I set Fontsize between 9.35 and 11.62, VB resets it to 9.75 (which is 13 pixels high) If I set fontsize between 11.63 and 12,, VB resets it to 12.0 (which is 16 pixels high) Why doesn't it allow characters that are 12, 14, or 15 pixels high? With a font size of 9.75 (points?) and 20 twips per point (doesn't twip stand for "twentieth of a point"?), why is my TextHeight 240 twips? Shouldn't it be 195 twips (9.75 times 20)? If I use 195 twips for spacing, it looks a bit compressed, whereas if I use 240, it looks kinda sparse.
From: Mike Williams on 1 Apr 2010 17:54 "NadCixelsyd" <nadcixelsyd(a)aol.com> wrote in message news:df644288-5c3a-47c2-b0e7-144b54c6c2fc(a)x12g2000yqx.googlegroups.com... > [Re setting various font sizes] > it prints 9.75 15 15 240 120 > Why did it change my font size from 10 to 9.75. My hunch > is that 10 points is 200 twips which is 13.333 pixels, whereas > 9.75 points is 195 twips which is a exactly 13 pixels. In other > words, regardless of the fontsize that I specify, VB will change > it to the nearest(?) size such that it is an integral number of pixels Your hunch is correct, but it's not VB that does it. The GDI32 font functions (which of course VB uses) require that the point size of all fonts be an integer pixel value on the device to which you are printing them, regardless of any changes you might make to the DC. (Even if you mess about with the mapmode and viewport settings, which is not something you would normally do anyway, the value returned will be a whole unit of some other size but it will still represent the nearest it can give you to a whole device pixel value). Most TrueType fonts can take on most pixel sizes for their point size (although some of them have certain limitations so the only way to be totally sure of what you can get is to set a specific font to your requirement and then check the value you actually get). If your machine is running at the standard 96 dpi (15 twips per pixel) then 10 points comes to 13.333 pixels and so, as you have correctly assumed, for most trueType fonts the system will give you 13 pixels, which is the equivalent of 9.75 points. On another computer (or on the same computer) if it is running at the 120 dpi setting (12 twips per pixel) then 10 points comes to 16.67 pixels, and so on that machine you will get 17 pixels, which is 10.2 points. On a printer, if it is running at 600 dpi, 10 points comes to 83.33 pixels and so the system will give you 83 pixels, which is the equivalent of 9.96 points. > Like FONTSIZE, I assume that TextHeight and TextWidth are > also always a intergral number of pixels (i.e. a multiple of 15 > twips on my monitor) Yes. The same "whole pixel" limitation applies to them as well. > I tried an assortment of font sizes between 9 and 12. > If I set fontsize between 9.00 and 9.34, VB resets it to 8.25 > (which is 11 pixels high) > If I set Fontsize between 9.35 and 11.62, VB resets it to 9.75 > (which is 13 pixels high) > If I set fontsize between 11.63 and 12,, VB resets it to 12.0 > (which is 16 pixels high) > Why doesn't it allow characters that are 12, 14, or 15 pixels high? Actually it does allow more than the above pixel values, at least with most fonts. The values you are getting above are almost certainly those you will get from a typical screen bitmap font such as the default MS Sans Serif, which is not a trueType font. Bitmap fonts have much greater point size limitations than TrueType fonts, and the above values look okay on the assumption that you are using a bitmap font (perhaps MS Sans serif). However, if you change to using a trueType font you will see a definite difference. Try the following code for example, first setting the font to MS Sans Serif and then running it again with the font set to Arial or Times new Roman or Courier New or whatever: Private Sub Command1_Click() Font.Name = "MS Sans Serif" Dim n As Single, p As Single, p2 As Long For n = 8 To 14 Step 0.1 Font.Size = n p = Font.Size p2 = ScaleY(Font.Size, vbPoints, vbPixels) List1.AddItem Format(n, "0,00") & vbTab & p & vbTab & p2 Next n End Sub > With a font size of 9.75 (points?) and 20 twips per point > (doesn't twip stand for "twentieth of a point"?) . . Yes it does. There are 20 twips in one point and there are 72 points in one inch which means there are 1440 twips in one inch. > . . why is my TextHeight 240 twips? Shouldn't it be 195 twips > (9.75 times 20)? No. The point size is the nominal height of the font itself and the TextHeight is the overall height of the character cell in which it lives. It is of course a bit more complicated than that. If you would like to see more details then run the following code, which will give you a graphic representation of a font and its character cell, together with a little explanation. Paste the following code into a VB Form: Mike Option Explicit Private Declare Function GetTextMetrics Lib "gdi32" _ Alias "GetTextMetricsA" (ByVal hdc As Long, _ lpMetrics As TEXTMETRIC) As Long Private Type TEXTMETRIC tmHeight As Long tmAscent As Long tmDescent As Long tmInternalLeading As Long tmExternalLeading As Long tmAveCharWidth As Long tmMaxCharWidth As Long tmWeight As Long tmOverhang As Long tmDigitizedAspectX As Long tmDigitizedAspectY As Long tmFirstChar As Byte tmLastChar As Byte tmDefaultChar As Byte tmBreakChar As Byte tmItalic As Byte tmUnderlined As Byte tmStruckOut As Byte tmPitchAndFamily As Byte tmCharSet As Byte End Type Private Const DEFAULT_QUALITY As Byte = 0 Private Const DRAFT_QUALITY As Byte = 1 Private Const NONANTIALIASED_QUALITY As Byte = 3 Private Const ANTIALIASED_QUALITY As Byte = 4 Private Const CLEARTYPE_COMPAT_QUALITY As Byte = 5 Private Const CLEARTYPE_QUALITY As Byte = 6 Private Sub Form_Load() ' A graphical representation of the various ' Font details (by Mike Williams). Dim fName As String, fSize As Single Dim sampleText As String fName = "Times New Roman" fSize = 72 sampleText = "MjtplqdgfH0123" Dim mymetrics As TEXTMETRIC, savey As Single Dim InternalLeading As Single Dim Ascent As Single Dim Descent As Single Dim ExternalLeading As Single Dim txtHeight As Single Me.AutoRedraw = True Me.Show Me.BackColor = vbWhite Me.Width = Me.ScaleX(7.6, vbInches, vbTwips) Me.Height = Me.ScaleY(5.7, vbInches, vbTwips) Me.Line (0, 0)-(Me.ScaleWidth, Me.ScaleHeight), _ RGB(200, 100, 255), BF Me.ScaleMode = vbPoints Me.Font.Name = fName Me.Font.Size = fSize ' 72 points = 1 inch Me.Font.Italic = False Me.Font.Bold = False txtHeight = Me.TextHeight("some text") GetTextMetrics Me.hdc, mymetrics InternalLeading = Me.ScaleY(mymetrics.tmInternalLeading, _ vbPixels, Me.ScaleMode) Ascent = Me.ScaleY(mymetrics.tmAscent, _ vbPixels, Me.ScaleMode) Descent = Me.ScaleY(mymetrics.tmDescent, _ vbPixels, Me.ScaleMode) ExternalLeading = Me.ScaleY(mymetrics.tmExternalLeading, _ vbPixels, Me.ScaleMode) Me.CurrentX = 0: Me.CurrentY = 0 Me.FontTransparent = True Me.Print sampleText Me.FontTransparent = False Me.Print sampleText savey = Me.CurrentY Me.Line (0, InternalLeading)- _ (Me.ScaleWidth, InternalLeading), vbYellow Me.Line (0, Ascent)- _ (Me.ScaleWidth, Ascent), vbGreen Me.Line (0, Ascent + Descent)- _ (Me.ScaleWidth, Ascent + Descent), vbBlue If mymetrics.tmExternalLeading > 0 Then Me.Line (0, Ascent + Descent + ExternalLeading)- _ (Me.ScaleWidth, Ascent + Descent + ExternalLeading), vbRed End If ' Capital letters (A - Z) and numbers (0 - 9)in most fonts ' start a little after the External Leading and extend down ' to the Ascent line, and the centre of those characters is ' usually about 0.48 of the overall "TextHeight" down from ' the top of the character cell. The following code will ' therefore draw a line approximately through the centre ' of these characters on most (but not all) fonts. Me.Line (0, txtHeight * 0.48)- _ (Me.ScaleWidth, txtHeight * 0.48), vbWhite Me.CurrentX = 0 Me.CurrentY = savey Me.Font.Name = "Arial" Me.Font.Size = 8 Me.Print " The example text is " & fName & " " _ & Format(fSize, "0.0") & " points" Me.Print " Internal Leading = " & InternalLeading & " points" Me.Print " Ascent = " & Ascent & " points" Me.Print " Descent = " & Descent & " points" Me.Print " External Leading = " & ExternalLeading & " points" Me.Print " Total Height (Ascent + Descent) = " _ & Ascent + Descent & " points" Me.Print " VB TextHeight returns " & txtHeight & " points" Me.Print " The point size is the Ascent plus the Descent"; Me.Print " minus the Internal Leading = "; Me.Print Ascent + Descent - InternalLeading Me.FontTransparent = True Me.Print Me.Print " Internal Leading is from the top down to the"; Me.Print " yellow line." Me.Print " Ascent is from the top down to the green line"; Me.Print " (called the Baseline)"; Me.Print " and it includes the Internal Leading." Me.Print " Descent is from the green line down to the blue"; Me.Print " line." Me.Print " The overall height is equal to Ascent plus"; Me.Print " Descent and is equal to the VB TextHeight." Me.Print " The point size is from the yellow line down to"; Me.Print " the blue line and is equal to Ascent plus Descent"; Me.Print " minus Internal Leading." If mymetrics.tmExternalLeading > 0 Then Me.Print " The External Leading is from the blue line to"; Me.Print " the red line and is ignored." Else Me.Print " This font has zero external leading." End If Me.Print " The white line is typically 0.48 of the TextHeight"; Me.Print " down from the top and runs approximately through the "; Me.Print " centre of capital letters and numerals." Me.Print " NOTE: If you use a negative value (normal practice)"; Me.Print " for the desired font size when using the "; Me.Print " CreateFontIndirect API the system will attempt" Me.Print " to give you a font where the distance from the yellow"; Me.Print " line to the blue line is equal to the requested value. "; Me.Print " If you use a positive value the" Me.Print " system will attempt to give you a font where the overall"; Me.Print " height is equal to the requested value. In both cases"; Me.Print " however all of the above elements " Me.Print " will be present. (Using a positive value is effectively "; Me.Print " the same as asking for a slightly smaller font.)" End Sub
|
Pages: 1 Prev: SendKeys/MySendKeys (Karl) Next: Convert UTF-16 Unicode to UTF-8 Unicode? |