gamefont.pas 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. unit gamefont;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, Controls, StdCtrls, Graphics, Types;
  6. function GetMonospacedFontName: String;
  7. function GetMonospacedFontSize: Integer;
  8. procedure ResizeMemoForFont(Memo: TMemo; WidthChars, HeightChars: Integer);
  9. function FindXPosOverMemo(Memo: TMemo; WidthChars: Integer): Integer;
  10. implementation
  11. {$IFDEF MSWINDOWS}
  12. uses
  13. Windows;
  14. {$ENDIF}
  15. function GetMemoChrome(Memo: TMemo): TSize;
  16. var
  17. TempBmp: Graphics.TBitmap;
  18. ChromeWidth, ChromeHeight: Integer;
  19. CharSize: TSize;
  20. {$IFDEF MSWINDOWS}
  21. procedure GetWindowsCromeValues;
  22. begin
  23. { Idea adapted from here: https://stackoverflow.com/a/48110254
  24. I'm not 100% sure why I have to add +4 for this to work, but I guess
  25. this will do for now. }
  26. ChromeWidth := Windows.GetSystemMetrics(SM_CXEDGE) * 2 + 4;
  27. ChromeHeight := Windows.GetSystemMetrics(SM_CYEDGE) * 2 + 4;
  28. end;
  29. {$ENDIF}
  30. begin
  31. //TODO: how do we get the width and the height of the memo's chrome?
  32. //for now, assume 1.5 char size (this seems to work in Windows)
  33. TempBmp:= Graphics.TBitmap.Create;
  34. TempBmp.Canvas.Font.Size := GetMonospacedFontSize;
  35. TempBmp.Canvas.Font.Name := GetMonospacedFontName;
  36. CharSize := TempBmp.Canvas.TextExtent('m');
  37. { This is a heuristic that will *hopefully* be correct. These values are
  38. overwritten by platform-specific functions to get frame/indent widths. }
  39. ChromeWidth := 3 * CharSize.Width div 2;
  40. ChromeHeight := CharSize.Height div 2;
  41. {$IFDEF MSWINDOWS}
  42. GetWindowsCromeValues;
  43. {$ENDIF}
  44. FreeAndNil(TempBmp);
  45. Result.Width := ChromeWidth;
  46. Result.Height := ChromeHeight;
  47. end;
  48. function GetMonospacedFontName: String;
  49. begin
  50. //TODO change this to take OS and font availability into account
  51. {$IF Defined(LCLGtk) or Defined(LCLGtk2) or Defined(LCLGtk3)}
  52. GetMonospacedFontName := 'Monospace';
  53. {$ELSE}
  54. GetMonospacedFontName := 'Courier New';
  55. {$ENDIF}
  56. end;
  57. function GetMonospacedFontSize: Integer;
  58. begin
  59. //TODO change this to take OS and font availability into account
  60. GetMonospacedFontSize := 9;
  61. end;
  62. function GetTestStringSizes(WidthChars: Integer): TSize;
  63. var
  64. TempBmp: Graphics.TBitmap;
  65. TestStr: String;
  66. begin
  67. TempBmp:= Graphics.TBitmap.Create;
  68. TempBmp.Canvas.Font.Size := GetMonospacedFontSize;
  69. TempBmp.Canvas.Font.Name := GetMonospacedFontName;
  70. TestStr := StringOfChar('m', WidthChars);
  71. GetTestStringSizes := TempBmp.Canvas.TextExtent(TestStr);
  72. FreeAndNil(TempBmp);
  73. end;
  74. procedure ResizeMemoForFont(Memo: TMemo; WidthChars, HeightChars: Integer);
  75. var
  76. StrSize: TSize;
  77. ChromeSize: TSize;
  78. begin
  79. StrSize := GetTestStringSizes(WidthChars);
  80. ChromeSize := GetMemoChrome(Memo);
  81. Memo.Width := StrSize.Width + ChromeSize.Width;
  82. Memo.Height := HeightChars * StrSize.Height + ChromeSize.Height;
  83. end;
  84. function FindXPosOverMemo(Memo: TMemo; WidthChars: Integer): Integer;
  85. var
  86. StrSize: TSize;
  87. ChromeSize: TSize;
  88. begin
  89. StrSize := GetTestStringSizes(WidthChars);
  90. ChromeSize := GetMemoChrome(Memo);
  91. FindXPosOverMemo := StrSize.Width + (ChromeSize.Width div 2);
  92. end;
  93. end.