Link to home
Start Free TrialLog in
Avatar of jm verdi
jm verdiFlag for France

asked on

New thread: print mirrored text (horiz. flip)

Hi all;
I create this new thread because the old was so big that i had time to smoke one cigarette before i load it entirely to see the incoming comments.
The deal is always:
A part of a a program that i write consist in printing text to a Laser HP5 with horizontal flipping (so the text is printed in mirrored way).
I can't use mirrored fonts, because my customer will have the ability to change these fonts later.
The report consist in a few hundred pages, at the A4 format, and each page has a lot of text ( i would say : about 3 columns of 100 lines each (it's a medium value)
Many softwares can do that, like QuarkXpress, Corel Ventura,.. but i can't use it: my program must do all the stuff.
A few ptinter can do this directly: my Epson Stylus prints at 1440 dpi and i can check a box which prints 'mirrored': but my customer will have the ability to print from quite any printer.
At the beginning, i thought that some component could exist, which can do this: a sort of special Component_Report. But perhaps not ?

The amount of points will be upgraded to 1000 points after the forum re-credit me the points of tghe old thread.

Jean marie Verdi
Avatar of ZifNab
ZifNab

Hello jm!

Ok in last example : ARect and ACanvas has to be switched.

Regards, Zif.
I seem to remember seen a API call called DrawMirrorImage, or something along
those lines.....

hang on I have it up here now....

It works like so...

DrawMirrorImage works in five steps:

              1.       Creates a duplicate HPENDATA of the input data.
      2.      Calls TrimPenData to remove unneeded information from the block.
      3.      Converts the new HPENDATA block to a mirror image.
      4.      Displays the mirror image by calling DrawPenDataFmt.
      5.      Deletes the mirror image HPENDATA block.

Hope this helps, let me now by comment etc.

Later

BoRiS
Hi JM, I got some interesting news! But before I'm going to try it out I want to ask you if you like it this way... Ok, here are some possibilities ....

I browsed on the net and found this :
1. A descendant of TImage, which can flip.... etc images! But it's shareware ....
(about 29$, you can find it at ascu.union.it/~milani/delphi)
2. A TBitmap that can flip, mirror, ... bitmap images... It's freeware, BUT maybe we have the same problem as we have with our BIG bitmaps....
(you can find it at delphi.lehner.at/fancyimg.zip)
3. A component, freeware, which converts TTF to Polylines .... We can convert any TTF to a drawing and draw this font on a metafile!!! and mirror the metafile.... because this works (mirroring drawings on a metafile).... and we can use BIG metafiles....

So what do you want to do? Use a shareware component (first we've to test it!!), test the freeware (although I don't have much hope with this one, our mirrored bitmaps have memory problems...) or use that last component (only TTF) .... Or keep looking for another solution.... What are the results of the last test? I keep helping you with any solution you choose.

Regards, Zif.
Avatar of jm verdi

ASKER

Hi ZifNab,

Last test: i got an error too with  Arect and Acannvas switched; this time this is: Types incimpatibles: TGraphic & TCanvas.

About the others ways: i am afraid of the two first: TImage or TBitMap (with the problem of the size) but i will download this two components and test it.
About the Third proposition: it seems very interesting: i'm just afraid of the conversion: do you think thaht the result (polylines) will be beautiful ? Is it not a 'a peu près' conversion? something with angles ?
We can make a try (just see the conversion, and print it, and compare it to the real TTF) If it works for the few sizes i will use, then we can make the mirror.
In case of changing the font, do you think that this conversion can be 'dynamic' during runtime ?

I go to the sites to download and test the two first components;
you do'nt mention the site of the third ?

Soon
JMVerdi



Hi Boris,

Thanks for your comment, but yoiu have to consider that i am new in Delphi (and API concerning Image management): do you have some sample that i can test ?
Something like: I write 'Hello World' at a certain location, and the result of printing is mirrored text at mirrored position ?
Thanks
Jean marie Verdi
Hi all,
I have checked the Win32 API about DrawMirrorImage. This function only mirrors the pen, not the actual drawing path itself.
Mirroring the desired font on runtime was a point I was working on, too. The conversion to polylines will not affect quality. The same thing is done in e.g. Quark Xpress, CorelDraw (Text to curves) etc. It is quite easy to find out if it is a true type, raster or vector font. Fonts other than true type can be mirrored more easily.
Zif, have you already taken a look at that font component ? I don't know yet how to draw these polylines into a DC.

Slash/d003303
Hi all,

I have tested the two components (free & share ware) and it seems that they don't support the Canvas property. They work when they load Bitmap pictures, and mirroring is good, but i got error when i want to Canvas.TextOut something with it. (error at runtime ?)
I'm happy to read that conversion don't affect quality; do ypou think you (Zif or/and d00..) can realize some piece of program in this direction ?
Uhh .. do you see plenty of new things in CeBit ?

Jean marie Verdi

drop 2 image (Timage) on a form and a button (Tbutton) on a form and try the following code (it works fine on my computer). To use the same code to print on a printer, resize image1 to the page size and replace the "image2" by "printer".

JDB


procedure TForm1.Button1Click(Sender: TObject);
var
      source_rect, dest_rect:Trect;
begin
      image1.canvas.textout(10, 10, 'Example of text');

      source_rect.top:=0;
  source_rect.left:=0;
  source_rect.bottom:=image1.height;
  source_rect.right:=image1.width;

  dest_rect.top:=0;
  dest_rect.left:=source_rect.right;
  dest_rect.bottom:=source_rect.bottom;
  dest_rect.right:=0;

      image2.canvas.stretchdraw(dest_rect, image1.picture.graphic);
end;

Hi Jean marie Verdi,
let's see what Zif says about the TTF component. After a few tries, I am sure that we can get some working code.
CeBIT was much too big, the funniest things I saw was the new Internet Phone from Samsung (a video phone that plugs right into the Ethernet) and the Nokia 9110 Communicator Cellular Phone(FTP, Telnet, EMail, WWW, Calendar, Adress Book, etc. and, oh yes, you can also place some phone calls if you like ;-))
The evening parties were much more exhausting than the day...

CU,
Slash/d003303
Hi pjdb,
take a look at
https://www.experts-exchange.com/topics/comp/lang/delphi/Q.10043255
for the previous thread (quite large) we had about this topic.
Hi pjdb's,

As d003303 says, and as i says in the label of my question, this thread comes to follow a thread which we have abandoned because it was very big.
There, we have tried your solution with 2 images and a stretchDraw. The problem is: the images have to be BIG enough to contain a lot of text, and to render it with quality on a printer at 600 dpi. At the A4 format, the page mesure 7 inches x 10inches so each of your two  image 'size must be about 4200 x 6000 pixels.(24 Mo)
Delphi (and Win95, i suppose) don't like images of this size...
 
Jean Marie verdi
I've read the previous thread (right now and not before, sorry).
I've try the following program with both NT 4. (SP 3) and Win 95 (OSR2) to print on HP IIIP and it work fine. I've writen with a 12 pitch font on the image a obtain a 12 pitch font on the printer. Of course, i don't have plain of text on it, but i don't see why it won't work.

procedure TForm1.Button1Click(Sender: TObject);
var
      dest_rect:Trect;
begin
      image1.width:=printer.pagewidth;
  image1.height:=printer.pageheight;

      image1.canvas.textout(10, 10, 'Example of text');

  dest_rect.top:=0;
  dest_rect.left:=printer.pagewidth;
  dest_rect.bottom:=printer.pageheight;
  dest_rect.right:=0;

  printer.begindoc;
      printer.canvas.stretchdraw(dest_rect, image1.picture.graphic);
  printer.enddoc;
end;
Hi pjdb,

I try to run exactly the lines of code you post here and the result is:
- as is, it hangs the PC and i must reboot it
- if i change the image1.width and height to 200,200, it works.
- if i change it to 1200,1200, it works too
if i run the program with PrinterHeight and printerwidth, and i check the system tool which comes with W95 which display system resources, and put a break point in the program, i notice that i have about 16 Mo : memory manager: free memory at the beginiing of runtime, and just after dest_rest.bottom:=printer.pageheight, the 16 Mo becomes 450 Ko, and just after printer.begindoc, the PC crashes.
I try it 4 or 5 times and it's always the same result at the same moment.

My PC is a pentium with 64 Mo, and the printer is a 300 dpi laser. I imagine that with a 600 dpi Laser, i will need 4x more memory.

I don't know how it works on your Win95 system ? How much Ram do you dispose ?

Jean marie

 
I have 64 MOof RAM, 150-300 MO of pagefile on a 233 Pentium (about 700-800 MO available on HD). Under NT it is using a maximum of 10 MO (seen in the task manager). NB : I'm using th e HP IIIP with a 300 dpi resolution

Well i'm not sure that it has hang the PC, it is not a high speed code, but it works.

I've think about another way to do it : flipting the text before printing it instead of printing and then flipping the all page. With it al you need is to use flip_textout instead of textout (and alter the work font instead of the printer font ;-)
This what it give :

procedure TForm1.Button1Click(Sender: TObject);
      procedure flip_textout(canvas:Tcanvas; left, top:integer; text:string);
      var
            source_rect, dest_rect:Trect;
      begin
            work.width:=work.canvas.textwidth(text);
            work.height:=work.canvas.textheight(text);
            work.canvas.textout(0, 0, text);
            source_rect.top:=0;
            source_rect.bottom:=work.height;
            source_rect.left:=0;
            source_rect.right:=work.width;
            dest_rect.top:=0;
            dest_rect.bottom:=source_rect.bottom;
            dest_rect.left:=canvas.cliprect.right - left;
            dest_rect.right:=canvas.cliprect.right - left - work.width;
            canvas.copyrect(dest_rect, work.canvas, source_rect);
      end;
var
      dest_rect:Trect;
begin
//      flip_textout(image1.canvas, 10, 10, 'Example of text');
      printer.begindoc;
      flip_textout(printer.canvas, 10, 10, 'Example of text');
      printer.enddoc;  
end;

JDB
hi jdb,

"i'm not sure it has hang the pc"
perhaps it not hangs on your side because your OS is NT!
Do you really test on W95 ?

About your new code, what is 'work' ? work.width, work.canvas..
Delphi doesn't recognize it and i got error message at compile time. (I use Delphi 2.01 but i can change PC and use D3 if 'work' comes from D3)

i must go now (here in france it's 2 past midnight!)  i come back in a few hours and see your answer.
Soon
Jean Marie
I've try the first one under win 95 (i've them both on my PC to make some test when i need). But i'ven't test the other one because i'm working mainly under NT.

work is a Timage component. I've named it like that because you can put the definition of flip_textout in the private part of the form and then call it from any procedure. I prefer to put it on the form, it allow to not allocate memory and deallocate memory at each call.

I'm using Delphi 2.01 to.

J'espère que la nuit a été bone (je suis français aussi même si je suis au Canada)

JDB
Hi jdb,

I try  your last code: it produces a white page. If i try again, the PC hangs hard: i must reboot.
I retry and cahnge the coordinates of the text (500,500 in place of 10,10) : with this coordinates,  the PC hangs at the first time.
After reboot, i replace the 10,10 coordinates: same thing: nothing on the printed page, then after a new clik on the button, hangs.
With trace, i can see that the 'hang' is at  the canvas.Copyrect line.

Salut aux canadiens et à bientôt

Jean marie
The forum has credited the points of the old thread so i increase this thread, as i said, to 1000
JMV
Hello all!! I'm back!! Hope you all too. Euhm, yes I forgot the address of that last component. I see now, sorry, here it is... Let give it  ring!

http://www.mdlive.com/d3k/ 

It's on there delphi components page (freeware)...

Regards, Zif.
I just can't understand why it hang your PC. I've test it under win95, win 95 OSR2 and NT and it work perfectly! I think we have misunderstood some where....

can you send me an Email privatly at mailto:jeanditbailleulp@usa.net i will send you my test program

JDB
I've re-read my suggestion, perhaps change the "canvas" of the paameter by "mycanvas" to give

procedure flip_textout(mycanvas:Tcanvas; left, top:integer; text:string);
....
dest_rect.left:=mycanvas.cliprect.right - left;
dest_rect.right:=mycanvas.cliprect.right - left - work.width;
mycanvas.copyrect(dest_rect, work.canvas, source_rect);

JDB

hi jdb,

you can send me the program-test at:
jmverdi@compuserve.com

sorry for the delay, i try the change (mycanvas) a few leter and come back

jmverdi
jdb,

i try the program and it doesn't hang the PC :-)  (however it's not exactly the same you wrote in this thread)
I have this result:
With the program 'as is', i print mirrored text at mirrored location, with a size very very little (i would say font size 2, unreadable).
If i deselect the first part of the procedure (flip_text out ) and select the second  ('entre images' et 'vers imprimante') it works too, and the result is :
printing of the text at correct location + printing of the mirrored text at correct mirrored location, with a big big big size of font (i would say font size 150= letters are quite 1 inch high)

So i modify the in initial size of the Image1 on the form: it had a size of about 200x200 and i put about 500x500.
The result is the same as before, but  with a font size smaller (i would say letters 1/3 inch high).
If i want the 'good' size, i must increase the size of image1.
And if i increase that size to a 'big 'size, i got error message (EoutOfResource).
I find it very strange, because in the program, the size of Image1 is increased at the size on the printer!
But here is all my observations.

Do you understand something ?

JmV
Zif,

Happy that you come back,

I downloaded the TTF convertor and use it. The source is included, and the source of a test-program. Thanks to the test-program ! because no help is given with the component and after you have installed the component, and put it on the form you don't know what to do. It has no events, and just 2 properties (choice of a font,and  factor quality =precision from 1 to 100, ).
With the test program, it's possible to display a single character of the choosen font in a paintbox. And i think that we are obliged to use a paintbox by char. And looking in the source code of component i see something like
width of xyz:=paintbox.width-20
height of xyz:=paintbox.height-20

It appears that it's not a 'global' ttf converter which can convert a whole page.

The second problem is the speed. With highest quality (=100), it takes time to convert ONE char (not much time, perhaps 1/2 second, but just one char..)
However i have not the delphian knowledge that it seems you have, so perhaps you better look yourself on it.
 
hope to read you again..

Jean marie Verdi
 
You just have to add the following line as a first line of the flip_textout procedure. It will adjust the sizes (in pixels) between the screen and the printer

work.canas.font.height:=mycanvas.foint.height;

JDB
Her it seems taht delphi does not resize the canva at the same time as the component. I suggest that you use a big size for the work (width:=700 and height:=150) component at design time and it will work fine.

JDB
Hi all,

About converting TTF: before we work on this topic further we should be sure that pjdb answer isn't going to work. But at this moment it's working almost so I suggest to dig in this problem a little bit further. It is indeed a clever idea to only swap the text and not the entirely page. We saw that swaping an entirely page was give us memmory problems. About that scaling problem. We should convert the pixels to the printer pixels to get a better result. This can be done very easily. you can see this on my earlier comments of the previous thread.

       var ScaleX, ScaleY : integer;

            with Printer do begin
             ScaleX := GetDeviceCaps(Handle, logPixelsX) div PixelsPerInch;
             ScaleY := GetDeviceCaps(Handle, logPixelsY) div PixelsPerInch;
            end;

Every calculated width and height should be multiplied with ScaleX and ScaleY. This way you get the right dimensions for your font on your printer. This must be done because dimensions for screen and printer aren't the same.

PS. I think it's normal you get EResource error, becaues you make your bitmap bigger, thus need more memmory, thus you get the same error as we had with mirroring the total page as big as a printer page at once. We first made a small bitmap and mirrored it -> no problem. But you need big Bitmap. Thus EResource problem... like here...

Now, what we can do also & thinking of it, it isn't such a bad idea at all! What about this?
We use one small bitmap (with the width and height of one line on a page!) We write our line of text on this bitmap. Mirror the bitmap and print the bitmap on the page. We write the second line of text on the bitmap. Mirror it and print the bitmap on the page. etc.etc. etc... I think this is it! Now we can even print A3 .... Because we can use small bitmaps, not much memmory and we can do whatever we want with it. What do you think about it? Shall we make a test program? I really think this is the solution to our problem!!!

I'm here untill 20.30h (belgium and french time)

Regards, Zif.


Using this approach, you wil lost some printing quality because you will use the screen quality to put it on the printer. That's why i suggest "work.canas.font.height:=mycanvas.font.height;" instead where you put the pixel height on the screen to the same value as the pixel height on the printer. The problem is then that my solution require more memory than yours.

JDB
Hi all,

if you adjust the image canvas DPI to the printer canvas DPI you will not have any quality losses. Sending bitmap pieces to the printer device driver (Zif's last idea) will (depends on the driver) also consume more memory than sending a font, but MUCH less memory than rendering the whole page in memory and StretchDraw it on the printer canvas. But, like JMV said, the page consists of a LOT of text, so there will be a lot subsequent bitmap pieces. Anyway, it is definately worth to check it out !
About JMV's processing speed problem when converting TTF to polylines, if you set the quality to 100 you will be able to print that character on a 1x1m paper without noticing any quality
losses. That character polyline will definately have too many lines. I look at it to get an algorithm for receiving a good value depending on the target devices DPI.
So Zif, you are working on mirroring with small bitmaps ? Then I will focus on this font to polyline thing.

See you,
Slash/d003303
Hi pjdb, can you explain me what you mean with 'work' is that the name of your TBitmap, TMetafile?
yo d003303,
I hadn't focussed me on anything, was just spreading to thoughts. I personally believe that if we could manage to convert the TTF to polylines this would be the best solution, because then we can draw these fonts on any width or height without loss of quality. We would have no limit about the page dimensions. With the piece of bitmaps method it would work also quit good, but not so good as with the TTF convertor, because indeed there will be lot's of text per page. The TTF converter lends it also much better for lots of different printing and different layours,  even if we want to add some drawings....
I think we better wait unil JMV gives his idea on which approach he want to follow. Does the program has to be made for different layouts etc.... then we better try out to make the best of our TTF converter. If the layout will always be the same (e.g. two columns or one column with the same with) then we can use the 'piece of bitmaps' approach...
Regards, Zif.
Hehe, I've some  problems with my printer, so i couldn't try it out.

procedure TForm1.Button3Click(Sender: TObject);
var ScaleX, ScaleY : integer;
    DummyPicture    : TPicture;
    i : integer;
    YPosition : integer;
    Tekstlines : Array[0..2] of String;
    R : TRect;
begin
 TekstLines[0] := 'This is just a test example';
 TekstLines[1] := 'We have to change the whole bunch if this works';
 TekstLines[2] := 'To a fully great working mirror printer';
 YPosition := 0;
 Printer.BeginDoc;
 with Printer do begin
  (* now some stupid lines, if it works, we must change all *)
  for i := 1 to 3 do begin
   DummyPicture := TPicture.Create;
   with DummyPicture do begin
    Bitmap.Canvas.Font.Size := i*10;
    Bitmap.Width  := Printer.PageWidth;
    Bitmap.Height := i*10;
    Bitmap.Canvas.TextOut(0,0,TekstLines[i]);
    R := Rect(DummyPicture.Bitmap.Width-1,0,-1, DummyPicture.Bitmap.Height);
    Bitmap.Canvas.StretchDraw(R,DummyPicture.Graphic);
   end;
  end;
  ScaleX := GetDeviceCaps(Handle, logPixelsX) div PixelsPerInch;
  ScaleY := GetDeviceCaps(Handle, logPixelsY) div PixelsPerInch;
  R := Rect(0, YPosition, DummyPicture.Bitmap.Width * ScaleX, DummyPicture.Bitmap.Height * ScaleY);
  Canvas.StretchDraw(R, DummyPicture.Graphic);
  DummyPicture.Free;  
 YPosition := YPosition + i*10;
 end;
 Printer.EndDoc;
end;

Regards, Zif.

Have a nice weeking!
Hi Zifnab

'work' is a Timage component you need to have on the form to allow the flip_textout procedure to fo her job. flip_textout will print the text on it to obtain a bitmap then flip it and send it to the cible canvas ou told her to write on.(If you want, i can sed you the example i've test by Email)

Of course if you are able the print a flip text directly (like with TTF) it will allow to obtain a better effect and to be compatible with any future system. My solution can because memory consuming if you have a very high resolution printer or if you have big text to print.

JDB
Hi all,

1. Zif, the program you sent prints a blank page.

2.About the printing's style of this report: there will be a few ( may be 2, 3 or 4)  different layout: today i'm sure of one with 3 colums, one with two colums.

3. About the approach: one 'little' bitmap, sent many times to the printer canvas, to compose the whole page:
I thought to this solution when i got memory problems during the old thread: it's possible, however iu thought it could be a little complex.
Imagine each column, composed of a few (20 to 50) 'things'. The number of 'things' is always different from a page to another, a column to another.
 These things are composed of a few lines (1 to 10). The number of lines is always different from a 'thing' to another.
In theses things, the font is changing. Font 1 for the first line, font 2 for the lines 4 and 7,..so the lines.height is different, and  the space between lines is differenrt too.
The result is something like
NAME Lastname
Address 1 (if exist)
Address 2 (if exist)
Address 3 (if exist)
some informations about work, diploms, schools..(if exist)

...

So i think that this approach is possible,but the bimap has to accurate 'very fine' the lines to write, and when it's copied on the printer canvas, not to write a litle on what was wrtitten just before.
But, another time, i think it can be done.

4. About TTF convector.
This solution seems to be very 'elegant', smart, useful if i (or the customer) want to change the layout, add bitmap (he asked me recently about this possibility: add logo bitmap in front of each name of anyone has a society: for the moment, we have not keeped this, for many reasons)
BUT, after a look of the component TTF Convector, i doubt a little ? except if anyone studies the source code and works on anything better ?


So, i am a little confused, but i would say: lets try to work (dear experts!) on the ttf convector or one another solution. If we (you) cannot find something which works, so we can return to the approach of the little bitmap, in last resort.


What do you think ?

JMVerdi

Hi all,

I don't know about you all, but I've got big problems getting into experts-exchange latest time ....

pjdb : my email is Tom.Deprez@uz.kuleuven.ac.be, I would like to see your example if you don't mind sending it to me.

JMV : same thoughts as I have. Lets try to work out the TTF convector.

d003303 : how are you doing?

Regards,
Zif.

Again this thread is become large....
Hi Zif,

No problem to get into experts-exchange.
Yes this thread becomes large!

Any comment about TTF convector ?

JMV
Hi all,
I am quite busy at work, and I wanted to finish my property sheet shell extension class with Craig's code first. But you know, windows programming can be just a pain...especially if you hang in details. Do you know why the API function GetDialogBaseUnits returns unusable values ? I think only M$ knows.
Anyway, I'll check the TTF thing, but don't know when I can find the time. Hopefuly this week.

CU,
Slash/d003303
Hi, I hope this doesn't sound stupid. Could you ask your client to print onto transparencies, and then make a photocopy of the reversed transparency? I know this lacks the sophistication of many of the other suggestions, but it would work fine, if a small number of these mirrored documents are required.

Regards,

Edward
Sorry guys, I can't follow anymore, I got really problems getting in Exp.Exch. Most of time I can't get in and I can't find out how this comes. I'll try to look for a solution and when I got one and when I can get in Exp.Exch I let you know!

Success.
Hi Edo,

I would say: the number of documents is about a few hundreds (a big book). and this book is re-printed every year.

About print onto transparencies and make photocopy of the reversed transârencies: It could be a solution, but i prefer find a computer solution if it's possible!

Experts have found a solution, here, but only with NT as OS. With 95, it's not impossible to think that they can find something (?). I hope :-)  I must give the work at the end of april- begin of mai.

Thanks for your idea.

Jean marie verdi

ASKER CERTIFIED SOLUTION
Avatar of ZifNab
ZifNab

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hello,

guys I need some help here, I am trying to copy a part of a metacanvas to a bitmap.
Does anybody knows how this has to be done???? I can't find any solution.

PS. This is the only thing I still need to get it to work!!!

Regards, Zif.
Hi, Zif

I'm happy to see that you have found something which will work (cross the finger).
Unfortunaly, as you can imagine, i don't know how to copy parts of metacanvas. In fact, i hate metacanvas, i never meet metacanvas. I prefer databases. The only thing i can do is delete metacanvas, or eat them.
Like Gal Gates said:  "A good metacanvas is a dead metacanvas."

But if you find something which can flip text, and use metacanvas, i will make an exception.:-)

Jean Marie Verdi

Ok, now I've done it in the other way... Mirroring every text before it's entered on the form. Proposed solution I.

This works here, I hope also at your computer.

 procedure TForm1.MirrorIt(X,Y, Z : integer; aStr : String;var ACanvas : TCanvas);
       var DummyBitmap : TBitmap;
           MirrorRect : TRect;
       begin
        DummyBitmap := TBitmap.Create;
        with dummybitmap do begin
         Font.Color := clBlack;
         Font.Size := 10;
         Width := Z;
         Height := Canvas.TextHeight(aStr);
         canvas.TextOut(x,0,astr);
        end;
        MirrorRect := Rect(DummyBitmap.Width-1,0,-1,DummyBitmap.Height);
        DummyBitmap.Canvas.stretchDraw(mirrorrect,DummyBitmap);
        ACanvas.Draw(x, y, dummyBitmap);
        DummyBitmap.Free;
       end;

procedure TForm1.Button4Click(Sender: TObject);
 var MyMetaFile : TMetafile;
      ACanvas    : TCanvas;

       begin
        Printer.BeginDoc;
         try
           MyMetafile := TMetafile.Create;
           MyMetafile.Enhanced := true;
           MyMetafile.Width := 200; //Printer.PageWidth;
           MyMetafile.Height := 200; //Printer.PageHeight;
           ACanvas := TMetafileCanvas.Create(MyMetafile, Printer.Canvas.Handle);
           try
            MirrorIt(0,0,Metafile.Width,'Hello world',ACanvas);
           finally
             ACanvas.Free;
           end;
         finally
          Printer.EndDoc;
         end;
       end;

PS. I hope still that someone can help me with my comment above...
      How to copy a part of a metafile canvas!!!
      Proposed solution II is stranded with this problem...

This easely can be changed for drawing bitmaps, etc.....

JM verdi, please give a living sign!

regards, Zif.
Hi JM,

now I know you're here, I'll stay a little bit longer... Please respond with the tests as soon as possible! For big messages, use my email Tom.Deprez@uz.kuleuven.ac.be.

You see I've coded this :
                  MyMetafile.Width := 200; //Printer.PageWidth;
                  MyMetafile.Height := 200; //Printer.PageHeight;
If this works change, remove '200; //' and test it again.

Regards, Zif.
Zif,

I tried with 200 and later with Printer.pageWidth...
Same result: a white page is printed

jmverdi
Ok, strange lets put some tests in it...

Change back to 200.
Put to Timages on the form.... (make them 200x200)

               DummyBitmap.Canvas.stretchDraw(mirrorrect,DummyBitmap);
               ACanvas.Draw(x, y, dummyBitmap);
-->           Image2.Canvas.Draw(0,0,dummyBitmap);
               DummyBitmap.Free;

                 try
                   MirrorIt(0,0,Metafile.Width,'Hello world',ACanvas);
-->           Image1.Canvas.Draw(0,0,dummyBitmap);
                  finally
                    ACanvas.Free;
                  end;

What appears on screen? Zif.


Zif,
About the second correction (Image1.canvas..)
dummybitmap is not defined in the button4click function.
jmv
Euhm yes, sorry, it has to be :

                         try
 ->                       MirrorIt(0,0,Metafile.Width,'Hello world',ACanvas); <- wrong!!
--> change this to MirrorIt(0,0,MyMetafile.Width,'Hello world',ACanvas);
                         finally
                           ACanvas.Free;
                         end;
       -->           Image1.Canvas.Draw(0,0,MyMetaFile);

Waiting...
Sorry, I changed some things after pasting it to here and these things give some strange results, this should work, I hope!

procedure TForm1.Button4Click(Sender: TObject);
 var MyMetaFile : TMetafile;
     ACanvas    : TCanvas;
     aWidth      : longint;

       begin
        Printer.BeginDoc;
         try
           MyMetafile := TMetafile.Create;
           MyMetafile.Enhanced := true;
           aWidth := 200; //Printer.PageWidth;
           MyMetafile.Width := aWidth;
           MyMetafile.Height := 200; //Printer.PageHeight;
           ACanvas := TMetafileCanvas.Create(MyMetafile, Printer.Canvas.Handle);
           try
            MirrorIt(0,0, aWidth,'Hello world',ACanvas);
           finally
             ACanvas.Free;
           end;
           finally
           Printer.EndDoc;
         end;
       end;

If you change to printer width .... , remove a Timages!.

Zif,

Sorry for delay, a customer went here and disturbs me!

I tested with the last code: on the screen nothing changes at runtime. On printing, its always a blank page.

jmV
Nothing changes? Mmmmm, ok I paste the whole working code (at my computer), wait some time and then move of home trying it on my computer....

 
       unit unit1;

       interface

       uses
         Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
         StdCtrls, ExtCtrls, Printers;

       type
         TForm1 = class(TForm)
    Image1: TImage;
    Image2: TImage;
    Button4: TButton;
    procedure Button4Click(Sender: TObject);
         private
           { Private declarations }
           procedure MirrorIt(X,Y, Z : integer;aStr:String;var ACanvas:TCanvas);
         public
           { Public declarations }
         end;

       var
         Form1: TForm1;

       implementation

       {$R *.DFM}


       procedure TForm1.MirrorIt(X,Y, Z : integer; aStr : String;var ACanvas : TCanvas);
       var DummyBitmap : TBitmap;
           MirrorRect : TRect;
       begin
        DummyBitmap := TBitmap.Create;
        with dummybitmap do begin
         Font.Color := clBlack;
         Font.Size := 10;
         Width := Z;
         Height := Canvas.TextHeight(aStr);
         canvas.TextOut(x,0,astr);
        end;
        MirrorRect := Rect(DummyBitmap.Width-1,0,-1,DummyBitmap.Height);
        DummyBitmap.Canvas.stretchDraw(mirrorrect,DummyBitmap);
        ACanvas.Draw(x, y, dummyBitmap);
        Image2.Canvas.Draw(0,0,dummyBitmap);
        DummyBitmap.Free;
       end;

       procedure TForm1.Button4Click(Sender: TObject);
 var MyMetaFile : TMetafile;
     ACanvas    : TCanvas;
     aWidth      : longint;

       begin
       //  Printer.BeginDoc;
         try
           MyMetafile := TMetafile.Create;
           MyMetafile.Enhanced := true;
           aWidth := 200; //Printer.PageWidth;
           MyMetafile.Width := aWidth;
           MyMetafile.Height := 200; //Printer.PageHeight;
           ACanvas := TMetafileCanvas.Create(MyMetafile, 0{Printer.Canvas.Handle});
           try
            MirrorIt(0,0, aWidth,'Hello world',ACanvas);
            //PrintIt(ACanvas);
           finally
             ACanvas.Free;
           end;
         Image1.Canvas.Draw(0,0,MyMetaFile);
         finally
       //    Printer.EndDoc;
         end;
       end;

end.

Note : doesn't print now! print settings are disabled.
          I wait 15 minutes, then I'm off to home.

Regards, ZIF.
Zif,

Sorry, i re-tried and on the screen (  on the Image2) 'Hello World' is written at the top.
(First, the image2 i used was very big and i stretched it so the characters were invisible. My new image2 is not so big)
But on the printed page, there is only white letters on white paper!
jmV
Zif,
see your last paste . i try it and in 5 minutes i come back
jmv
prints white letters? Curious, how can you see this?
 anyway try this :
                  ACanvas := TMetafileCanvas.Create(MyMetafile, 0{Printer.Canvas.Handle});
                  try
                   ACanvas.Font.Color := clBlack;
                   ACanvas.Font.Size := 10;
                   MirrorIt(0,0, aWidth,'Hello world',ACanvas);                  
                  finally
                    ACanvas.Free;
                  end;

I'll try it at home! promised.
Zif,

Ok with the code posted at 10:49, i see on thtwo images 'Hello world' MIRRORED;
(Another time: sorry for the Image big size mismathch)
JMV
Zif,

White letters on white page=nothing on the page. That's french humour. I just missed the :-) after this declaration.
Humm, We are close , don't you think so ?
jmV
hi jm verdi,

Ok got the french humour ;-).
Great it mirrors!!

Yes we're very close, I'll look at it at home at paste the solution (I hope) to this thread...

Too bad that I don't know how to copy a metacanvas.... damn....

about printing ....

procedure TForm1.Button4Click(Sender: TObject);
        var MyMetaFile : TMetafile;
            ACanvas    : TCanvas;
            aWidth      : longint;

              begin
               Printer.BeginDoc;
                try
                  MyMetafile := TMetafile.Create;
                  MyMetafile.Enhanced := true;
                  aWidth := 200; //Printer.PageWidth;
                  MyMetafile.Width := aWidth;
                  MyMetafile.Height := 200; //Printer.PageHeight;
                  ACanvas := TMetafileCanvas.Create(MyMetafile, 0{Printer.Canvas.Handle});
                  try
                    ACanvas.Font.Color := clBlack;  // to be sure, normally not nescecarry ;-)
                    ACanvas.Font.Size := 10;
                    MirrorIt(0,0, aWidth,'Hello world',ACanvas);
                                finally
                    ACanvas.Free;
                  end;
                Image1.Canvas.Draw(0,0,MyMetaFile);
                finally
                 Printer.EndDoc;
                end;
              end;

Regards, Zif.

PS. One of our previous solutions could print this, so this problem isn't really a problem, we just have to dig up the right code ....
Zif,

with last code: 11:13
Always white chars on the printed page :-)
and mirrored 'Heloo world' on the 2 images.

i must leave now, too, and toimorrow during the day i am not here, but at the evening i can test code if you find something.

Thank for your help
jean marie Verdi



Hi JM Verdi,

This is the solution ...... I tested it, and guess what it did it!!!! Yeahoe! Finally we did it!


       unit unit1;

       interface

       uses
         Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
         StdCtrls, ExtCtrls, Printers;

       type
        TForm1 = class(TForm)
           Button4: TButton;
           procedure Button4Click(Sender: TObject);
         private
           { Private declarations }
          procedure MirrorIt(X,Y,Z : integer;var ACanvas:TCanvas; aBitmap:TBitmap);
          procedure WriteText(X,Y, Z : integer;aStr:String;var ACanvas:TCanvas;Mirror:Boolean);
          procedure WriteBitmap(X,Y,Z : integer;aBitmap:TBitmap;var ACanvas:TCanvas;Mirror:Boolean);
         public
           { Public declarations }
         end;

       var
         Form1: TForm1;

       implementation

       {$R *.DFM}

       procedure TForm1.MirrorIt(X,Y,Z : integer;var ACanvas:TCanvas; aBitmap:TBitmap);
       var MirrorRect : TRect;
       begin
         (* Create mirror rectangle *)
         MirrorRect := Rect(aBitmap.Width-1,0,-1,aBitmap.Height);
         (* switch bitmap to mirrorod bitmap *)
         aBitmap.Canvas.stretchDraw(mirrorrect,aBitmap);
         (* draw mirrored bitmap to correct place on canvas *)
         ACanvas.Draw(Z-x-aBitmap.Width, y, aBitmap);
       end;

       procedure TForm1.WriteText(X,Y, Z : integer; aStr : String;var ACanvas : TCanvas;Mirror:Boolean);
       var DummyBitmap : TBitmap;
       begin
        (* Prepare text *)
        DummyBitmap := TBitmap.Create;
        with dummybitmap do begin
                                (* You can change font here *)
         Font.Color := clBlack; (* Give font a color *)
         Font.Size := 10;       (* Give font a height *)
         Width := Canvas.TextWidth(aStr);
         Height := Canvas.TextHeight(aStr);
         canvas.TextOut(0,0,astr); (* write string to bitmap *)
        end;
        (* Mirror or not mirror *)
        if Mirror then MirrorIt(x,y,Z,ACanvas,DummyBitmap)
         else ACanvas.Draw(x, y, DummyBitmap);
        DummyBitmap.Free;
       end;

procedure TForm1.WriteBitmap(X,Y,Z : integer;aBitmap:TBitmap;var ACanvas:TCanvas;Mirror:Boolean);
var DummyBitmap : TBitmap;
    MirrorRect : TRect;

begin
 (* Prepare bitmap *)
 DummyBitmap := TBitmap.Create;
 with dummybitmap do begin
  Width := aBitmap.width;
  Height := abitmap.height;
  canvas.Draw(0,0,aBitmap);
 end;
 (* Mirror Bitmap or not *)
 if Mirror then MirrorIt(x,y,Z,ACanvas,DummyBitmap)
  else ACanvas.Draw(x, y, DummyBitmap);
end;

 procedure TForm1.Button4Click(Sender: TObject);
 var MetaPage : TMetafile;
     MetaPageCanvas    : TCanvas;
     PageWidth, PageHeight      : longint;
     ARect : TRect;
     ScaleX, ScaleY : integer;


       begin
        Printer.BeginDoc;
        try
         MetaPage := TMetafile.Create;
         (* Be sure to work with correct dimensions *)
         ScaleX := GetDeviceCaps(Printer.Handle, logPixelsX) div PixelsPerInch;
         ScaleY := GetDeviceCaps(Printer.Handle, logPixelsY) div PixelsPerInch;
         (* Convert printer dimensions to screen dimensions *)
         PageWidth := Printer.PageWidth;// div ScaleX;
         PageHeight := Printer.PageHeight;// div ScaleY;
         with MetaPage do begin
          Enhanced := true;
          Width := PageWidth;
          Height := PageHeight;
         end;
          MetaPageCanvas := TMetafileCanvas.Create(MetaPage,0);
          try
           WriteText(0,0, PageWidth,'Hello world : mirrored',MetaPageCanvas,true);
           WriteText(0,25, PageWidth,'Hello world : not mirrored', MetaPageCanvas, false);
          finally
           MetaPageCanvas.Free;
          end;
          with Printer do begin
         (* ARect:= rect(0,0,MetaPage.Width*ScaleX, MetaPage.Height*ScaleY);
          Canvas.StretchDraw(ARect, MetaPage) *)
           Canvas.Draw(0,0,MetaPage);
          end;
         finally
          Printer.EndDoc;
         end;
         MetaPage.Free;
       end;

end.

Some notes :
1. Haven't tested WriteBitmap.
2. - Now it prints very small characters (at my printer) -->
      In this case we use printer canvas --- > high resolution
   - change this to work on screen resolution :

     (* Convert printer dimensions to screen dimensions *)
         PageWidth := Printer.PageWidth div ScaleX;
         PageHeight := Printer.PageHeight div ScaleY;

          with Printer do begin
           ARect:= rect(0,0,MetaPage.Width*ScaleX, MetaPage.Height*ScaleY);
           Canvas.StretchDraw(ARect, MetaPage);
          end;
   
     --> now bigger chars on printer (my printer)
3. This works, but you have to write all your printing stuff yourself, preview ...., font,...
4. If I've time in the weekend I'll modify a printing component, which was shareware
    but now is freeware.... (found it one time on the net)
5. Maybe I can get a credit in your program? ;-)
6.This REALLY works on my Win95!!
7. I 'll still help you when you're in trouble....

Regards, zif!

Good luck!!
Okelido,

I couldn't wait for changing that printing component. But I toke more time then I thought. :-(.  Look out, for printing bitmaps, you've to flip them yourself. If you need help with it, I'll help you. It will be the same code as printed here above....

So, I sugest, try project above, so my night work isn't done for nothing...
Try then project with component, and never let my boss hear about this...

I sended it to you email address, ....

Good luck!!

PS. What happend with pjdb's code? His code looked very promissing too. What didn't worked?

Regards, ZIF. (and now, getting to work overtime.....)
Zif,

Excellent: your code works great: now, my printer prints black characters on the white page! :-)
and Yes, the characters were little but they grow with the modification.  
and you're right, the component you sended is very interesting. It seems that the author has worked a lot!

Sure: i credit your work in my program : Tom Deprez ? i presume, or ZifNab ?
 
I learned much these last days thanks to you and the others experts.
Thanks a big lot for your help and your kindness.

It's a little thing but i'm pleased to grade your excellent answer.

Jean Marie Verdi