Wingdings font problem

General TRichView support forum. Please post your questions here
BernhardRoos
Posts: 104
Joined: Mon Nov 26, 2007 1:49 pm

Wingdings font problem

Post 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
Sergey Tkachenko
Site Admin
Posts: 17566
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

What is the source for displayed documents?
Do you use TppRichView or TppDBRichView?
Version of Delphi?
BernhardRoos
Posts: 104
Joined: Mon Nov 26, 2007 1:49 pm

Post by BernhardRoos »

I'm using tppRichView
Best wishes
Bernhard
BernhardRoos
Posts: 104
Joined: Mon Nov 26, 2007 1:49 pm

Post by BernhardRoos »

and I have Delphi XE3.
Best wishes
Bernhard
Sergey Tkachenko
Site Admin
Posts: 17566
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Can you send a sample project (as simple as possible) to richviewgmailcom?
BernhardRoos
Posts: 104
Joined: Mon Nov 26, 2007 1:49 pm

Post 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
Sergey Tkachenko
Site Admin
Posts: 17566
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post 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?
BernhardRoos
Posts: 104
Joined: Mon Nov 26, 2007 1:49 pm

Post 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;
Sergey Tkachenko
Site Admin
Posts: 17566
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post 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.
BernhardRoos
Posts: 104
Joined: Mon Nov 26, 2007 1:49 pm

Post 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
BernhardRoos
Posts: 104
Joined: Mon Nov 26, 2007 1:49 pm

Post 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
BernhardRoos
Posts: 104
Joined: Mon Nov 26, 2007 1:49 pm

Post 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
Sergey Tkachenko
Site Admin
Posts: 17566
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post 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.
Sergey Tkachenko
Site Admin
Posts: 17566
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post 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;
BernhardRoos
Posts: 104
Joined: Mon Nov 26, 2007 1:49 pm

Post 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
Post Reply