source: branches/2.19_branch/Components/RichTextStyleUnit.pas@ 324

Last change on this file since 324 was 39, checked in by RBRi, 19 years ago
  • ACLProfile calls
  • Property svn:eol-style set to native
File size: 17.1 KB
Line 
1Unit RichTextStyleUnit;
2
3Interface
4
5uses
6 Forms, Classes, Graphics, CanvasFontManager, RichTextDocumentUnit;
7
8type
9 TTextDrawStyle = record
10 Font: TFontSpec;
11 Color: TColor;
12 BackgroundColor: TColor;
13 Alignment: TTextAlignment;
14 Wrap: boolean;
15 LeftMargin: longint;
16 RightMargin: longint;
17 end;
18
19 TMarginSizeStyle = ( msAverageCharWidth, msMaximumCharWidth, msSpecifiedChar );
20
21 TRichTextSettings = class( TComponent )
22 protected
23 FHeading1Font: TFont;
24 FHeading2Font: TFont;
25 FHeading3Font: TFont;
26
27 FFixedFont: TFont;
28 FNormalFont: TFont;
29
30 FDefaultBackgroundColor: TColor;
31 FDefaultColor: TColor;
32
33 FDefaultAlignment: TTextAlignment;
34 FDefaultWrap: boolean;
35
36 FAtLeastOneWordBeforeWrap: boolean;
37
38 FMarginSizeStyle: TMarginSizeStyle;
39 FMarginChar: longint;
40
41 FOnChange: TNotifyEvent;
42
43 FMargins: TRect;
44
45 FUpdateCount: longint;
46 FChangesPending: boolean;
47
48 Procedure Change;
49
50 Procedure SetNormalFont( NewFont: TFont );
51 Procedure SetFixedFont( NewFont: TFont );
52 Procedure SetHeading1Font( NewFont: TFont );
53 Procedure SetHeading2Font( NewFont: TFont );
54 Procedure SetHeading3Font( NewFont: TFont );
55
56 Procedure SetDefaultColor( NewColor: TColor );
57 Procedure SetDefaultBackgroundColor( NewColor: TColor );
58
59 Procedure SetDefaultAlignment( Alignment: TTextAlignment );
60 Procedure SetDefaultWrap( Wrap: boolean );
61 Procedure SetAtLeastOneWordBeforeWrap( NewValue: boolean );
62
63 Procedure SetMarginSizeStyle( NewValue: TMarginSizeStyle );
64 Procedure SetMarginChar( NewValue: longint );
65
66 Procedure SetMargins( const NewMargins: TRect );
67
68 function GetMargin_Left: longint;
69 Procedure SetMargin_Left( NewValue: longint );
70 function GetMargin_Bottom: longint;
71 Procedure SetMargin_Bottom( NewValue: longint );
72 function GetMargin_Right: longint;
73 Procedure SetMargin_Right( NewValue: longint );
74 function GetMargin_Top: longint;
75 Procedure SetMargin_Top( NewValue: longint );
76
77 Procedure SetupComponent; override;
78 destructor Destroy; override;
79
80 Procedure AssignFont( Var Font: TFont;
81 NewFont: TFont );
82
83 // Hide properties...
84 property Name;
85
86 public
87 property OnChange: TNotifyEvent read FOnChange write FOnChange;
88
89 procedure BeginUpdate;
90 procedure EndUpdate;
91
92 // Stream in/out
93 Procedure ReadSCUResource( Const ResName: TResourceName;
94 Var Data;
95 DataLen: LongInt ); override;
96 Function WriteSCUResource( Stream: TResourceStream ): boolean; override;
97
98 property Margins: TRect read FMargins write SetMargins;
99
100 property Heading1Font: TFont read FHeading1Font write SetHeading1Font;
101 property Heading2Font: TFont read FHeading2Font write SetHeading2Font;
102 property Heading3Font: TFont read FHeading3Font write SetHeading3Font;
103 property FixedFont: TFont read FFixedFont write SetFixedFont;
104 property NormalFont: TFont read FNormalFont write SetNormalFont;
105
106 published
107
108 property DefaultBackgroundColor: TColor read FDefaultBackgroundColor write SetDefaultBackgroundColor;
109 property DefaultColor: TColor read FDefaultColor write SetDefaultColor;
110
111 property DefaultAlignment: TTextAlignment read FDefaultAlignment write SetDefaultAlignment;
112 property DefaultWrap: boolean read FDefaultWrap write SetDefaultWrap;
113 property AtLeastOneWordBeforeWrap: boolean read FAtLeastOneWordBeforeWrap write SetAtLeastOneWordBeforeWrap;
114
115 property MarginSizeStyle: TMarginSizeStyle read FMarginSizeStyle write SeTMarginSizeStyle;
116 property MarginChar: longint read FMarginChar write SetMarginChar;
117
118 // margins are exposed as individual properties here
119 // since the Sibyl IDE cannot cope with editing a record property
120 // within a class property (as in RichTextView)
121 property Margin_Left: longint read GetMargin_Left write SetMargin_Left;
122 property Margin_Bottom: longint read GetMargin_Bottom write SetMargin_Bottom;
123 property Margin_Right: longint read GetMargin_Right write SetMargin_Right;
124 property Margin_Top: longint read GetMargin_Top write SetMargin_Top;
125 end;
126
127// pRichTextSettings = ^TRichTextSettings;
128 Procedure ApplyStyle( const Style: TTextDrawStyle;
129 FontManager: TCanvasFontManager );
130
131 Procedure ApplyStyleTag( const Tag: TTag;
132 Var Style: TTextDrawStyle;
133 FontManager: TCanvasFontManager;
134 const Settings: TRichTextSettings;
135 const X: longint );
136
137 function GetDefaultStyle( const Settings: TRichTextSettings ): TTextDrawStyle;
138
139Exports
140 TRichTextSettings,'User','';
141
142Implementation
143
144uses
145 SysUtils,
146 ACLStringUtility;
147// ACLProfile;
148
149Procedure ApplyStyle( const Style: TTextDrawStyle;
150 FontManager: TCanvasFontManager );
151begin
152 FontManager.SetFont( Style.Font );
153 FontManager.Canvas.Pen.Color := Style.Color;
154end;
155
156Procedure ApplyStyleTag( Const Tag: TTag;
157 Var Style: TTextDrawStyle;
158 FontManager: TCanvasFontManager;
159 const Settings: TRichTextSettings;
160 const X: longint );
161var
162 MarginParam1: string;
163 MarginParam2: string;
164 NewMargin: longint;
165 FontFaceName: string;
166 FontSizeString: string;
167 NewStyle: TTextDrawStyle;
168 ParseIndex: longint;
169 XSizeStr: string;
170 YSizeStr: string;
171
172 MarginSize: longint;
173 ParsePoint: longint;
174begin
175 case Tag.TagType of
176 ttBold:
177 Include( Style.Font.Attributes, faBold );
178 ttBoldOff:
179 Exclude( Style.Font.Attributes, faBold );
180 ttItalic:
181 Include( Style.Font.Attributes, faItalic );
182 ttItalicOff:
183 Exclude( Style.Font.Attributes, faItalic );
184 ttUnderline:
185 Include( Style.Font.Attributes, faUnderscore );
186 ttUnderlineOff:
187 Exclude( Style.Font.Attributes, faUnderscore );
188
189 ttFixedWidthOn:
190 SibylFontToFontSpec( Settings.FFixedFont, Style.Font );
191 ttFixedWidthOff:
192 SibylFontToFontSpec( Settings.FNormalFont, Style.Font );
193
194 ttHeading1:
195 SibylFontToFontSpec( Settings.FHeading1Font, Style.Font );
196 ttHeading2:
197 SibylFontToFontSpec( Settings.FHeading2Font, Style.Font );
198 ttHeading3:
199 SibylFontToFontSpec( Settings.FHeading3Font, Style.Font );
200 ttHeadingOff:
201 SibylFontToFontSpec( Settings.FNormalFont, Style.Font );
202
203 ttFont:
204 begin
205 ParseIndex := 1;
206 GetNextQuotedValue( Tag.Arguments, ParseIndex, FontFaceName, DoubleQuote );
207 GetNextQuotedValue( Tag.Arguments, ParseIndex, FontSizeString, DoubleQuote );
208 NewStyle := Style;
209 try
210 NewStyle.Font.FaceName := FontFaceName;
211
212 if Pos( 'x', FontSizeString ) > 0 then
213 begin
214 XSizeStr := ExtractNextValue( FontSizeString, 'x' );
215 YSizeStr := FontSizeString;
216 NewStyle.Font.XSize := StrToInt( XSizeStr );
217 NewStyle.Font.YSize := StrToInt( YSizeStr );
218 NewStyle.Font.PointSize := 0;
219 end
220 else
221 begin
222 NewStyle.Font.PointSize := StrToInt( FontSizeString );
223 end;
224
225 if ( NewStyle.Font.FaceName <> '' )
226 and ( NewStyle.Font.PointSize >= 1 ) then
227 begin
228 Style := NewStyle;
229 end;
230
231 except
232 end;
233 end;
234
235 ttFontOff:
236 // restore default
237 SibylFontToFontSpec( Settings.FNormalFont, Style.Font );
238
239 ttColor:
240 GetTagColor( Tag.Arguments, Style.Color );
241 ttColorOff:
242 Style.Color := Settings.FDefaultColor;
243 ttBackgroundColor:
244 GetTagColor( Tag.Arguments, Style.BackgroundColor );
245 ttBackgroundColorOff:
246 Style.BackgroundColor := Settings.FDefaultBackgroundColor;
247
248 ttRed:
249 Style.Color := clRed;
250 ttBlue:
251 Style.Color := clBlue;
252 ttGreen:
253 Style.Color := clGreen;
254 ttBlack:
255 Style.Color := clBlack;
256
257 ttAlign:
258 Style.Alignment := GetTagTextAlignment( Tag.Arguments,
259 Settings.FDefaultAlignment );
260
261 ttWrap:
262 Style.Wrap := GetTagTextWrap( Tag.Arguments );
263
264 ttSetLeftMargin,
265 ttSetRightMargin:
266 begin
267 ParsePoint := 1;
268 GetNextValue( Tag.Arguments, ParsePoint, MarginParam1, ' ' );
269 if ( Tag.TagType = ttSetLeftMargin )
270 and ( MarginParam1 = 'here' ) then
271 begin
272 Style.LeftMargin := X div FontWidthPrecisionFactor;
273 end
274 else
275 begin
276 try
277 MarginSize := StrToInt( MarginParam1 );
278 GetNextValue( Tag.Arguments, ParsePoint, MarginParam2, ' ' );
279 if MarginParam2 = 'pixels' then
280 NewMargin := MarginSize
281
282 else if MarginParam2 = 'deffont' then
283 NewMargin := MarginSize
284 * Settings.NormalFont.Width
285
286 else
287 begin
288 case Settings.MarginSizeStyle of
289 msAverageCharWidth:
290 NewMargin := MarginSize * FontManager.AverageCharWidth;
291 msMaximumCharWidth:
292 NewMargin := MarginSize * FontManager.MaximumCharWidth;
293 msSpecifiedChar:
294 NewMargin := MarginSize
295 * FontManager.CharWidth( Chr( Settings.MarginChar ) )
296 div FontWidthPrecisionFactor;
297 end;
298 end;
299 except
300 NewMargin := 0;
301 end;
302
303 if Tag.TagType = ttSetLeftMargin then
304 Style.LeftMargin := Settings.Margins.Left
305 + NewMargin
306 else
307 Style.RightMargin := Settings.Margins.Right
308 + NewMargin;
309 end;
310 end;
311
312 end;
313
314 ApplyStyle( Style, FontManager );
315
316end;
317
318function GetDefaultStyle( const Settings: TRichTextSettings ): TTextDrawStyle;
319begin
320 SibylFontToFontSpec( Settings.FNormalFont, Result.Font );
321 Result.Alignment := Settings.FDefaultAlignment;
322 Result.Wrap := Settings.FDefaultWrap;
323 Result.Color := Settings.FDefaultColor;
324 Result.BackgroundColor := Settings.FDefaultBackgroundColor;
325 Result.LeftMargin := Settings.Margins.Left;
326 Result.RightMargin := Settings.Margins.Right;
327end;
328
329Procedure GetStartupFont( Var Font: TFont;
330 Const Face: string;
331 Const Size: longint );
332begin
333 Font := Screen.CreateCompatibleFont( Screen.GetFontFromPointSize( Face, Size ) );
334 ReferenceFont( Font );
335 Font.AutoDestroy := true;
336end;
337
338Procedure TRichTextSettings.SetupComponent;
339begin
340 inherited SetupComponent;
341
342 Name := 'RichTextSettings';
343
344 GetStartupFont( FNormalFont, 'Helv', 8 );
345 GetStartupFont( FFixedFont, 'Courier', 8 );
346 GetStartupFont( FHeading1Font, 'Helv', 18 );
347 GetStartupFont( FHeading2Font, 'Helv', 12 );
348 GetStartupFont( FHeading3Font, 'Helv', 8 );
349 FHeading3Font.Attributes := [ faBold ];
350
351 FDefaultColor := clBlack;
352 FDefaultBackgroundColor := clWhite;
353
354 FDefaultAlignment := taLeft;
355 FDefaultWrap := true;
356 FAtLeastOneWordBeforeWrap := false;
357
358 FMarginSizeStyle := msMaximumCharWidth;
359 FMarginChar := Ord( ' ' );
360
361 FMargins.Left := 0;
362 FMargins.Right := 0;
363 FMargins.Top := 0;
364 FMargins.Bottom := 0;
365
366 FUpdateCount := 0;
367 FChangesPending := false;
368end;
369
370destructor TRichTextSettings.Destroy;
371begin
372 DereferenceFont( FNormalFont );
373 DereferenceFont( FFixedFont );
374 DereferenceFont( FHeading1Font );
375 DereferenceFont( FHeading2Font );
376 DereferenceFont( FHeading3Font );
377
378 Inherited Destroy;
379end;
380
381// Font read/write from SCU. I have NO IDEA why I have to do this manually. But
382// this way works and everything else I tried doesn't
383Procedure TRichTextSettings.ReadSCUResource( Const ResName: TResourceName;
384 Var Data;
385 DataLen: LongInt );
386Begin
387 If ResName = 'Heading1Font' Then
388 Begin
389 If DataLen <> 0 Then
390 FHeading1Font := ReadSCUFont( Data, DataLen );
391 End
392 Else If ResName = 'Heading2Font' Then
393 Begin
394 If DataLen <> 0 Then
395 FHeading2Font := ReadSCUFont( Data, DataLen );
396 End
397 Else If ResName = 'Heading3Font' Then
398 Begin
399 If DataLen <> 0 Then
400 FHeading3Font := ReadSCUFont( Data, DataLen );
401 End
402 Else If ResName = 'FixedFont' Then
403 Begin
404 If DataLen <> 0 Then
405 FFixedFont := ReadSCUFont( Data, DataLen );
406 End
407 Else if ResName = 'NormalFont' then
408 Begin
409 If DataLen <> 0 Then
410 FNormalFont := ReadSCUFont( Data, DataLen );
411 End
412 Else
413 Inherited ReadSCUResource( ResName, Data, DataLen );
414End;
415
416Function TRichTextSettings.WriteSCUResource( Stream: TResourceStream ): boolean;
417begin
418 Result := Inherited WriteSCUResource( Stream );
419 If Not Result Then
420 Exit;
421
422 If FHeading1Font <> Nil then
423 Result := FHeading1Font.WriteSCUResourceName( Stream, 'Heading1Font' );
424 If FHeading2Font <> Nil then
425 Result := FHeading2Font.WriteSCUResourceName( Stream, 'Heading2Font' );
426 If FHeading3Font <> Nil then
427 Result := FHeading3Font.WriteSCUResourceName( Stream, 'Heading3Font' );
428 If FFixedFont <> Nil then
429 Result := FFixedFont.WriteSCUResourceName( Stream, 'FixedFont' );
430 If FNormalFont <> Nil then
431 Result := FNormalFont.WriteSCUResourceName( Stream, 'NormalFont' );
432
433end;
434
435Procedure TRichTextSettings.Change;
436begin
437 if FUpdateCount > 0 then
438 begin
439 FChangesPending := true;
440 exit;
441 end;
442
443 if FOnChange <> nil then
444 FOnChange( self );
445end;
446
447Procedure TRichTextSettings.SetDefaultAlignment( Alignment: TTextAlignment );
448begin
449 if Alignment = FDefaultAlignment then
450 exit; // no change
451
452 FDefaultAlignment := Alignment;
453 Change;
454end;
455
456Procedure TRichTextSettings.SetDefaultWrap( Wrap: boolean );
457begin
458 if Wrap = FDefaultWrap then
459 exit; // no change
460
461 FDefaultWrap := Wrap;
462 Change;
463end;
464
465Procedure TRichTextSettings.SetAtLeastOneWordBeforeWrap( NewValue: boolean );
466begin
467 if NewValue = FAtLeastOneWordBeforeWrap then
468 exit; // no change
469
470 FAtLeastOneWordBeforeWrap := NewValue;
471 Change;
472end;
473
474Procedure TRichTextSettings.SetMarginChar( NewValue: longint );
475begin
476 if NewValue = FMarginChar then
477 exit; // no change
478
479 FMarginChar := NewValue;
480
481 if FMarginSizeStyle <> msSpecifiedChar then
482 // doesn't matter, will be ignored
483 exit;
484 Change;
485end;
486
487Procedure TRichTextSettings.SetMarginSizeStyle( NewValue: TMarginSizeStyle );
488begin
489 if NewValue = FMarginSizeStyle then
490 exit; // no change
491
492 FMarginSizeStyle := NewValue;
493 Change;
494end;
495
496Function FontSame( FontA: TFont; FontB: TFont ): boolean;
497begin
498 if ( FontA = nil )
499 or ( FontB = nil ) then
500 begin
501 Result := FontA = FontB;
502 exit;
503 end;
504
505 Result := ( FontA.FaceName = FontB.FaceName )
506 and ( FontA.PointSize = FontB.PointSize )
507 and ( FontA.Attributes = FontB.Attributes );
508end;
509
510Procedure TRichTextSettings.AssignFont( Var Font: TFont;
511 NewFont: TFont );
512begin
513 If NewFont = Nil Then
514 NewFont := Screen.DefaultFont;
515
516 if FontSame( NewFont, Font ) then
517 exit; // no change
518
519 DereferenceFont( Font );
520 Font := NewFont;
521 ReferenceFont( Font );
522
523 Change;
524End;
525
526Procedure TRichTextSettings.SetHeading1Font( NewFont: TFont );
527begin
528// ProfileEvent( 'TRichTextSettings.SetHeading1Font' );
529 AssignFont( FHeading1Font, NewFont );
530
531// if FHeading1FOnt = nil then
532// ProfileEvent( ' Set to nil' );
533
534end;
535
536Procedure TRichTextSettings.SetHeading2Font( NewFont: TFont );
537begin
538 AssignFont( FHeading2Font, NewFont );
539End;
540
541Procedure TRichTextSettings.SetHeading3Font( NewFont: TFont );
542begin
543 AssignFont( FHeading3Font, NewFont );
544End;
545
546Procedure TRichTextSettings.SetFixedFont( NewFont: TFont );
547begin
548 AssignFont( FFixedFont, NewFont );
549end;
550
551Procedure TRichTextSettings.SetNormalFont( NewFont: TFont );
552begin
553 AssignFont( FNormalFont, NewFont );
554end;
555
556Procedure TRichTextSettings.SetMargins( const NewMargins: TRect );
557begin
558 if NewMargins = FMargins then
559 exit; // no change
560 FMargins := NewMargins;
561 Change;
562end;
563
564function TRichTextSettings.GetMargin_Left: longint;
565begin
566 Result := FMargins.Left;
567end;
568
569Procedure TRichTextSettings.SetMargin_Left( NewValue: longint );
570begin
571 Margins.Left := NewValue;
572end;
573
574function TRichTextSettings.GetMargin_Bottom: longint;
575begin
576 Result := FMargins.Bottom;
577end;
578
579Procedure TRichTextSettings.SetMargin_Bottom( NewValue: longint );
580begin
581 Margins.Bottom := NewValue;
582end;
583
584function TRichTextSettings.GetMargin_Right: longint;
585begin
586 Result := FMargins.Right;
587end;
588
589Procedure TRichTextSettings.SetMargin_Right( NewValue: longint );
590begin
591 Margins.Right := NewValue;
592end;
593
594function TRichTextSettings.GetMargin_Top: longint;
595begin
596 Result := FMargins.Top;
597end;
598
599Procedure TRichTextSettings.SetMargin_Top( NewValue: longint );
600begin
601 Margins.Top := NewValue;
602end;
603
604Procedure TRichTextSettings.SetDefaultColor( NewColor: TColor );
605begin
606 if NewColor = FDefaultColor then
607 exit;
608 FDefaultColor := NewColor;
609 Change;
610end;
611
612Procedure TRichTextSettings.SetDefaultBackgroundColor( NewColor: TColor );
613begin
614 if NewColor = FDefaultBackgroundColor then
615 exit;
616 FDefaultBackgroundColor := NewColor;
617 Change;
618end;
619
620procedure TRichTextSettings.BeginUpdate;
621begin
622 inc( FUpdateCount );
623end;
624
625procedure TRichTextSettings.EndUpdate;
626begin
627 if FUpdateCount = 0 then
628 exit;
629
630 dec( FUpdateCount );
631 if FUpdateCount = 0 then
632 begin
633 if FChangesPending then
634 begin
635 Change;
636 FChangesPending := false;
637 end;
638 end;
639end;
640
641Initialization
642 RegisterClasses( [ TRichTextSettings ] );
643End.
Note: See TracBrowser for help on using the repository browser.