Display/Print Inverted Text

[Home]   [Puzzles & Projects]    [Delphi Techniques]   [Math Topics]   [Library]   [Utilities]

 

Search

 

Search DelphiForFun.org only

Support DFF

 If you shop at Amazon anyway,  consider using this link. We receive a few cents from each purchase.   Thanks.

In Association with Amazon.com

 

Support DFF

 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.

 

 

Contact

Feedback:  Send an e-mail with your comments about this program (or anything else).

 

Search DelphiForFun.org only

 

 

 

 

 

 Inverted Text,     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 link below.         

 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?).

bulletThe 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 procedure.  
bulletInitInvertedtext 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. 
bulletDrawInvertedText 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.  
bulletNot 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.
bulletAnother 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.
bulletI 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.
bulletFinally, 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 code.   

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 operations:

Setting TMemo margins
Reformatting Tmemo text on initial entry to remove hard line breaks inserted by Delphi a design time.
Horizontal and/or vertical flipping of Tmemo text to a separate image.
Resizing images when form size changes..
Synchronized 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.
The longer 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. 

Download  TestInverted_MirroredText Source  (requires DFF Library DFFLIBV04 or later to compile)

Download latest DFF Library, ( DFFLibV14_24Mar2014 )

Download TestInverted_MirroredText executable

 
Created: April 1, 2004

Modified: May 18, 2009

      

      

  [Feedback]   [Newsletters (subscribe/view)] [About me]
Copyright 2000-2013, Gary Darby    All rights reserved.