As of October, 2016, Embarcadero is offering a free release
of Delphi (Delphi
10.1 Berlin Starter Edition ). There
are a few restrictions, but it is a welcome step toward making
more programmers aware of the joys of Delphi. They do say
"Offer may be withdrawn at any time", so don't delay if you want
to check it out. Please use the
link to let me know if the link stops working.
Support DFF - Shop
If you shop at Amazon anyway, consider using
this link. We receive a few cents from each purchase.
Support DFF - Donate
If you benefit from the website, in terms of
knowledge, entertainment value, or something otherwise useful,
consider making a donation via PayPal to help defray the
costs. (No PayPal account necessary to donate via credit
card.) Transaction is secure.
e-mail with your comments about this program (or anything else).
Mirror text, Or Both?
The original version of this program dealt with text that had been rotated
about its "Z" axis, as if a sheet of paper lying on the table had
been rotated 180° flat. The discussion below applies to
that case. A recent exploration of mirrored text led to a second
program using an entirely different way of inverting, and a lot
better understanding of rotations. This program is described in an addendum
at the bottom of this page. Program TestMirroredText2 is contained in the download
Most of the items here in Delphi_Techniques
were written to solve some sub-problem of another program I was working
on. "Divide and conquer" is
my normal mode of problem solving. In this case I wanted to print solutions upside-down at the
bottom of the page when the user requested a printout of a "Scrambled
Pie" puzzle. Here's the code that solves that
"sub-problem". As usual, there were a few unexpected twists and
turns along the way (sub-sub-problems?).
|The trick to rotating text is to modify a font field known as
"escapement" which specifies the angle for a text string in
tenths of a degree. This is accomplished in an InitInvertedText
|InitInvertedtext has one more job - to determine the line spacing
for the current font. By trial and error, I arrived at using the sum
of two text metric fields (tmHeight and tmExternalLeading)
obtained by calling the GettextMetrics Windows API function. |
|DrawInvertedText is the procedure which draws strings on a
specified canvas on a specified line relative to the bottom right corner of
the page. This becomes, of course, the top-left corner when you turn
the page (or your monitor) upside down. |
|Not all fonts can be rotated - documentation says only TrueType fonts are eligible.
Again by trial and error, I found that some others may be rotated; some
produce weird results. I added a font selection dialog to the
main form so you can play with font characteristics and see the result.|
|Another of the twists discovered in writing this, is Delphi's
insertion of Carriage Return/Linefeed (CR/LF) pairs into text entered into
the Tmemo Lines property at design time.
These hard breaks cause terrible looking output if font characteristics or
display area sizes are changed at run time. My fix for that is a MemoFixUp
procedure which removes all CR/LF pairs unless two consecutive pairs are
found. So if you hit enter twice while entering text at design time, a
blank line will result. This make a good visual paragraph separator
which MemoFixUp will honor.|
|I moved the three procedures described above into a separate unit, U_InvertedText,
to simplify their use in other programs. They are called
from the main form unit U_TextInvertedText.|
|Finally, there are some problems unique to printing. Because the
resolution of printers is typically much higher than monitor displays,
merely stretching the monitor image to fit the page is not generally
adequate. The best solution is simply to recreate the display on the
printers canvas in the same manner as it was created originally. The Windows
code that generates characters is smart enough to check the resolution of
the output devices and adjust the character sizes appropriately to maintain
fairly uniform visual appearance. |
OK, I'm off to work on the next sub-problem: how to display the letters
of a text string at random locations within a specified quadrant of a given
circle, without overlap. That should be fun!.
Addendum April 15, 2005: A fellow wrote the
other day asking about "mirrored" text for a teleprompter application
he was working on. I started out to modify inverted text program but ended
up with an entirely new application. The TestMirroredText program
described here creatres mirrored, inverted, or mirrored-inverted text. It uses TCanvas Copyrect procedure to copy text from
one canvas to another. It turns out that Copyrect is smart enough
to handle cases where the left and right (or top & bottom) coordinates are
reversed. the result is a fast way to flip or mirror an image. Since
TMemo does not have a Canvas property, I copy the text to a temporary
bitmap and then perform the transform copying that bitmap canvas to its final
location (display Canvas or Printer Canvas). I discovered a few more
tricks about setting margins and re-justifying text in a TMemo along the
way. You can pick them up from the
Addendum April 22, 2005: I added variable speed auto-scrolling
to the program this week - one step closer to a real
teleprompter application. Resizing of the form is now also
supported. So the program now has examples of a number of potentially useful
Tmemo text on initial entry to remove hard line breaks inserted by Delphi
a design time.
and/or vertical flipping of Tmemo text to a separate image.
images when form size changes..
auto-scrolling of Tmemo and TImage text.
Addendum January 23, 2006: A teacher from England
recently asked if it would be possible to maximize the transformed text to full
screen to allow it's use as a simple teleprompter. I've never seen a
real teleprompter, but here Version 2, my cut at what one might look like.
Here are the changes
||Added a Maximize
button which opens the transformed text in a new full screen window.
When the window is showing, left/right mouse buttons (or down./up arrow
keys) control scrolling speed and direction. the
Escape key, "Esc", closes the maximized window.
||Added a Load
text button to allow a text file to be loaded. With the current
implementation, size is limited to about 32,000 characters.
introductory text size brought to light to need to sense end-of-page when
printing and start a new page.
Note for programmers: The internal formatting uses a couple of
procedures from a utility unit (DFFUtils) which was included in the
previous zipped source file. If you want to recompile the
program, DFFUtils is now part of a zipped DFF Library file
which contains a number of units used to multiple program here at
DFF. The idea is that I can implement future enhancements or
fixes without tracking and reposting lots of program source
files. See this
link for more information.
Addendum March23, 2006: I had a request some time ago
to allow users to set the background color but it fell through the
cracks. Apparently real teleprompters commonly display white
text on a black background. Font color could always be set to
white here but white on white is hard to read! Background can
now be set to any desired color.
TestInverted_MirroredText Source (requires DFF Library
DFFLIBV04 or later to compile)
Download latest DFF Library, (
|Created: April 1, 2004
February 18, 2016