Recent

Author Topic: Make a textstring look like in MS Word or Libreoffice  (Read 2971 times)

ChristianundCo

  • New Member
  • *
  • Posts: 11
Make a textstring look like in MS Word or Libreoffice
« on: October 09, 2018, 06:34:36 pm »
Hello there, sorry for my English.

I'm programming a tool to edit subtitles. (simple textlines)
For that I need a function that writes a textstring to canvas. Then I want to measure the width of the written text. Because I need the textwidth in pixel for later.

Now I saw that a text looks in every app different.
For example I have these two textlines
Code: [Select]
Eins zwei drei vier fünf sechs sieben acht neun
...........................................................................

I want them in "Tahoma" and BOLD. Now my problem. In my font (Tahoma, bold) they must have same length AT EVERY CHOOSEN SIZE.
In MSWord (not Wordpad) and Libreoffice and some other apps they are of equal length. (ok, there is a pixel difference at Size 50 but that doesn't matter)
It looks like this in every fontsize: https://s1.imagebanana.com/file/181009/51gakppp.jpg

That's what I want!

But in Windows Notepad and Freepascal MemoBox it looks something like this: https://s1.imagebanana.com/file/181009/SPFcJmY7.jpg
The dots in the second line are of different length to the first line. Sometime more, sometimes less depending on the fontsize.

Then I tried draw it on free pascal default canvas with the codeline

Code: Pascal  [Select][+][-]
  1. Canvas.Font.Quality:=  fqAntialiased;

This is better but not good enough.

Then I tried the bgrabitmap-9.9-package and the CanvasBGRA with a TBGRAVectorizedFontRenderer

The result ist this: https://s1.imagebanana.com/file/181009/huqIPNji.jpg
My function is this:

Code: Pascal  [Select][+][-]
  1. var
  2.     bmp: TBGRABitmap;
  3.  
  4.  
  5.   begin
  6.     a:=26; //FOntsize
  7.  
  8.  
  9.     bmp := TBGRABitmap.Create(ClientWidth,ClientHeight,ColorToRGB(clBtnFace));
  10.  
  11.     bmp.FontRenderer := TBGRAVectorizedFontRenderer.Create;    
  12.     bmp.CanvasBGRA.Font.Name := 'Tahoma';
  13.     bmp.CanvasBGRA.Font.Quality :=fqFineClearTypeBGR;
  14.     bmp.CanvasBGRA.Font.Style:=[fsBold];
  15.     bmp.CanvasBGRA.Font.Height:= round(-a* Font.PixelsPerInch/72);
  16.  
  17.      bmp.CanvasBGRA.Brush.Color:=BGRA(255,0,0,255);
  18.     bmp.CanvasBGRA.TextOut(0,0,zeile1);
  19.     bmp.CanvasBGRA.TextOut(0,80,zeile2);
  20.  
  21.     bmp.Draw(Canvas,0,0);
  22.  
  23.      Form1.Edit1.Text:=IntToStr(bmp.CanvasBGRA.TextWidth(zeile1));
  24.  
  25.    bmp.Free;
  26. end;

Here are the 2 line nearly of equal length in every fontsize (a=12 ... a=45). But not so exact like in MS Word or other apps. But I want them equal.
Is there a better way to get this 2 lines look like in word?  Note that I need a solution together with a GetTextwidth-function because later I need the pixelwidth.





wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Make a textstring look like in MS Word or Libreoffice
« Reply #1 on: October 09, 2018, 07:41:21 pm »
Using a proportional font like Tahoma the two strings 'Eins zwei drei vier fünf sechs sieben acht neun' and '...........................................................................' will almost never have the same length because every character has its own width, and the ratios of character widths will change with font size, at least due to round-off error. You can only "cheat" by drawing the first string word by word and add a pixel here and there such that the length difference is balanced.

See attached project in which the widths of both strings should be equal within 1 pixel (even this could be avoided by adding the remaining pixel randomly to one of the spaces). Note that this is just a proof of concept, it does not mean that there may not be bug here and there.
« Last Edit: October 09, 2018, 07:46:10 pm by wp »

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Make a textstring look like in MS Word or Libreoffice
« Reply #2 on: October 09, 2018, 07:48:45 pm »
IMO it requires some special feature for variable space between words or, better, between characters. Lazarus doesn't have any, don't know about BGRA.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

ChristianundCo

  • New Member
  • *
  • Posts: 11
Re: Make a textstring look like in MS Word or Libreoffice
« Reply #3 on: October 09, 2018, 07:56:27 pm »
Thank you for your answers and your code.
But why does Word etc. it right? Nearly no difference between the two lines whether size is "12" or size is "45"

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: Make a textstring look like in MS Word or Libreoffice
« Reply #4 on: October 09, 2018, 08:10:12 pm »
But why does Word etc. it right? Nearly no difference between the two lines whether size is "12" or size is "45"
By chance. Word probably draws the text word by word and uses a different width for the space character than is defined by the font itself (otherwise all programs should show the same text width).

What is the line with the dots good for?

You write in the first post that you want to measure the width of text. Why don't you use the method TextWidth(text) of the Canvas?
« Last Edit: October 09, 2018, 08:12:53 pm by wp »

ChristianundCo

  • New Member
  • *
  • Posts: 11
Re: Make a textstring look like in MS Word or Libreoffice
« Reply #5 on: October 09, 2018, 08:20:36 pm »
What is the line with the dots good for?

That was a simple example to test if my pascal-tool works like MSWord or my subtitle editor (aegisub)


Why don't you use the method TextWidth(text) of the Canvas?

In line 23 i use it.  :)


Handoko

  • Hero Member
  • *****
  • Posts: 5158
  • My goal: build my own game engine using Lazarus
Re: Make a textstring look like in MS Word or Libreoffice
« Reply #6 on: October 09, 2018, 08:35:21 pm »
But why does Word etc. it right? Nearly no difference between the two lines whether size is "12" or size is "45"

Not only Word and LibreOffice. I tested Inkscape and Krita Linux version, the dots and text are equally long if I resize the font. But not so on GIMP.

I think the issue is depended on the text rendering engine they use.

ChristianundCo

  • New Member
  • *
  • Posts: 11
Re: Make a textstring look like in MS Word or Libreoffice
« Reply #7 on: October 09, 2018, 08:50:56 pm »
Yes! That I think, too. Therefore I made the code with the vectorfontrenderer. Because this was the only solution that comes nearly to MSWord and a few other tools.

I forgot to say: If I use c# there is the line


Code: C#  [Select][+][-]
  1.  g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

and the two lines are exactly of same length.
without -> not
But I don't want to translate my tool to c#

 

TinyPortal © 2005-2018