Recent

Author Topic: TDWEdit  (Read 7796 times)

CharlyTango

  • Full Member
  • ***
  • Posts: 171
Re: TDWEdit
« Reply #15 on: September 05, 2025, 01:18:26 pm »
I don't think it will be particularly well received if you're thinking of passing on ppu files. Lazarus is not Delphi, and even if it were technically possible, I can't imagine that it would be accepted by the community, if only from the point of view of platform independence.
Lazarus stable, Win32/64

hedgehog

  • Jr. Member
  • **
  • Posts: 75
Re: TDWEdit
« Reply #16 on: September 07, 2025, 07:32:59 am »
Hi, Ed78z!

How did you solve the problem described in this post?
https://forum.lazarus.freepascal.org/index.php/topic,64553.0.html

Can you provide an simple example of "Hello World!", or "Hello Word!" :) ?

Thanks

hedgehog

  • Jr. Member
  • **
  • Posts: 75
Re: TDWEdit
« Reply #17 on: September 07, 2025, 10:17:27 am »
Oh, of course, I know about that code word.

P.S. I just saw that you just commented out the lines in DX12.D2D1 that were causing the error

jianwt

  • Full Member
  • ***
  • Posts: 164
Re: TDWEdit
« Reply #18 on: September 10, 2025, 09:13:24 am »
@Ed78z
I ran the compiled program and input Chinese in TDWEdit. It perfectly supports Chinese input. But I don't know if this control can support the automatic line wrap function?

jianwt

  • Full Member
  • ***
  • Posts: 164
Re: TDWEdit
« Reply #19 on: September 19, 2025, 03:17:35 am »
I just added the SAVE and LOAD features...for the RTF format...it supports 80% of full RTF format, more than TRichMemo or KMemo
Still working on my own RTF units.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Windows, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.   DWEdit, QColors, QPapers, QRTFParser, QRTFSaver;
  10.  
  11. type
  12.   { TForm1 }
  13.   TForm1 = class(TForm)
  14.     Button1: TButton;
  15.     Button2: TButton;
  16.     procedure Button1Click(Sender: TObject);
  17.     procedure Button2Click(Sender: TObject);
  18.     procedure FormCreate(Sender: TObject);
  19.     procedure FormShow(Sender: TObject);
  20.     procedure DWEditSelStartChanged(Sender: TObject);
  21.     procedure DWEditZoomChanged(Sender: TObject);
  22.     procedure DWEditSelPageChanged(Sender: TObject);
  23.     procedure DWEditPageCountChanged(Sender: TObject);
  24.   private
  25.     DWEdit1:TDWEdit;
  26.     procedure UpdateCaption;
  27.     procedure SetupInitialText;
  28.     procedure ApplyCharacterFormatting;
  29.     procedure ApplySpecialFormatting;
  30.     procedure EmbedSampleImage;
  31.     procedure ApplyParagraphFormatting;
  32.   public
  33.   end;
  34.  
  35. var
  36.   Form1: TForm1;
  37.  
  38. implementation
  39.  
  40. {$R *.lfm}
  41.  
  42. { TForm1 }
  43.  
  44. procedure TForm1.FormCreate(Sender: TObject);
  45. begin
  46.   DWEdit1:=TDWEdit.Create(Self);
  47.   with DWEdit1 do
  48.   begin
  49.     Parent := Self;
  50.     SetBounds(0,50,700,550);
  51.     Font.Name := 'Segoe UI';
  52.     Font.Size := 12;
  53.     WordWrap := wwNoWrap;
  54.     TextMargin := 10;
  55.     OnSelStartChange := @DWEditSelStartChanged;
  56.     OnZoomChange := @DWEditZoomChanged;
  57.     OnSelPageChange := @DWEditSelPageChanged;
  58.     OnPageCountChange := @DWEditPageCountChanged;
  59.  
  60.     ZoomFactor := 1.00;
  61.  
  62.     ViewMode:=vmWebView;
  63.     ShowPaperBoundaries:=True;//ONLY in WebView: true/false
  64.     PaperSize:=ppsLetter;
  65.     PaperMargin:=mgNormal;
  66.  
  67.     GridVisible := True;
  68.     GridSize := Point(20, 20);
  69.     GridColor := QColors.clBlue;
  70.     GridStyle := gsLines;// gsLines;
  71.     GridOpacity := 0.1;// 0.0 .. 1.0
  72.   end;
  73. end;
  74.  
  75. procedure TForm1.Button1Click(Sender: TObject);
  76. var
  77.   FS: TFileStream;
  78. begin
  79.   FS := TFileStream.Create('sample.rtf', fmCreate);
  80.   try
  81.     DWEdit1.SaveToRTFStream(FS);
  82.   finally
  83.     FS.Free;
  84.   end;
  85. end;
  86.  
  87. procedure TForm1.Button2Click(Sender: TObject);
  88. var
  89.   FS: TFileStream;
  90. begin
  91.   if FileExists('sample.rtf') then
  92.   begin
  93.     FS := TFileStream.Create('sample.rtf', fmOpenRead);
  94.     try
  95.       DWEdit1.LoadFromRTFStream(FS);
  96.     finally
  97.       FS.Free;
  98.     end;
  99.   end;
  100. end;
  101.  
  102. procedure TForm1.SetupInitialText;
  103. var
  104.   AllText: TStringList;
  105. begin
  106.   AllText := TStringList.Create;
  107.   try
  108.     AllText.Add('Welcome to DWEdit! 🚀 Here are some features:');
  109.     AllText.Add('Ligatures & Stylistic Alternates (in Gabriola font).');
  110.     AllText.Add('Mix colors, sizes, and styles like bold & italic.');
  111.     AllText.Add('Highlighting with background colors is easy.');
  112.     AllText.Add('Custom underlines for emphasis or spellcheck.');
  113.     AllText.Add('Formulas: H2O and E=mc2 (Superscript/Subscript).');
  114.     AllText.Add('Spacing can be adjusted per character.');
  115.     AllText.Add('You can even embed  images "flowing" within text!');
  116.     AllText.Add('Paragraph''s alignment: Left, Right, Center & Justified.');
  117.     AllText.Add('Adjustable space between lines: (next three lines:)');
  118.     AllText.Add('🙂😊😃😄😆😍😘😗😉 👨🏻👩🏽👧🏾👦🏿 (different skin tones)');
  119.     AllText.Add('Full copy/paste & undo/redo system....');
  120.     AllText.Add('"Old Persian": 𐎠𐎡𐎢𐎣𐎤𐎥𐎦𐎧𐎨𐎩𐎪𐎫𐎬𐎭 (A "Left-to-Right" script language)');
  121.     AllText.Add('The next line is "New Persian", which is a Right-to-Left language:');
  122.     AllText.Add('این یک جمله نمونه به زبان فارسی است.');
  123.     AllText.Add(LineEnding+LineEnding);
  124.     AllText.TrailingLineBreak := False;
  125.     DWEdit1.Lines.Text := AllText.Text;
  126.   finally
  127.     AllText.Free;
  128.   end;
  129. end;
  130.  
  131. procedure TForm1.ApplyCharacterFormatting;
  132. var
  133.   attrs: TStyleAttributes;
  134. begin
  135.   // Bold and Italicize 'DWEdit!'
  136.   DWEdit1.SelStart := 11; DWEdit1.SelLength := 7;
  137.   DWEdit1.SetSelectionFontStyle([fsBold, fsItalic], smAdd);
  138.  
  139.   // Mix colors, sizes, and styles
  140.   attrs := Default(TStyleAttributes);
  141.  
  142.   attrs.AttributesSet := [saFontColor]; attrs.FontColor := clBlue;
  143.   DWEdit1.SelStart := 105; DWEdit1.SelLength := 6; DWEdit1.SetSelectionAttributes(attrs); // 'colors'
  144.  
  145.   attrs.AttributesSet := [saFontSize]; attrs.FontSize := 25;
  146.   DWEdit1.SelStart := 113; DWEdit1.SelLength := 5; DWEdit1.SetSelectionAttributes(attrs); // 'sizes'
  147.  
  148.   attrs.AttributesSet := [saFontStyle]; attrs.FontStyle := [fsBold];
  149.   DWEdit1.SelStart := 136; DWEdit1.SelLength := 4; DWEdit1.SetSelectionAttributes(attrs); // 'bold'
  150.  
  151.   attrs.FontStyle := [fsItalic];
  152.   DWEdit1.SelStart := 143; DWEdit1.SelLength := 6; DWEdit1.SetSelectionAttributes(attrs); // 'italic'
  153.  
  154.   // Background Color (Highlighting)
  155.   DWEdit1.SelStart := 152; DWEdit1.SelLength := 12;
  156.   attrs := Default(TStyleAttributes);
  157.   attrs.AttributesSet := [saBackgroundColor];
  158.   attrs.BackgroundColor := QColors.clLightGreen;
  159.   DWEdit1.SetSelectionAttributes(attrs);
  160. end;
  161.  
  162. procedure TForm1.ApplySpecialFormatting;
  163. var
  164.   underline: TDecoration;
  165. begin
  166.   // OpenType Features
  167.   DWEdit1.SelStart := 47; DWEdit1.SelLength := 52;
  168.   DWEdit1.SetSelectionFont('Gabriola');
  169.   DWEdit1.SetSelectionFeatures([ffStandardLigatures, ffStylisticSet1]);
  170.  
  171.   // Custom Wavy Red Underline
  172.   DWEdit1.SelStart := 205; DWEdit1.SelLength := 10;
  173.   underline.Enabled := True;
  174.   underline.Style := dsWavy;
  175.   underline.Color := QColors.clRed_Crayola;
  176.   underline.Thickness := 1.0;
  177.   underline.Offset := 3.0;
  178.   DWEdit1.SetSelectionUnderline(underline);
  179.  
  180.   // Subscript and Superscript
  181.   DWEdit1.SetBaselineScriptForRange(256, 1, bsSubscript); // '2' in H2O
  182.   DWEdit1.SetBaselineScriptForRange(267, 1, bsSuperscript); // '2' in E=mc2
  183.  
  184.   // Character Spacing
  185.   DWEdit1.SetCharacterSpacingForRange(295, 7, 5.0); // 'Spacing'
  186. end;
  187.  
  188. procedure TForm1.EmbedSampleImage;
  189. var
  190.   bmp: TBitmap;   pic: TPicture;
  191. begin
  192.   DWEdit1.SelStart := 354;  DWEdit1.SelLength := 0;
  193.   bmp := TBitmap.Create;
  194.   pic := TPicture.Create;
  195.   try
  196.     // --- Insert Bitmap ---
  197.     bmp.SetSize(50, 30);
  198.     bmp.Canvas.Brush.Color := QColors.clRed_Pantone;
  199.     bmp.Canvas.FillRect(Rect(0, 0, 50, 30));
  200.     bmp.Canvas.Brush.Color := QColors.clWhite;
  201.     bmp.Canvas.Font.Size := 14;
  202.     bmp.Canvas.TextOut(4, 2, 'Ed78');
  203.     DWEdit1.InsertImage(bmp);
  204.     // --- Insert any pictures from file ---
  205.     DWEdit1.SelStart := 786;   DWEdit1.SelLength := 1;
  206.     DWEdit1.Alignment := paCenter;
  207.     pic.LoadFromFile('Image.png');
  208.     DWEdit1.InsertImage(pic, 0.65);// scale to 65%
  209.   finally
  210.     bmp.Free;
  211.     pic.Free;
  212.   end;
  213. end;
  214.  
  215. procedure TForm1.ApplyParagraphFormatting;
  216. begin
  217.   // Paragraph Alignment: Left
  218.   DWEdit1.SelStart := 0; DWEdit1.SelLength := 100;
  219.   DWEdit1.Alignment := paLeft;
  220.  
  221.   // Paragraph Alignment: Center
  222.   DWEdit1.SelStart := 160; DWEdit1.SelLength := 100;
  223.   DWEdit1.Alignment := paCenter;
  224.  
  225.   // Paragraph Alignment: Right
  226.   DWEdit1.SelStart := 300; DWEdit1.SelLength := 50;
  227.   DWEdit1.Alignment := paRight;
  228.  
  229.   // Paragraph Alignment: Justified; When: wwNoWrap;
  230.   DWEdit1.SelStart := 400; DWEdit1.SelLength := 1;
  231.   DWEdit1.Alignment := paJustified;
  232.  
  233.   // Set the line spacing
  234.   DWEdit1.SetLineSpacingMultiplier(444, 180, 2.0); //Double space
  235.  
  236.   // Set BiDIMode for the R2L Persian language
  237.   DWEdit1.SelStart := 750;  DWEdit1.SelLength := 1;
  238.   DWEdit1.SetSelectionBiDiMode(bdmRightToLeft);
  239.   DWEdit1.Alignment := paRight;
  240. end;
  241.  
  242. procedure TForm1.FormShow(Sender: TObject);
  243. begin
  244.   DWEdit1.BeginUpdate; // Disable Undo System
  245.   try
  246.     SetupInitialText;
  247.     ApplyCharacterFormatting;
  248.     ApplySpecialFormatting;
  249.     EmbedSampleImage;
  250.     ApplyParagraphFormatting;
  251.     // Important: Reset selection and set focus
  252.     DWEdit1.SelStart := 0;
  253.     DWEdit1.SelLength := 0;
  254.     DWEdit1.SetFocus;
  255.   finally
  256.     DWEdit1.EndUpdate; // Re-enable Undo System
  257.   end;
  258. end;
  259.  
  260. procedure TForm1.UpdateCaption;
  261. var
  262.   Line, Col: Integer;
  263.   P: TPoint;
  264.   CurrentPage, TotalPage: Integer;
  265. begin
  266.   if not Assigned(DWEdit1) then Exit;
  267.  
  268.   // Get all the info
  269.   DWEdit1.GetSelPage(CurrentPage);
  270.   DWEdit1.GetPageCount(TotalPage);
  271.   DWEdit1.GetCaretLocation(Line, Col);
  272.   DWEdit1.GetCaretPos(P);
  273.  
  274.   // Format the caption
  275.   Self.Caption := Format(
  276.     'SelStart: %d (Line: %d, Col: %d) or in Pixels[X: %d, Y: %d] — Zoom: %d%% — Page: %d of %d',
  277.     [DWEdit1.SelStart, Line + 1, Col + 1, P.X, P.Y, Round(DWEdit1.ZoomFactor * 100), CurrentPage, TotalPage]
  278.   );
  279. end;
  280.  
  281. procedure TForm1.DWEditSelStartChanged(Sender: TObject);
  282. begin
  283.   UpdateCaption;
  284. end;
  285.  
  286. procedure TForm1.DWEditZoomChanged(Sender: TObject);
  287. begin
  288.   UpdateCaption;
  289. end;
  290.  
  291. procedure TForm1.DWEditSelPageChanged(Sender: TObject);
  292. begin
  293.   UpdateCaption;
  294. end;
  295.  
  296. procedure TForm1.DWEditPageCountChanged(Sender: TObject);
  297. begin
  298.   UpdateCaption;
  299. end;
  300.  
  301. end.

@Ed78z

Can TDWEdit.pas be made public? When can it be made public?
« Last Edit: September 19, 2025, 03:23:24 am by jianwt »

Ed78z

  • Jr. Member
  • **
  • Posts: 76
Re: TDWEdit
« Reply #20 on: September 21, 2025, 12:33:16 am »
Hi Jianwt,
I'm still working on it, I just fixed some bugs for: copy-paste From/To MS-WORD and Load/Save From/To .RTF file...

My goal to create a new Lazarus component with modern features like MS WORD, was very ambitious! and I need to stop going further! since it needs a team not just me alone!

So, whatever I developed till now, it's enough! (TDWEdit is still far far advanced than TRichMemo)... I will fix couple of tiny bugs as soon as I can.
« Last Edit: October 08, 2025, 12:11:45 pm by Ed78z »

hedgehog

  • Jr. Member
  • **
  • Posts: 75
Re: TDWEdit
« Reply #21 on: October 11, 2025, 09:25:33 am »
Hi

It seems to me that for the dark mode you should choose a more contrasting highlight color, as, for example, is done in VSСode

chrv

  • Jr. Member
  • **
  • Posts: 71
Re: TDWEdit
« Reply #22 on: November 17, 2025, 11:01:49 am »
Hi,
This component seems very interesting.
Unfortunately, i don't know where to find it for testing.
Win32 Laz 2.0.12 FPC 3.2.0 AND Laz 3.4 FPC 3.2.2

Ed78z

  • Jr. Member
  • **
  • Posts: 76
Re: TDWEdit
« Reply #23 on: November 20, 2025, 02:03:05 am »
Hi chrv, I was very busy last month... I was able to add paper rotation, paper size and extensive "Events" properties to the component... I guess next month I can release it....

Update: I added native format (.DWE) save/load functionality for maximum/advance features that are not existed in the RTF format.

Code: Pascal  [Select][+][-]
  1. unit MainForm;
  2.  
  3. {Sample Application for DWEdit Component}
  4.  
  5. {$mode objfpc}{$H+}
  6.  
  7. interface
  8.  
  9. uses
  10.   Windows, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  11.   Clipbrd, ComCtrls, ExtCtrls,
  12.  
  13.   DWEdit, QColors, QPapers, QRTFParser, QStatusBar, QThemeColors, QTheme,
  14.   DWSharedTypes, QLanguages, QRTFImage, QScrollBar, QRTFSaver;
  15.  
  16. Const
  17.   CM_DELAYED_INIT = WM_USER + 200;// for UpdateCaption at the first run
  18.  
  19. type
  20.   { TForm1 }
  21.   TForm1 = class(TForm)
  22.     Button1, Button2: TButton;
  23.     Button10: TButton;
  24.     Button3: TButton;
  25.     Button4: TButton;
  26.     Button5: TButton;
  27.     Button6: TButton;
  28.     Button7: TButton;
  29.     Button8: TButton;
  30.     Button9: TButton;
  31.     ColorButton1: TColorButton;
  32.     Label1: TLabel;
  33.     Panel1: TPanel;
  34.  
  35.  
  36.     procedure Button10Click(Sender: TObject);
  37.     procedure Button1Click(Sender: TObject);
  38.     procedure Button2Click(Sender: TObject);
  39.     procedure Button3Click(Sender: TObject);
  40.     procedure Button4Click(Sender: TObject);
  41.     procedure Button5Click(Sender: TObject);
  42.     procedure Button6Click(Sender: TObject);
  43.     procedure Button7Click(Sender: TObject);
  44.     procedure Button8Click(Sender: TObject);
  45.     procedure Button9Click(Sender: TObject);
  46.     procedure ColorButton1ColorChanged(Sender: TObject);
  47.     procedure FormCreate(Sender: TObject);
  48.     procedure FormActivate(Sender: TObject);
  49.     procedure DWEditSelStartChanged(Sender: TObject);
  50.     procedure DWEditZoomChanged(Sender: TObject);
  51.     procedure DWEditSelPageChanged(Sender: TObject);
  52.     procedure DWEditPageCountChanged(Sender: TObject);
  53.  
  54.   private
  55.     DWEdit1:TDWEdit;// disable if installed
  56.     QStatusBar1: TQStatusBar;// disable if installed
  57.     FFirstShow: Boolean;
  58.  
  59.     Procedure InitStatusBar;
  60.     procedure UpdateCaption;
  61.     procedure CMDelayedInit(var {%H-}Message: TMessage); message CM_DELAYED_INIT;
  62.     procedure SetupInitialText;
  63.     procedure ApplyCharacterFormatting;
  64.     procedure ApplySpecialFormatting;
  65.     procedure EmbedSampleImage;
  66.     procedure ApplyParagraphFormatting;
  67.   public
  68.   end;
  69.  
  70.  
  71. var
  72.   Form1: TForm1;
  73.  
  74. implementation
  75.  
  76. {$R *.lfm}
  77.  
  78. { TForm1 }
  79.  
  80. Procedure TForm1.InitStatusBar;
  81. Begin
  82.   QStatusBar1 := TQStatusBar.Create(Self);
  83.   QStatusBar1.Parent := Self;
  84.   QStatusBar1.Align := alBottom;
  85.   QStatusBar1.SimplePanel := false;
  86.   QStatusBar1.BidiMode:=bdLeftToRight;
  87.   with QStatusBar1.Panels.Add do
  88.   begin
  89.     Style:=psNormal;
  90.     Width := 70; Alignment := taLeftJustify;
  91.     Text := 'Panel[0]';
  92.   end;
  93.   with QStatusBar1.Panels.Add do
  94.   begin
  95.     Style:=psSuccess;
  96.     Width := 70; Alignment := taCenter;
  97.     Text := 'Panel[1]';
  98.   end;
  99.   with QStatusBar1.Panels.Add do
  100.   begin
  101.     Style:=psWarning;
  102.     Width := 70; Alignment := taRightJustify;
  103.     Text := 'Panel[2]';
  104.   end;
  105.   with QStatusBar1.Panels.Add do
  106.   begin
  107.     Style:=psError;
  108.     Width := 70; Alignment := taLeftJustify;
  109.     Text := 'Panel[3]';
  110.   end;
  111. end;
  112.  
  113. procedure TForm1.FormCreate(Sender: TObject);
  114. begin
  115.   FFirstShow := True;
  116.  
  117.   DWEdit1:=TDWEdit.Create(Self);
  118.   with DWEdit1 do
  119.   begin
  120.     Parent := Self;
  121.     Align:=alClient;
  122.     Font.Name := 'Segoe UI';
  123.     Font.Size := 12;
  124.     WordWrap:=wwCharacter;
  125.     OnSelStartChange := @DWEditSelStartChanged;
  126.     OnZoomChange := @DWEditZoomChanged;
  127.     OnSelPageChange := @DWEditSelPageChanged;
  128.     OnPageCountChange := @DWEditPageCountChanged;
  129.  
  130.     //PaperSize:=ppsHalf_Letter;
  131.     PaperSize:=ppsLetter;
  132.     GridVisible := True;
  133.     GridSize := Point(20, 20);
  134.     GridColor := clLightBlue;
  135.     GridStyle := gsLines;//gsDots;
  136.     GridOpacity := 0.4;
  137.     ZoomFactor:=0.7;
  138.   end;
  139.  
  140.   InitStatusBar;
  141. end;
  142.  
  143. procedure TForm1.FormActivate(Sender: TObject);
  144. begin
  145.   if FFirstShow then
  146.   begin
  147.     FFirstShow := False;
  148.     ColorButton1.ButtonColor := $00FF0000;//pure blue
  149.     ApplyTheme(CurrentTheme, ColorButton1.ButtonColor);
  150.     DWEdit1.SetTheme(CurrentTheme, ColorButton1.ButtonColor);
  151.  
  152.     Label1.Font.Color:=ColorButton1.ButtonColor;
  153.  
  154.     DWEdit1.BeginUpdate;
  155.     try
  156.       SetupInitialText;
  157.       ApplyCharacterFormatting;
  158.       ApplySpecialFormatting;
  159.       EmbedSampleImage;
  160.       ApplyParagraphFormatting;
  161.  
  162.       DWEdit1.SelStart := 0;
  163.       DWEdit1.SelLength := 0;
  164.       DWEdit1.SetFocus;
  165.     finally
  166.       DWEdit1.EndUpdate;
  167.     end;
  168.     DWEdit1.ClearUndoHistory;
  169.     // Queue the final layout/caption update for the next CPU cycle.
  170.     // This ensures it runs AFTER the form has physically resized to the screen.
  171.     PostMessage(Handle, CM_DELAYED_INIT, 0, 0);
  172.   end;//FFirstShow
  173.  
  174. end;
  175.  
  176. procedure TForm1.Button1Click(Sender: TObject);
  177. var      // SAVE to RTF
  178.   FS: TFileStream;
  179.   FN: String;
  180. begin
  181.   FN := ExpandFileName('sample.rtf');
  182.   FS := TFileStream.Create(FN, fmCreate);
  183.   try
  184.     DWEdit1.SaveToRTFStream(FS);
  185.   finally
  186.     FS.Free;
  187.   end;
  188.   ShowMessage(FN + LineEnding + 'Has been Saved!');
  189.   DWEdit1.SetFocus;
  190. end;
  191.  
  192. procedure TForm1.Button10Click(Sender: TObject);
  193. var
  194.   FS: TFileStream;
  195.   FN: String;
  196.   OldReductionState: Boolean;
  197. begin
  198.   if DWEdit1.ViewLayout = vmWebLayout then
  199.   begin
  200.     DWEdit1.ViewLayout := vmPaperLayout;
  201.     Button3.Caption := 'Web Layout';
  202.     UpdateCaption;
  203.     //Allow the engine to recalculate metrics before saving
  204.     Application.ProcessMessages;
  205.   end;
  206.  
  207.   FN := ExpandFileName('sample.pdf');
  208.   try
  209.     FS := TFileStream.Create(FN, fmCreate);
  210.   except
  211.     on E: Exception do
  212.     begin
  213.       ShowMessage('Error creating file. Check if it is open in another app.');
  214.       Exit;
  215.     end;
  216.   end;
  217.  
  218.   OldReductionState := DWEdit1.DWESizeReduction;
  219.   try
  220.     try
  221.       DWEdit1.DWESizeReduction := True;
  222.       Screen.Cursor := crHourGlass;
  223.       try
  224.         DWEdit1.SaveToPDFStream(FS);
  225.       finally
  226.         Screen.Cursor := crDefault;
  227.       end;
  228.  
  229.       ShowMessage('PDF Saved Successfully:' + sLineBreak + FN);
  230.     except
  231.       on E: Exception do
  232.         ShowMessage('Export Failed: ' + E.Message);
  233.     end;
  234.   finally
  235.     DWEdit1.DWESizeReduction := OldReductionState;
  236.     FS.Free;
  237.   end;
  238.  
  239.   DWEdit1.SetFocus;
  240. end;
  241.  
  242. procedure TForm1.Button2Click(Sender: TObject);
  243. var        // LOAD from RTF
  244.   FS: TFileStream;
  245. begin
  246.   if FileExists('sample.rtf') then
  247.   begin
  248.     FS := TFileStream.Create('sample.rtf', fmOpenRead);
  249.     try
  250.       DWEdit1.LoadFromRTFStream(FS);
  251.     finally
  252.       FS.Free;
  253.     end;
  254.     UpdateCaption;
  255.     DWEdit1.SetFocus;
  256.   end;
  257. end;
  258.  
  259. procedure TForm1.Button3Click(Sender: TObject);
  260. begin
  261.   // Switching TO Web Layout
  262.   if DWEdit1.ViewLayout = vmPaperLayout then
  263.   begin
  264.     DWEdit1.ViewLayout := vmWebLayout;
  265.     // Web Layout: "Infinite" horizontal canvas
  266.     DWEdit1.WordWrap := wwNoWrap;
  267.     Button3.Caption := 'Web Layout';
  268.   end
  269.   // Switching TO Paper Layout
  270.   else if DWEdit1.ViewLayout = vmWebLayout then
  271.   begin
  272.     DWEdit1.ViewLayout := vmPaperLayout;
  273.     // Paper Layout: Standard document wrapping
  274.     DWEdit1.WordWrap := wwWrap;
  275.     Button3.Caption := 'Paper Layout';
  276.   end;
  277.   UpdateCaption;
  278.   DWEdit1.SetFocus;
  279. end;
  280.  
  281. procedure TForm1.Button4Click(Sender: TObject);
  282. var
  283.   NewAccentColor: TColor;
  284. begin
  285.   NewAccentColor := ColorButton1.ButtonColor;
  286.  
  287.   if CurrentTheme = tmDark then
  288.   begin
  289.     Button4.Caption := 'Light Mode';
  290.     CurrentTheme := tmLight;
  291.   end else
  292.   begin
  293.     Button4.Caption := 'Dark Mode';
  294.     CurrentTheme := tmDark;
  295.   end;
  296.  
  297.   ApplyTheme(CurrentTheme, NewAccentColor);
  298.   DWEdit1.SetTheme(CurrentTheme, NewAccentColor);
  299.  
  300.   DWEdit1.SetFocus;
  301. end;
  302.  
  303. procedure TForm1.Button5Click(Sender: TObject);
  304. begin
  305.   if DWEdit1.PaperSize = ppsLetter then
  306.   begin
  307.     DWEdit1.PaperSize := ppsHalf_Letter;
  308.     Button5.Caption := 'To Letter';
  309.   end
  310.   else
  311.   begin
  312.     DWEdit1.PaperSize := ppsLetter;
  313.     Button5.Caption := 'To Half Letter';
  314.   end;
  315.   UpdateCaption;
  316.   DWEdit1.SetFocus;
  317. end;
  318.  
  319. procedure TForm1.Button6Click(Sender: TObject);
  320. begin
  321.   if DWEdit1.PaperOrientation = ppoPortrait then
  322.   begin
  323.     // Switch to Landscape
  324.     DWEdit1.PaperOrientation := ppoLandscape;
  325.     Button6.Caption := 'To Portrait';
  326.   end
  327.   else
  328.   begin
  329.     // Switch back to Portrait
  330.     DWEdit1.PaperOrientation := ppoPortrait;
  331.     Button6.Caption := 'To Landscape';
  332.   end;
  333.   UpdateCaption;
  334.   DWEdit1.SetFocus;
  335. end;
  336.  
  337. procedure TForm1.Button7Click(Sender: TObject);
  338. begin
  339.   if DWEdit1.PaperMargin = mgNormal then
  340.   begin
  341.     DWEdit1.PaperMargin := mgCustom;
  342.     Button7.Caption := 'Margin: Custom';
  343.   end
  344.   else
  345.   begin
  346.     DWEdit1.PaperMargin := mgNormal;
  347.     Button7.Caption := 'Margin: Normal';
  348.   end;
  349.   UpdateCaption;
  350.   DWEdit1.SetFocus;
  351. end;
  352.  
  353. procedure TForm1.Button8Click(Sender: TObject);
  354. var
  355.   FS: TFileStream;
  356. begin // Load DWE native format
  357.   if FileExists('sample.dwe') then
  358.   begin
  359.     FS := TFileStream.Create('sample.dwe', fmOpenRead);
  360.     try
  361.       DWEdit1.LoadFromNativeStream(FS);
  362.     finally
  363.       FS.Free;
  364.     end;
  365.     UpdateCaption;
  366.     DWEdit1.SetFocus;
  367.   end;
  368. end;
  369.  
  370. procedure TForm1.Button9Click(Sender: TObject);
  371. var
  372.   FS: TFileStream;
  373.   FN: String;
  374.   OldReductionState: Boolean;
  375. begin // Save DWE native format
  376.   FN := ExpandFileName('sample.dwe');
  377.   FS := TFileStream.Create(FN, fmCreate);
  378.   OldReductionState := DWEdit1.DWESizeReduction;
  379.   try
  380.     DWEdit1.DWESizeReduction := True; // Use JPEG for file compactness
  381.     DWEdit1.SaveToNativeStream(FS);
  382.   finally
  383.     DWEdit1.DWESizeReduction := OldReductionState;
  384.     FS.Free;
  385.   end;
  386.   ShowMessage(FN + LineEnding + 'Has been Saved!');
  387.   DWEdit1.SetFocus;
  388. end;
  389.  
  390. procedure TForm1.ColorButton1ColorChanged(Sender: TObject);
  391. var
  392.   NewAccentColor: TColor;
  393. begin
  394.   NewAccentColor := ColorButton1.ButtonColor;
  395.  
  396.   ApplyTheme(CurrentTheme, NewAccentColor);
  397.   DWEdit1.SetTheme(CurrentTheme, NewAccentColor);
  398.  
  399.   Label1.Font.Color:=NewAccentColor;
  400.   DWEdit1.SetFocus;
  401. end;
  402.  
  403. procedure TForm1.SetupInitialText;
  404. var
  405.   AllText: TStringList;
  406. begin
  407.   AllText := TStringList.Create;
  408.   try
  409.     AllText.Add('Welcome to DWEdit! 🚀 Here are some features:');
  410.     AllText.Add('Ligatures & Stylistic Alternates (in Gabriola font).');
  411.     AllText.Add('Mix colors, sizes, and styles like bold & italic.');
  412.     AllText.Add('Highlighting with background colors is easy.');
  413.     AllText.Add('Custom underlines for emphasis or spellcheck.');
  414.     AllText.Add('Formulas: H2O and E=mc2 (Superscript/Subscript).');
  415.     AllText.Add('Spacing can be adjusted per character.');
  416.     AllText.Add('You can even embed  images "flowing" within text!');
  417.     AllText.Add('Paragraph''s alignment: Left, Right, Center & Justified.');
  418.     AllText.Add('Adjustable space between lines: (next three lines:)');
  419.     AllText.Add('🙂😊😃😄😆😍😘😗😉👨🏻👩🏽👧🏾👦🏿 (different skin tones)');
  420.     AllText.Add('Full copy/paste & undo/redo system....');
  421.     AllText.Add('"Old Persian": 𐎠𐎡𐎢𐎣𐎤𐎥𐎦𐎧𐎨𐎩𐎪𐎫𐎬𐎭 (A "Left-to-Right" script language)');
  422.     AllText.Add('The next line is "New Persian", which is a Right-to-Left language:');
  423.     AllText.Add('این یک جمله نمونه به زبان فارسی است.');
  424.     AllText.Add(LineEnding+LineEnding+LineEnding+LineEnding+LineEnding);
  425.     AllText.TrailingLineBreak := False;
  426.     DWEdit1.Lines.Text := AllText.Text;
  427.   finally
  428.     AllText.Free;
  429.   end;
  430. end;
  431.  
  432. procedure TForm1.ApplyCharacterFormatting;
  433. var
  434.   attrs: TStyleAttributes;
  435. begin
  436.   DWEdit1.SelStart := 11; DWEdit1.SelLength := 7;
  437.   DWEdit1.SetSelectionFontStyle([fsBold, fsItalic], smAdd);
  438.  
  439.   attrs := Default(TStyleAttributes);
  440.  
  441.   attrs.AttributesSet := [saFontColor]; attrs.FontColor := clBlue;
  442.   DWEdit1.SelStart := 105; DWEdit1.SelLength := 6; DWEdit1.SetSelectionAttributes(attrs);
  443.  
  444.   attrs.AttributesSet := [saFontSize]; attrs.FontSize := 25;
  445.   DWEdit1.SelStart := 113; DWEdit1.SelLength := 5; DWEdit1.SetSelectionAttributes(attrs);
  446.  
  447.   attrs.AttributesSet := [saFontStyle]; attrs.FontStyle := [fsBold];
  448.   DWEdit1.SelStart := 136; DWEdit1.SelLength := 4; DWEdit1.SetSelectionAttributes(attrs);
  449.  
  450.   attrs.FontStyle := [fsItalic];
  451.   DWEdit1.SelStart := 143; DWEdit1.SelLength := 6; DWEdit1.SetSelectionAttributes(attrs);
  452.  
  453.   // Background Color (Highlighting)
  454.   DWEdit1.SelStart := 152; DWEdit1.SelLength := 12;
  455.   attrs := Default(TStyleAttributes);
  456.   attrs.AttributesSet := [saBackgroundColor, saFontColor];
  457.   attrs.BackgroundColor := GetThemeColor(tcAccentDefault);
  458.   attrs.FontColor := GetThemeColor(tcTextOnAccentPrimary);
  459.   DWEdit1.SetSelectionAttributes(attrs);
  460. end;
  461.  
  462. procedure TForm1.ApplySpecialFormatting;
  463. var
  464.   underline: TDecoration;
  465. begin
  466.   // OpenType Features
  467.   DWEdit1.SelStart := 47; DWEdit1.SelLength := 52;
  468.   DWEdit1.SetSelectionFont('Gabriola');
  469.   DWEdit1.SetSelectionFeatures([ffStandardLigatures, ffStylisticSet1]);
  470.  
  471.   // Custom Underline
  472.   DWEdit1.SelStart := 205; DWEdit1.SelLength := 10;
  473.   underline.Enabled := True;
  474.   underline.Style := dsDoubleWave;
  475.   underline.Color := QColors.clRed;
  476.   DWEdit1.SetSelectionUnderline(underline);
  477.  
  478.   // Subscript and Superscript
  479.   DWEdit1.SetBaselineScriptForRange(256, 1, bsSubscript); // '2' in H2O
  480.   DWEdit1.SetBaselineScriptForRange(267, 1, bsSuperscript); // '2' in E=mc2
  481.  
  482.   // Character Spacing
  483.   DWEdit1.SetCharacterSpacingForRange(295, 7, 5.0); // 'Spacing'
  484. end;
  485.  
  486. procedure TForm1.EmbedSampleImage;
  487. var
  488.   bmp: TBitmap;   pic: TPicture;
  489. begin
  490.   DWEdit1.SelStart := 354;  DWEdit1.SelLength := 0;
  491.   bmp := TBitmap.Create;
  492.   pic := TPicture.Create;
  493.   try
  494.     // --- Insert Bitmap ---
  495.     bmp.SetSize(50, 30);
  496.     bmp.Canvas.Brush.Color := QColors.clRed_Pantone;
  497.     bmp.Canvas.FillRect(Rect(0, 0, 50, 30));
  498.     bmp.Canvas.Brush.Color := QColors.clWhite;
  499.     bmp.Canvas.Font.Size := 14;
  500.     bmp.Canvas.TextOut(4, 2, 'Ed78');
  501.     DWEdit1.InsertImage(bmp);
  502.     // --- Insert any pictures from file ---
  503.     DWEdit1.SelStart := 787;   DWEdit1.SelLength := 1;
  504.     DWEdit1.Alignment := paCenter;
  505.     pic.LoadFromFile('Image.png');
  506.     DWEdit1.InsertImage(pic, 0.65);// scale to 65%
  507.   finally
  508.     bmp.Free;
  509.     pic.Free;
  510.   end;
  511. end;
  512.  
  513. procedure TForm1.ApplyParagraphFormatting;
  514. begin
  515.   DWEdit1.SelStart := 0; DWEdit1.SelLength := 100;
  516.   DWEdit1.Alignment := paLeft;
  517.  
  518.   DWEdit1.SelStart := 160; DWEdit1.SelLength := 100;
  519.   DWEdit1.Alignment := paCenter;
  520.  
  521.   DWEdit1.SelStart := 300; DWEdit1.SelLength := 50;
  522.   DWEdit1.Alignment := paRight;
  523.  
  524.   DWEdit1.SelStart := 400; DWEdit1.SelLength := 1;
  525.   DWEdit1.Alignment := paJustified;
  526.  
  527.   //lsSingle, lsOneHalf, lsDouble, lsMultiple, lsAtLeast, lsExactly
  528.   //DWEdit1.SetLineSpacing(444, 180, lsAtLeast, 15.0);
  529.   DWEdit1.SetLineSpacing(444, 180, lsDouble);
  530.  
  531.   // Set BiDIMode for the R2L Persian language
  532.   DWEdit1.SelStart := 750;  DWEdit1.SelLength := 1;
  533.   DWEdit1.SetSelectionBiDiMode(bdRightToLeft);
  534.   DWEdit1.Alignment := paRight;
  535. end;
  536.  
  537. procedure TForm1.UpdateCaption;
  538. var
  539.   Line, Col: Integer;
  540.   PP, PD: TPoint;
  541.   CurrentPage, TotalPage: Integer;
  542. begin
  543.   if not Assigned(DWEdit1) then Exit;
  544.  
  545.   // Get all the info
  546.   DWEdit1.GetSelPage(CurrentPage);
  547.   DWEdit1.GetPageCount(TotalPage);
  548.   DWEdit1.GetCaretLocation(Line, Col);
  549.   DWEdit1.GetCaretPos(PP);
  550.   DWEdit1.GetCaretPosDIP(PD);
  551.  
  552.   // Format the caption
  553.   Self.Caption := Format(
  554.     'SelStart: %d (Line: %d, Col: %d) — DIPs[X: %d, Y: %d] — Pixels[X: %d, Y: %d] — Zoom: %d%% — Page: %d of %d',
  555.     [DWEdit1.SelStart, Line+1, Col+1 , PD.X, PD.Y, PP.X, PP.Y, Round(DWEdit1.ZoomFactor * 100), CurrentPage, TotalPage]
  556.   );
  557. end;
  558.  
  559. procedure TForm1.CMDelayedInit(var Message: TMessage);
  560. begin
  561.   // 1. Tell the component to recalculate
  562.   DWEdit1.ResetLayout;
  563.  
  564.   // 2. Tell the form to refresh the title
  565.   UpdateCaption;
  566. end;
  567.  
  568. procedure TForm1.DWEditSelStartChanged(Sender: TObject);
  569. begin
  570.   UpdateCaption;
  571. end;
  572.  
  573. procedure TForm1.DWEditZoomChanged(Sender: TObject);
  574. begin
  575.   UpdateCaption;
  576. end;
  577.  
  578. procedure TForm1.DWEditSelPageChanged(Sender: TObject);
  579. begin
  580.   UpdateCaption;
  581. end;
  582.  
  583. procedure TForm1.DWEditPageCountChanged(Sender: TObject);
  584. begin
  585.   UpdateCaption;
  586. end;
  587.  
  588.  
  589. end.
« Last Edit: November 28, 2025, 09:03:55 pm by Ed78z »

Ed78z

  • Jr. Member
  • **
  • Posts: 76
Re: TDWEdit
« Reply #24 on: November 28, 2025, 05:21:42 am »
PDF export added! but still needs some improvement...
Please test it, any feedback appreciated!
https://drive.google.com/drive/folders/11Q1DPsEUJ8wMdlwjZt_o3qAHpZS4EFjj
« Last Edit: November 28, 2025, 09:10:50 pm by Ed78z »

 

TinyPortal © 2005-2018