Re: Rotated Text Help Needed
- From: "BeastFish" <beastfish@xxxxxxxxxxxxxxxxx>
- Date: Fri, 7 Oct 2005 17:00:29 -0400
Mike,
I gave it a go on my Win98SE drive. Looks fine, no discrepancies with the
cell heights as you said happened on your XP. I tried it outputting to the
printer with VB5. If I get a chance later today, I'll swap drives and give
it a go with VB6.
"Mike Williams" <Mike@xxxxxxxxxxxxxxxxx> wrote in message
news:di3sfd$v6l$1@xxxxxxxxxxxxxxxxxxxxxx
> Hi everyone
>
> I've got a little query about rotated fonts that I've never noticed before
> and I hope that some of you may be able to help me with it. Actually, I
> think it might be just WinXP that has the problem and not Win98, but I
can't
> check my Win98 machine at the moment. It's a bit of a "long winded"
> explanation, but I hope you'll bear with me and check it out for me.
Anyway,
> here goes . . .
>
> Earlier today I was writing some code that I intended to post in response
to
> a recent newsgroup question. The code is a simple example of how to
produce
> text that "wraps around a circle" on a printer (although the same
principle,
> and the same problem, also occurs when drawing it to the screen). I
haven't
> yet bothered about aligning the characters so that they "centralise
> themselves" against the desired point on the circumference, or so that
they
> position the "glyph" rather than the character cell at the desired
position
> (although I will do later) and so the example currently positions the
> characters such that the top left corner of the character cell sits at the
> desired position. Anyway, here's the problem . . .
>
> Paste the following code into a standard VB Form containing a command
button
> and then run the project and click the button (make sure you are using an
A4
> or a US Letter or similar size paper in your printer). As you will see,
the
> code draws the individual characters of a text string in a circle, with
each
> character being spaced out by exactly the same amount from the previous
> character. It also draws a light grey background rectangle so that you can
> see what is going on and it draws a very small circle at each of the
> calculated positions around the circumference. At each of those positions
it
> draws a character from the string, such that the top left corner of each
> character cell is positioned at its appropriate point. Additionally, I
have
> deliberately set the font transparency to False, so that you can see the
> character cell as well as the character glyph itself. Okay, so far so
good.
>
> Now look carefully at each of the characters. You will (I hope) see that
all
> of the character cells have exactly the same "cell height" (as you would
of
> course expect) *except for* the characters that are positioned such that
> their rotation is an exact multiple of 90 degrees (top, bottom, left and
> right). On my own WinXP machine those four character cells are smaller in
> height than the others, by an amount which is significant! The character
> "glyph" itself is the same height (that is the height of the actual
> character glyph is the same height as other similar character glyphs in
> different positions) but the height of the "character cell" itself is
quite
> different (quite a bit smaller). This means that since the top left corner
> of the "character cell" is positioned where it should be, and since the
> glyph in each case sits more or less centrally within the cell, the glyph
> itself ends up in the wrong position, making it look a bit odd when
compared
> to the others. Not quite in a circle. Now I know that there are various
ways
> to code around this, but I don't want to do that until (or unless) I know
> that it is a problem which occurs on all machines (or at least on all
> machines running the same version of Windows). On a "clock face" generator
> that I once wrote the same problem must have existed, but I didn't realise
> it because I had included code which moved the character pixel by pixel
(in
> a hidden picture box) until the glyph itself touched the circle, and so
the
> clock printed out exactly and I didn't realise that the problem even
> existed.
>
> On my WinXP machine, if you look at the printed output you can see that
the
> "I", "T", "O" and "Space" that sit at each of the four "exact multiple of
90
> degree" positions are not quite where they should be. The top left corner
of
> the character cell is exactly positioned, but the fact that the cell is
> slightly less high means that the glyph is not.
>
> Having carried out a quick check (using much larger font sizes) I can see
> that in general "rotated fonts" have slightly different cell heights and
> glyph heights than character which are printed normally (without using the
> CreatFontIndirect API), but that in general these differences are
consistent
> and so are not a problem. However, the "exact multiple of 90 degree"
rotated
> fonts are something different, and they have neither a cell height or a
> glyph height that is the same as either a standard printed font or a
> "rotated font that is not at an exact multiple of 90 degrees". Puzzling.
>
> Sorry for the long posting, but I really would appreciate it if you could
> run the following code for me and tell me what result you get (examine the
> printed output very carefully). Also, I would be grateful if you could
tell
> me which version of Windows you are using.
>
> By the way, yoy may find that the first time you click the button you get
a
> page showing the large circle and the small little position circles and
the
> text itself (without the grey background rectangle so that you cannot see
> the white character cells around each character). If that happens then
click
> the button again and you should get the output I intended. (Now I remember
> why I decided a while ago to ditch the VB printer object and instead to
use
> the API printer functions for all my printing needs!)
>
> Anyway, here's the code. Please examine the printed output carefully and
> tell me in detail what you see. Sorry for being a bit "pushy", bit I
really
> would appreciate an early response :-)
>
> Mike
>
>
> Option Explicit
> Private Const LF_FACESIZE = 32
> Private Type LOGFONT
> lfHeight As Long
> lfWidth As Long
> lfEscapement As Long
> lfOrientation As Long
> lfWeight As Long
> lfItalic As Byte
> lfUnderline As Byte
> lfStrikeOut As Byte
> lfCharSet As Byte
> lfOutPrecision As Byte
> lfClipPrecision As Byte
> lfQuality As Byte
> lfPitchAndFamily As Byte
> lfFaceName As String * LF_FACESIZE
> End Type
> Private Declare Function CreateFontIndirect Lib "gdi32" _
> Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long
> Private Declare Function SelectObject Lib "gdi32" _
> (ByVal hdc As Long, ByVal hObject As Long) As Long
> Private Declare Function DeleteObject Lib "gdi32" _
> (ByVal hObject As Long) As Long
> Private Declare Function TextOut Lib "gdi32" Alias _
> "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal _
> y As Long, ByVal lpString As String, ByVal nCount _
> As Long) As Long
> Private Declare Function SetBkMode Lib "gdi32" _
> (ByVal hdc As Long, ByVal nBkMode As Long) As Long
> Private Const TRANSPARENT = 1
> Private Const OPAQUE = 2
> Private Const RadToTenthDegree As Single = 572.957795
> Private Const pi = 3.14159
> Private myhDC As Long
> Private new_font As Long, old_font As Long
>
> Private Sub RotateFont(outDevice As Object, angle As Single)
> Dim myAngle As Long
> myhDC = outDevice.hdc
> myAngle = angle * RadToTenthDegree ' convert from radians
> Dim log_font As LOGFONT
> With log_font
> .lfEscapement = myAngle
> .lfHeight = outDevice.ScaleY(outDevice.Font.Size * 20, vbTwips, vbPixels)
> .lfFaceName = outDevice.Font.Name & vbNullChar
> If outDevice.Font.Bold = True Then
> .lfWeight = 700
> Else
> .lfWeight = 400
> End If
> .lfItalic = outDevice.Font.Italic
> .lfUnderline = outDevice.Font.Underline
> End With
> new_font = CreateFontIndirect(log_font)
> old_font = SelectObject(myhDC, new_font)
> End Sub
>
> Private Sub CircleText(obj As Object, x1 As Single, y1 As Single, r1 As
> Single, s1 As String)
> ' add code later to check for valid object type
> Dim angle As Single, p As Long, n As Long
> Dim xp As Single, yp As Single, position As Single
> Dim myhDC As Long, ret As Long
> obj.ScaleMode = vbInches
> p = Len(s1)
> angle = (2 * pi) / p
> position = pi / 2
> myhDC = obj.hdc
> For n = 0 To p - 1
> xp = x1 - (r1 * Sin(position))
> yp = y1 - (r1 * Cos(position))
> ' hyp = Sqr(testradius * testradius + (xd / 2) * (xd / 2))
> ' tempangle = ArcSin((xd / 2) / hyp)
> ' tempangle = tempangle + angle
>
> ' (more stuff goes in here later)
>
> xp = obj.ScaleX(xp, vbInches, vbPixels)
> yp = obj.ScaleY(yp, vbInches, vbPixels)
> RotateFont obj, position
> ret = TextOut(myhDC, xp, yp, Mid$(s1, n + 1, 1), 1)
> ' change the font back and get rid of the new font
> SelectObject myhDC, old_font
> DeleteObject new_font
> ' draw a small circle at each position for test purposes
> Printer.ScaleMode = vbPixels
> Printer.Circle (xp, yp), 12
> Printer.ScaleMode = vbInches
> position = position - angle
> Next n
> End Sub
>
> Private Sub Command1_Click()
> Printer.Print
> Printer.Font.Name = "Arial"
> Printer.Font.Size = 32
> ' set to FontTransparent = False just for test purposes so
> ' that we can see the actual top left corner of each
> ' character block (note we use SetBkMode instead of using
> ' the Printer.FontTransparent property becase the
> ' FontTransparent property has some odd behaviour when
> ' printing rotated text characters)
> SetBkMode Printer.hdc, OPAQUE
> Printer.ForeColor = vbBlack
> ' draw a light grey rectangle just for test purposes
> Printer.FillStyle = vbFSSolid
> Printer.Line (0, 0)-(8, 8), RGB(128, 128, 128), BF
> Printer.FillStyle = vbFSTransparent
> Dim s1 As String
> s1 = "IS THIS TEXT PRINTED CORRECTLY OR IS IT NOT "
> CircleText Printer, 4, 4, 3.8, s1
> ' draw a bounding circle just for test purposes
> Printer.Circle (4, 4), 3.8
> ' draw a regular character just for test purposes
> Printer.CurrentX = 0: Printer.CurrentY = 0
> Printer.Print "I"
> Printer.EndDoc
> End Sub
>
>
>
>
.
- Follow-Ups:
- Re: Rotated Text Help Needed
- From: Mike Williams
- Re: Rotated Text Help Needed
- References:
- Rotated Text Help Needed
- From: Mike Williams
- Rotated Text Help Needed
- Prev by Date: Re: Rotated Text Help Needed
- Next by Date: Re: Checking CRC?? [URJENT!!]
- Previous by thread: Re: Rotated Text Help Needed
- Next by thread: Re: Rotated Text Help Needed
- Index(es):