TRichView - Getting The Line Height

General TRichView support forum. Please post your questions here
Graham
Posts: 64
Joined: Sun Jan 27, 2013 7:51 pm
Location: Berkshire U.K.

TRichView - Getting The Line Height

Post by Graham »

Having got the text for a particular line, is there something I can call to get the height (in pixels) of the line as it is displayed on the screen.
If not, I can calculate it myself from the font sizes along the line, but is there any interline spacing between the rows of text?
Sergey Tkachenko
Site Admin
Posts: 17564
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Do you need line height when the document is formatted?
Do you need at the specified position of document?
Graham
Posts: 64
Joined: Sun Jan 27, 2013 7:51 pm
Location: Berkshire U.K.

Post by Graham »

The document will have been formatted.

I will call the routine we discussed in an earlier message. So having got the text and a string containing the styles for each character, I now need the line height as it is displayed in the RichView component. I would like the full height of the line regardless of how much of the line is displayed. I can do a calculation myself base on GetTextMetric, but I need to know if you add any extra spacing between the lines over and above that returned by this.
Sergey Tkachenko
Site Admin
Posts: 17564
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Ok, let's use the procedure from http://www.trichview.com/forums/viewtopic.php?t=5880
We need DNo1 and DNo2. They are indices in rve.RVData.DrawItems.
Top coordinates of drawing item (ditem = rve.RVData.DrawItems): ditem.Top-ditem.ExtraSpaceAbove
Bottom coordinates of drawing item: ditem.Top + ditem.Height + ditem.ExtraSpaceBelow
(ExtraSpaceBelow and ExtraSpaceAbove allow to take line spacing into account).

Additionally, there may be spacing between paragraphs, but since it is not belong to lines, it is not taken into account here.
Graham
Posts: 64
Joined: Sun Jan 27, 2013 7:51 pm
Location: Berkshire U.K.

Post by Graham »

I'll try this early next week. The ultimate goal of this particular task is to copy the text exactly as displayed in a RichView into a bitmap for subsequent processing. I have tried to use CopyRect from Canvas to Canvas and this works, but the resulting bitmap is not as per the original. I seem to be getting artifacts from the graphics. If I write the text directly to the bitmap its perfect.
Graham
Posts: 64
Joined: Sun Jan 27, 2013 7:51 pm
Location: Berkshire U.K.

Post by Graham »

Actually just tried it now. Looks OK. Under what circumstances does

ditem.ExtraSpaceBelow or ditem.ExtraSpaceAbove become > 0

The dItem.Height matches the TextMetric tmHeight. Do you ever account for tmExternalLeading or is this not applicable here.
In my test I have am using Arial, Size = 64 and the tmExternalLeading = 3
Sergey Tkachenko
Site Admin
Posts: 17564
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

TRichView ignores font's external leading.
ExtraSpaceBelow and Above may be non-zero because of line spacing (for example, "double" line spacing increases ExtraSpaceBelow)

For your task, consider using TRVReportHelper to draw onto a bitmap. If you specify the same width as in TRichViewEdit, results must be identical.
Graham
Posts: 64
Joined: Sun Jan 27, 2013 7:51 pm
Location: Berkshire U.K.

Post by Graham »

So now I am experimenting with TRVReportHelper.

I have created text of all sorts of sizes colours etc. in a RichView. I now want to use ReportHelper to format the data into pages that are 128 pixels high. It nearly works as I would like, but I may be doing something wrong.

Let's say a typical text line is 80 pixels high. What I would like in page 1 of ReportHelper is the first line and about half of the second line. Page 2 of the ReportHelper would contain the second half of line 1 and some of line 2 etc.

What I get is a single line in each page of the ReportHelper. So when I reconstruct that data into a large bitmap, the lines of text are separated by large gaps.

Is this a feature or am I doing something wrong?
Graham
Posts: 64
Joined: Sun Jan 27, 2013 7:51 pm
Location: Berkshire U.K.

Post by Graham »

Basically I think the FormatNextPage routine is only working on whole lines. Is it possible to not have it do this, but just fit all it can into the specified height?
Sergey Tkachenko
Site Admin
Posts: 17564
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Formatting up to the specified height is not supported yet, sorry.
Graham
Posts: 64
Joined: Sun Jan 27, 2013 7:51 pm
Location: Berkshire U.K.

Post by Graham »

That's unfortunate because it would have been a perfect solution to my problem.

So I have to attempt to perfect my previous method of using:

rve.GetItemAt(X, currentScrollY, RVData, ItemNo, OffsetInItem, False);

tStr := GetSpecifiedLineText(rve, ItemNo, OffsetInItem, sStr, LineHeight);

As you will remember I am trying to get the text as it is displayed in RichView at a particular offset from the top of the display.

GetSpecifiedLineText is our new function to return the text, the line height and a string (sStr) containing the style numbers for each character.

The problem I now have is that this doesn't always work. Usually the value of X is set to 0, but sometimes I have to set it to the end of the line, 668 in my case. And sometimes I have to increment the OffsetInItem before calling GetSpecifiedLineText, otherwise the string returned is empty.

Any clues?
Graham
Posts: 64
Joined: Sun Jan 27, 2013 7:51 pm
Location: Berkshire U.K.

Post by Graham »

Setting the final parameter of GetItemAt to TRUE, seems to help, but creates other issues which I am investigating.
Graham
Posts: 64
Joined: Sun Jan 27, 2013 7:51 pm
Location: Berkshire U.K.

Post by Graham »

The problem I have now is that the new routine only returns the first word of the displayed line.

The start of the new routine is almost a copy of "GetCurrentLineText":

rve.RVData.Item2DrawItem(ItemNo, OffsetInItem, DNo1, DOffs, rvdpBetterBelow);
DNo2 := DNo1+1;
while not rve.RVData.DrawItems[DNo1].FromNewLine do
dec(DNo1);

while (DNo2<rve.ItemCount) and not rve.RVData.DrawItems[DNo2].FromNewLine do
inc(DNo2);

dec(DNo2);


The calculation of DNo2 does not seem to be correct. DNo2 and rve.ItemCount do not refer to the same things do they?
I am getting DNo2 values far greater than ItemCount.


This works, but now I have no limit detection for the end stop!

while (not rve.RVData.DrawItems[DNo2].FromNewLine) do
inc(DNo2);


What is the relationship between Items and DrawItems?
Sergey Tkachenko
Site Admin
Posts: 17564
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

You are right, this is a bug. It must be

Code: Select all

while (DNo2<rve.RVData.DrawItems.Count) and not rve.RVData.DrawItems[DNo2].FromNewLine do 
// is you set Strict=True for GetItemAt, the function would return the item only if it is exactly at the given location; if you "miss", it does not return any result. If Strict=False, it returns the closest item, so it never fails.
Graham
Posts: 64
Joined: Sun Jan 27, 2013 7:51 pm
Location: Berkshire U.K.

Post by Graham »

OK, now how do I get the height of a Blank line. Rve.GetItemAt returns an item number of -1
Post Reply