From: Mike Williams on 28 Mar 2010 12:45 "sven2000" <sven2000(a)gmail.com> wrote in message news:483a013e-4cac-42e8-b592-77c3e11f7898(a)k13g2000yqe.googlegroups.com... > I've noticed this for Symath. > Except from that, the textheight in VB is always the same. > Form1.Print "x" > Form1.Print Form1.TextWidth("x") & " " & Form1.TextHeight("x") > Form1.Print "X" > Form1.Print Form1.TextWidth("X") & " " & Form1.TextHeight("X") The TextHeight of a font of any specific size and type is the sum of its Ascent and Descent (or the overall height of a character cell or the distance from the top of one line of text to the top of the next line in a normally printed block of text if you prefer to look at it in either of those ways). It is the same for all characters in the font, so the character "x" and the character"X" and the character "." all have the same TextHeight (except that the VB TextHeight function, as opposed to the GDI32 GettextExtentPoint32 function, assumes that any string containing a line feed or a carriage consists of two or more printed lines and so VB TextHeight returns two or three or more times the normal value for any string containing either of those characters). So, the characters "X" and "x" and "." all have the same TextHeight. It is their TextWidths that are different (in a proportionaly spaced font, which most fonts are). If you instead want to get the height of the actual "drawn part" of a specific character, and its placement within the character cell (which of course is different for different characters) then you can use the GetGlyphOutline function, although that is not necessary for most jobs. Regarding the Ascent and Descent and various other things and how they relate to the overall TextHeight here is some code that produces a more graphical explanation of it (paste it 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
From: Jeff Johnson on 29 Mar 2010 16:52 "Mike Williams" <Mike(a)WhiskyAndCoke.com> wrote in message news:OIiWmLlzKHA.3884(a)TK2MSFTNGP06.phx.gbl... > It seems that the Cambria Math font has recently acquired an extremely > large Ascent and Descent. Has it perhaps always been that way and I've > never noticed it before, or is it something recent, perhaps a Vista thing? I wrote an owner-draw combo box in...well, let's just say "another language"...to draw each font name in its own font and I ran into exactly the same thing you're seeing. XP SP2.
From: sven2000 on 7 Apr 2010 16:56 Thanks Mike, that's very helpful. Two questions, though. As it says the ascent includes the internal leading. This is not true normally in font metrics, right? And there's a white center line, but there's no x-height?
From: Mike Williams on 7 Apr 2010 19:35 "sven2000" <sven2000(a)gmail.com> wrote in message news:72a6c676-4657-4ac3-912e-6249b344f500(a)30g2000yqi.googlegroups.com... > Thanks Mike, that's very helpful. > Two questions, though. As it says the ascent includes the > internal leading. This is not true normally in font metrics, > right? In the TextMetric structure the tmAscent is from the base line to the top and the tmDescent is from the base line to the bottom. The total of these two is the tmHeight, which is the total height and which is the same as would, for example, be returned by the VB TextHeight function. The tmInternalLeading is measured from the top and is contained within the overall Height (usually quite small and almost always entirely within the Ascent portion). In most fonts that I've seen it usually extends down to just above the top edge of the capital letters. http://msdn.microsoft.com/en-us/library/dd145132(VS.85).aspx > And there's a white center line, but there's no x-height? The TEXTMETRIC structure (used by the GetTextMetrics function) does not include an entry for the x-height. There is an x-height entry in the more detailed OUTLINETEXTMETRIC structure (as used by the GetOutlineTextMetric function) but according to the MS docs the x-height entry is not supported. If you want to get an idea of the x-height then you could use the GetGlyphOutline function which can tell you the size and position within the cell of the "black box" that exactly fits over the shape of the glyph of any character you pass to it. However, having said that, I think that there are some fonts where, as odd as it seems, the character "x" is not actually the same height as the x-height of the font. I'm pretty sure that GDI+ can tell you the x-height of most fonts, and also other things such as the CapsHeight etc, but I don't "do" GDI+ so I can't help you on that one. Mike
From: Mike Williams on 9 Apr 2010 11:46 "sven2000" <sven2000(a)gmail.com> wrote in message news:72a6c676-4657-4ac3-912e-6249b344f500(a)30g2000yqi.googlegroups.com... > Thanks Mike, that's very helpful. > Two questions, though. As it says the ascent includes > the internal leading. This is not true normally in font > metrics, right? Further to my previous reponse to this question, I've just realised what you actually meant by it. In my previous response I assumed that you were asking me to confirm, or that you were querying, what I had said in my earlier messages regarding GDI32, and so when I answered it I reaffirmed that the Internal Leading as far as the GDI GetTextMetrics function is concerned is included in the Ascent and actually forms a part of it, which is in fact the case as is shown in the example code I had earlier posted which gives a graphical repesentation of the information returned by the GDI32 GetTextMetrics function. However, I've just realised that you had actually accepted that point but that you were saying the inclusion of the Internal Leading within the Ascent is not normally the practise generally in font metrics, rather than specifically in Windows GDI. In that case you are of course correct because (as far as I know) most systems other than Windows GDI which deal with fonts do no treat them in that manner, and the various "leadings" are /not/ considered to be part of either the Ascent or the Descent of a font, which makes sense of course because the "leadings" actually were lumps of lead back in the old days, although in recent years people seem to be moving away from the "leading" term and using other names for it. Certainly the people at Apple do not see any Leading as being part of the Ascent, and neither do most people, I would suspect. So, you're right in that respect, and Windows (at least Windows GDI32) is the "odd one out" (and it would appear that GDI+ and .Nxt are "the odd one out" as well, as mentioned below. It seems to be a general "MS Windows" thing). Whether Micro$oft intended it that way, or whether it was just something which came about purely because of the fact that no one person is really in charge of anything at Micro$oft, is anybody's guess! It's not always easy to find really detailed information about stuff like that on MSDN, and when you do find it you often find that one piece of information entirely contradicts another, even on the same page! Micro$oft have never been any good at writing help files or documentation in a way that is really helpful, and they are often either so incomplete, or sometimes so "overly complete" in some respects and "incomplete" in other respects, that they are worse than useless! I've just had a look for some information on MSDN to see what I can find regarding Ascent and Descent and Leading etc (and how it is seen by Micro$oft) and to see whether it has changed since GDI32, but (as usual) I came away more confused than I was when I went there! The reason, as usual, is that the MSDN page I found contains conflicting information! http://msdn.microsoft.com/en-us/library/ms533824(v=VS.85).aspx Like most Micro$oft things these days, it deals with GDI+ rather thanGDI32 (although that of course is specifically what I was looking for) and the examples are in .Nxt so I cannot (or rather I am not prepared to!) try them for myself. If you look at the nice little drawings at the top of the page (the drawings of the letter Q) you will see quite clearly that /in the drawings/ the Ascent and Descent together form the font size, and they do /not/ inlcude any form of leading (either internal or external). So, judging solely by the labelled drawings it looks as though Micro$oft have had a change of heart and have moved to comply with Apple and most other people in this respect . .. .. . However, if you look at the output from the Micro$oft example .Nxt code on the very same page (which uses GDI+ stuff and the output of which is shown below the code) you will see a different story. Font sizes are normally expressed in pixels (rather than points) in .Nxt and also GDI+ allows floating point values when dealing with them, so there are some differences but it is easy to account for them. In the example they have used a 16 pixel Arial font and the output shows the font size as being 16.00 pixels, the Ascent as being 14.48 pixels and the Descent as being 3.39 pixels. So, the total of the values returned for the Ascent and Descent is 18.19 pixels, 2.19 pixels greater than the font size, and between them they clearly include the "leading" (totally contrary to the labelled drawing of the letter Q at the top of the page!). In fact, if you do a bit of peddling around in VB6 using very large font sizes to compensate for the fact that we cannot use floating point values with GDI32 font stuff you will see that for the Arial font the typical Internal Leading is 0.12 times the font size (when both are expressed in the same units). So, for a typical 16.00 pixel Arial font we would expect the Internal Leading to be 1.92 pixels, giving a total of 17.92 pixels. Therefore, the total of Ascent and Descent returned by the .Nxt GDI+ code (18.19 pixels) clearly includes /all/ of the expected value for Internal Leading. In fact it might even include the External Leading as well, which is a much smaller amount and which is ignored in VB6 and GDI32. Naturally you need to make allowances for the differences between the two systems and for the fact that the font stuff in GDI+ uses floating point values whereas GDI32 does not, but it is quite clear that the drawing at the top of that MSDN page shows that the Internal Leading (or any other kind of leading) is NOT included in the Ascent and Descent, whereas the actual .Nxt code on the very same MSDN page and the GDI+ results it returns clearly shows quite the opposite! Typical Micro$oft stuff, that ;-) Here (below) is a "rough and ready" modification of the code I posted previously which I have changed to use pixels throughout instead of points and which displays the VB6 (GDI32) details of a 160 pixel Arial font. You should be able to compare the output of it with the output of the GDI+ 16 pixel Arial font .Nxt code shown on the MSDN page and you'll see what I mean (the outputs of the code below should of course be divided by 10 in your head to make the comparison . . I've avoided doing the "divide by ten" in code so as to make it obvious that it is pulling in the correct results). Whoever made and labelled the drawings of the font characters on that MSDN page clearly knows what the Ascent and Descent of a font SHOULD be, but he then appears to have totally ignored the output of the code he included on the same MSDN page, which clearly shows that Windows thinks quite the opposite! 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, pixelSize As Single, y As Single Dim sampleText As String fName = "Arial" Me.ScaleMode = vbPixels Me.Font.Name = fName ' set font size to 160 pixels (not points) pixelSize = 160 ' set point size so as to achieve a 160 pixel font Me.Font.Size = Me.ScaleY(pixelSize, vbPixels, vbPoints) Me.Font.Italic = False Me.Font.Bold = False sampleText = "QtjM" 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(900, vbPixels, vbTwips) Me.Height = Me.ScaleY(680, vbPixels, vbTwips) Me.Line (0, 0)-(Me.ScaleWidth, Me.ScaleHeight), _ RGB(200, 100, 255), BF txtHeight = Me.TextHeight("some text") GetTextMetrics Me.hdc, mymetrics InternalLeading = mymetrics.tmInternalLeading Ascent = mymetrics.tmAscent Descent = mymetrics.tmDescent ExternalLeading = mymetrics.tmExternalLeading Me.CurrentX = 0: Me.CurrentY = 0 Me.FontTransparent = True Me.Print sampleText; y = Me.TextHeight("x") Me.Font.Name = "Times New Roman" Me.Print " " & sampleText; Me.CurrentY = Me.CurrentY + y Me.CurrentX = 0 Me.Font.Name = "Arial" Me.FontTransparent = False Me.Print sampleText; Me.Font.Name = "Times New Roman" Me.Print " " & sampleText; Me.CurrentY = Me.CurrentY + y 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 following details are for Arial " _ & Format(pixelSize) & " pixels (The Times New Roman is also displayed purely so you can compare the Q glyph)" Me.Print " Internal Leading = " & InternalLeading & " pixels" Me.Print " Ascent = " & Ascent & " pixels" Me.Print " Descent = " & Descent & " pixels" Me.Print " External Leading = " & ExternalLeading & " pixels" Me.Print " Total Height (Ascent + Descent) = " _ & Ascent + Descent & " pixels" Me.Print " VB TextHeight returns " & txtHeight & " pixels" Me.Print " The font size is the Ascent plus the Descent"; Me.Print " minus the Internal Leading = "; Me.Print Ascent + Descent - InternalLeading & " pixels" 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
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: Read and Parse Emails using VB Next: Normal.dot keeps bugging me!! |