Page 1 of 2
Wingdings font problem
Posted: Wed Jun 05, 2013 11:13 am
by BernhardRoos
Hello,
since Richview 14.3 we have the problem that reports with Wingdings Symbols in RB 14 are not correct displaying. Instead of the symbol, which we are set in the Editor, it displays another symbol in the preview of the Reportbuilder.
With the previous version (13) all worked fine.
We don't have a new version of RB. It worked fine with RB14 and Richview 13.
Is this a known problem? What can we do to solve this problem? Any ideas?
Best wishes
Bernhard
Posted: Wed Jun 05, 2013 12:03 pm
by Sergey Tkachenko
What is the source for displayed documents?
Do you use TppRichView or TppDBRichView?
Version of Delphi?
Posted: Thu Jun 06, 2013 1:52 pm
by BernhardRoos
I'm using tppRichView
Best wishes
Bernhard
Posted: Thu Jun 06, 2013 1:53 pm
by BernhardRoos
and I have Delphi XE3.
Best wishes
Bernhard
Posted: Thu Jun 06, 2013 3:17 pm
by Sergey Tkachenko
Can you send a sample project (as simple as possible) to richviewgmailcom?
Posted: Fri Jun 07, 2013 12:37 pm
by BernhardRoos
If I'm making a sample project all works fine.
I have debugging my app and find out that the following line is the problem :
sText := RVData.GetItemTextW(i);
sText should be the ascii character 'nnnnn'. In Wingdings this is the sign of black rectangles.
But since the newest Richview version (RV 14), I get for sText '.......'
With all other fonts it works fine, but in Wingdings I get not the correct string.
Is in the function GetItemTextW something changed in RV 14?
Best wishes
Bernhard
Posted: Fri Jun 07, 2013 1:13 pm
by Sergey Tkachenko
Yes, it was changed.
If text is stored as Unicode inside TRichView, GetItemTextW returns it as it is, no conversion.
But if text of SYMBOL_CHARSET font is stored as ANSI, GetItemTextW converts it differently now.
There are two different ways of conversion.
The first way (used before) is using a system default language (CP_ACP locale), as if this is a text of the system default language.
This is a bad approach, because for character with codes >= 128 it produces different results depending on the system language.
For example, if you receive this Unicode string on English version of Windows, it is useless in Russian version.
The second way is used now. In addition to mapping as if system-default language, Windows maps symbol fonts to Unicode private use area, by adding $F000 to ANSI character code. This is a system-independent way.
On the same system, the both versions of GetItemTextW must be displayed identically, if you use the same font.
So may be the problem is in text processing in your code?
Posted: Wed Jun 12, 2013 1:01 pm
by BernhardRoos
Thanks for your answer. I'm using the following code for text processing. Can you say me what I have to change? Especially what I have to do in the first line where I'm using GetItemTextW.
Best wishes
Bernhard
Code: Select all
procedure TFormReportAusfuehren.AllgemeinRichViewNormalerPlatzhalter(RVData : TCustomRVFormattedData; mSicherMemo : tppRichView; i : Integer);
var j, ParaNO, Style : Integer;
BR, ContinuePara : Boolean;
sText : String;
s : TRVRawByteString;
sTextList : TStrings;
item : TRVTextItemInfo;
begin
try
// loading field value in the stream
sText := RVData.GetItemTextW(i);
AllgemeinMemoSetzeFelder(False, mSicherMemo, sText);
// bei Richview ist das Zeile Unterdrücken einfacher zu realisieren. Im Gegensatz zu Richtext wird
// es deswegen nicht in AllgemeinMemoSetzeFelder gemacht sondern an dieser Stelle.
if trim(sText)=T_REPAUS_MEMOZEILEUNTERDRUECKEN then begin
RVData.DeleteItems(i, 1);
end
else begin
if pos(#13, sText)>0 then begin // Wurden Memofelder ersetzt mit hartem Return so sind es plötzlich mehr als eine Zeile
// und muß gesondert behandelt werden. Jede Zeile muß mit gleichem Stil eingefügt werden
sTextList := TStringList.Create;
sTextList.Text := sText;
ParaNo := RVData.GetItemPara(i);
BR := RVData.GetItem(i).BR;
Style := RVData.GetItemStyle(i);
ContinuePara := RVData.GetItem(i).SameAsPrev;
RVData.DeleteItems(i, 1); // altes Item wird gelöscht
// Jede Zeile wird nun als Item eingefügt
for j := sTextList.Count-1 downto 0 do begin
item := RichViewTextItemClass.Create(RVData);
s := sTextList[j];
item.ParaNo := ParaNo;
item.StyleNo := Style;
if j=0 then begin
item.SameAsPrev := ContinuePara;
item.BR := BR;
end;
item.Inserting(RVData, s, False);
RVData.Items.InsertObject(i, s, item);
item.Inserted(RVData, i);
end;
sTextList.Free; sTextList := nil;
end
else begin // einzeilges Item wird mit neuem Text ersetzt
if pos(T_REPAUS_MEMOZEILEUNTERDRUECKEN, sText)=1 then sText := copy(sText,2,length(sText));
RVData.SetItemTextW(i, sText);
end;
end;
except on E:Exception do SURunErrorReport(Self,'TFormReportAusfuehren.AllgemeinRichviewNormalerPlatzhalter', E); end;
end;
Posted: Thu Jun 13, 2013 11:57 am
by Sergey Tkachenko
If you use Delphi version prior to Delphi 2009, I suggest to change GetItemTextW to GetItemText.
Or you need to rewrite all text processing to use Unicode functions.
Posted: Tue Jun 18, 2013 5:53 am
by BernhardRoos
We are using Delphi XE3.
What do you mean with "Rewriting all text processing in uni code"? This code worked fine with previous version of RV and Delphi XE2.
What have I to change in the code above? Or should I change directly GetItemTextW in the source of Richview? If so, can you give me an example? Perhaps I can use the GetItemTextW source code from the previous version of RV?
Best wishes
Bernhard
Posted: Tue Jun 18, 2013 6:13 am
by BernhardRoos
Another question. Does older versions of RV run with Delphi XE3.
Some of our customers are very angry about this problem.
Best wishes
Bernhard
Posted: Tue Jun 18, 2013 7:18 am
by BernhardRoos
Now I have a solution which works for me.
Instead I'm using GetItemTextW, I'm now using GetItemTextR. The difference between GetItemTextW and GetItemTextR for Wingdings font is, that GetItemTextW returns '......' and GetItemTextR returns 'nnnnn' (in the old version also GetItemTextW returns 'nnnnn').
Now my question. What is the difference between this two functions? Should I also use SetItemTextR instead of SetItemTextW?
Best wishes
Bernhard
Posted: Tue Jun 18, 2013 3:09 pm
by Sergey Tkachenko
GetItemTextR and SetItemTextR are "low level" functions.
They work with the internal representation of text.
GetItemTextR returns ANSI string if the item contains ANSI text, or a raw byte string where two adjacent characters represent one Unicode character.
The same strings must be SetItemTextR. If you give it a string in a wrong representation, the document will be corrupted.
Actually, they should be avoided.
If AllgemeinMemoSetzeFelder does not corrupt sText, the problems may be caused by String <-> RawByteString conversion.
I'll try to modify your example.
Posted: Tue Jun 18, 2013 3:27 pm
by Sergey Tkachenko
Code: Select all
uses RVInsertItems;
procedure TFormReportAusfuehren.AllgemeinRichViewNormalerPlatzhalter(RVData : TCustomRVFormattedData; mSicherMemo : tppRichView; i : Integer);
var j, ParaNo, Style : Integer;
BR, ContinuePara : Boolean;
sText : String;
s : TRVRawByteString;
sTextList : TStrings;
begin
try
// loading field value in the stream
sText := RVData.GetItemTextW(i);
AllgemeinMemoSetzeFelder(False, mSicherMemo, sText);
// bei Richview ist das Zeile Unterdrücken einfacher zu realisieren. Im Gegensatz zu Richtext wird
// es deswegen nicht in AllgemeinMemoSetzeFelder gemacht sondern an dieser Stelle.
if trim(sText)=T_REPAUS_MEMOZEILEUNTERDRUECKEN then begin
RVData.DeleteItems(i, 1);
end
else begin
if pos(#13, sText)>0 then begin // Wurden Memofelder ersetzt mit hartem Return so sind es plötzlich mehr als eine Zeile
// und muß gesondert behandelt werden. Jede Zeile muß mit gleichem Stil eingefügt werden
sTextList := TStringList.Create;
sTextList.Text := sText;
ParaNo := RVData.GetItemPara(i);
BR := RVData.GetItem(i).BR;
Style := RVData.GetItemStyle(i);
ContinuePara := RVData.GetItem(i).SameAsPrev;
RVData.DeleteItems(i, 1); // altes Item wird gelöscht
// Jede Zeile wird nun als Item eingefügt
for j := sTextList.Count-1 downto 0 do begin
if (j=0) and ContinuePara then
ParaNo := -1;
RVInsertStringW(RVData, i, sTextList[j], Style, ParaNo);
if (j=0) and BR then
RVData.GetItem(i).BR := True;
end;
sTextList.Free; sTextList := nil;
end
else begin // einzeilges Item wird mit neuem Text ersetzt
if pos(T_REPAUS_MEMOZEILEUNTERDRUECKEN, sText)=1 then sText := copy(sText,2,length(sText));
RVData.SetItemTextW(i, sText);
end;
end;
except on E:Exception do SURunErrorReport(Self,'TFormReportAusfuehren.AllgemeinRichviewNormalerPlatzhalter', E); end;
end;
Posted: Wed Jun 19, 2013 6:23 am
by BernhardRoos
Thanks for the changes in my example.
But this doesn't solve the problem. The problem is in the line GetItemTextW. Instead of the characters 'nnnnn' I get some other characters ('......'). 'nnnnn' are the correct characters. In Wingdings this are the black rectangle.
If I'm using GetItemTextR all works as expected. I've changed now GetItemTextW in GetItemTextR and SetItemTextW in SetItemTextR. For this text processing I need the raw data (only the text), because I want replace the text with another text. In previous RV versions it worked also with GetItemTextW. But now it works only if I use GetItemTextR.
So far as I can see all Reports works fine with this change. I let you know, if I see any problems.
Best wishes
Bernhard