You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

350 rivejä
9.9 KiB

  1. unit utsGDI;
  2. {$IFDEF FPC}
  3. {$mode delphi}{$H+}
  4. {$ENDIF}
  5. interface
  6. uses
  7. Classes, SysUtils, utsTypes, syncobjs{$IFDEF FPC}, dynlibs{$ELSE}, Windows{$ENDIF};
  8. type
  9. HDC = Cardinal;
  10. {$IFNDEF FPC}
  11. DWORD = Cardinal;
  12. PDWORD = ^DWORD;
  13. TLibHandle = Cardinal;
  14. {$ENDIF}
  15. TFixed = packed record
  16. fract: Word;
  17. value: Smallint;
  18. end;
  19. TMat2 = packed record
  20. eM11: TFixed;
  21. eM12: TFixed;
  22. eM21: TFixed;
  23. eM22: TFixed;
  24. end;
  25. PMat2 = ^TMat2;
  26. const
  27. GDI_ERROR = DWORD($FFFFFFFF);
  28. FW_NORMAL = 400;
  29. FW_BOLD = 700;
  30. DEFAULT_CHARSET = 1;
  31. NONANTIALIASED_QUALITY = 3;
  32. ANTIALIASED_QUALITY = 4;
  33. GGO_METRICS = 0;
  34. GGO_BITMAP = 1;
  35. GGO_GRAY8_BITMAP = 6;
  36. GGO_GLYPH_INDEX = $80;
  37. FR_PRIVATE = $10;
  38. FR_NOT_ENUM = $20;
  39. LOCALE_USER_DEFAULT = $0400;
  40. LOCALE_ILANGUAGE = $1;
  41. GCP_MAXEXTENT = $100000;
  42. TMPF_FIXED_PITCH = 1;
  43. type
  44. HFONT = Cardinal;
  45. HGDIOBJ = Cardinal;
  46. TLogFontA = record
  47. lfHeight: Longint;
  48. lfWidth: Longint;
  49. lfEscapement: Longint;
  50. lfOrientation: Longint;
  51. lfWeight: Longint;
  52. lfItalic: Byte;
  53. lfUnderline: Byte;
  54. lfStrikeOut: Byte;
  55. lfCharSet: Byte;
  56. lfOutPrecision: Byte;
  57. lfClipPrecision: Byte;
  58. lfQuality: Byte;
  59. lfPitchAndFamily: Byte;
  60. lfFaceName: array[0..31] of AnsiChar;
  61. end;
  62. PLogFontA = ^TLogFontA;
  63. TTextMetricW = record
  64. tmHeight: Longint;
  65. tmAscent: Longint;
  66. tmDescent: Longint;
  67. tmInternalLeading: Longint;
  68. tmExternalLeading: Longint;
  69. tmAveCharWidth: Longint;
  70. tmMaxCharWidth: Longint;
  71. tmWeight: Longint;
  72. tmOverhang: Longint;
  73. tmDigitizedAspectX: Longint;
  74. tmDigitizedAspectY: Longint;
  75. tmFirstChar: WideChar;
  76. tmLastChar: WideChar;
  77. tmDefaultChar: WideChar;
  78. tmBreakChar: WideChar;
  79. tmItalic: Byte;
  80. tmUnderlined: Byte;
  81. tmStruckOut: Byte;
  82. tmPitchAndFamily: Byte;
  83. tmCharSet: Byte;
  84. end;
  85. PTextMetricW = ^TTextMetricW;
  86. TGlyphMetrics = record
  87. gmBlackBoxX: Cardinal;
  88. gmBlackBoxY: Cardinal;
  89. gmptGlyphOrigin: TtsPosition;
  90. gmCellIncX: Smallint;
  91. gmCellIncY: Smallint;
  92. end;
  93. PGlyphMetrics = ^TGlyphMetrics;
  94. TGCPResultsW = record
  95. lStructSize: DWORD;
  96. lpOutString: PWideChar;
  97. lpOrder: PDWORD;
  98. lpDx: PInteger;
  99. lpCaretPos: PInteger;
  100. lpClass: PChar;
  101. lpGlyphs: PCardinal;
  102. nGlyphs: Cardinal;
  103. nMaxFit: Cardinal;
  104. end;
  105. PGCPResultsW = ^TGCPResultsW;
  106. TPanose = record
  107. bFamilyType: Byte;
  108. bSerifStyle: Byte;
  109. bWeight: Byte;
  110. bProportion: Byte;
  111. bContrast: Byte;
  112. bStrokeVariation: Byte;
  113. bArmStyle: Byte;
  114. bLetterform: Byte;
  115. bMidline: Byte;
  116. bXHeight: Byte;
  117. end;
  118. PPanose = ^TPanose;
  119. TOutlineTextmetricW = record
  120. otmSize: LongWord;
  121. otmTextMetrics: TTextMetricW;
  122. otmFiller: Byte;
  123. otmPanoseNumber: TPanose;
  124. otmfsSelection: LongWord;
  125. otmfsType: LongWord;
  126. otmsCharSlopeRise: Integer;
  127. otmsCharSlopeRun: Integer;
  128. otmItalicAngle: Integer;
  129. otmEMSquare: LongWord;
  130. otmAscent: Integer;
  131. otmDescent: Integer;
  132. otmLineGap: LongWord;
  133. otmsCapEmHeight: LongWord;
  134. otmsXHeight: LongWord;
  135. otmrcFontBox: TtsRect;
  136. otmMacAscent: Integer;
  137. otmMacDescent: Integer;
  138. otmMacLineGap: LongWord;
  139. otmusMinimumPPEM: LongWord;
  140. otmptSubscriptSize: TtsPosition;
  141. otmptSubscriptOffset: TtsPosition;
  142. otmptSuperscriptSize: TtsPosition;
  143. otmptSuperscriptOffset: TtsPosition;
  144. otmsStrikeoutSize: LongWord;
  145. otmsStrikeoutPosition: Integer;
  146. otmsUnderscoreSize: Integer;
  147. otmsUnderscorePosition: Integer;
  148. otmpFamilyName: PWideChar;
  149. otmpFaceName: PWideChar;
  150. otmpStyleName: PWideChar;
  151. otmpFullName: PWideChar;
  152. end;
  153. POutlineTextmetricW = ^TOutlineTextmetricW;
  154. TCreateFontIndirectA = function (const p1: TLogFontA): HFONT; stdcall;
  155. TAddFontResourceA = function(Filename: PAnsiChar): Integer; stdcall;
  156. TAddFontResourceExA = function(Filename: PAnsiChar; Flag: DWORD; pdv: Pointer): Integer; stdcall;
  157. TAddFontMemResourceEx = function(pbFont: Pointer; cbFont: DWORD; pdv: Pointer; pcFonts: PDWORD): THandle; stdcall;
  158. TRemoveFontResourceA = function(Filename: PAnsiChar): Boolean; stdcall;
  159. TRemoveFontResourceExA = function(filename: PAnsiChar; Flag: DWORD; pdv: Pointer): Boolean; stdcall;
  160. TRemoveFontMemResourceEx = function(fh: THandle): Boolean; stdcall;
  161. TGetTextMetricsW = function(DC: HDC; var TM: TTextMetricW): Boolean; stdcall;
  162. TGetGlyphOutlineA = function(DC: HDC; uChar, uFormat: Cardinal; lpgm: PGlyphMetrics; cbBuffer: DWORD; lpvBuffer: Pointer; lpmat2: PMat2): DWORD; stdcall;
  163. TGetCharacterPlacementW = function(DC: HDC; Str: PWideChar; Count, MaxExtent: Integer; Result: PGCPResultsW; Flags: DWORD): DWORD; stdcall;
  164. TGetFontData = function(DC: HDC; TableName, Offset: DWORD; Buffer: Pointer; Data: DWORD): DWORD; stdcall;
  165. TCreateCompatibleDC = function(DC: HDC): HDC; stdcall;
  166. TDeleteDC = function(DC: HDC): Boolean; stdcall;
  167. TSelectObject = function(DC: HDC; p2: HGDIOBJ): HGDIOBJ; stdcall;
  168. TDeleteObject = function(p1: HGDIOBJ): Boolean; stdcall;
  169. TGetOutlineTextMetricsW = function(DC: HDC; p2: LongWord; var OTMetricStructs: TOutlineTextmetricW): LongWord; stdcall;
  170. TGetLocaleInfoA = function(Locale: DWORD; LCType: DWORD; lpLCData: pAnsiChar; cchData: Integer): Integer; stdcall;
  171. var
  172. CreateFontIndirectA: TCreateFontIndirectA;
  173. AddFontResourceA: TAddFontResourceA;
  174. AddFontResourceExA: TAddFontResourceExA;
  175. AddFontMemResourceEx: TAddFontMemResourceEx;
  176. RemoveFontResourceA: TRemoveFontResourceA;
  177. RemoveFontResourceExA: TRemoveFontResourceExA;
  178. RemoveFontMemResourceEx: TRemoveFontMemResourceEx;
  179. GetTextMetricsW: TGetTextMetricsW;
  180. GetGlyphOutlineA: TGetGlyphOutlineA;
  181. GetCharacterPlacementW: TGetCharacterPlacementW;
  182. GetFontData: TGetFontData;
  183. CreateCompatibleDC: TCreateCompatibleDC;
  184. DeleteDC: TDeleteDC;
  185. SelectObject: TSelectObject;
  186. DeleteObject: TDeleteObject;
  187. GetOutlineTextMetricsW: TGetOutlineTextMetricsW;
  188. GetLocaleInfoA: TGetLocaleInfoA;
  189. procedure InitGDI;
  190. procedure QuitGDI;
  191. implementation
  192. uses
  193. utsTextSuite;
  194. const
  195. LIB_GDI32 = 'gdi32.dll';
  196. LIB_KERNEL32 = 'kernel32.dll';
  197. var
  198. gdiRefCount: Integer;
  199. gdiCritSec: TCriticalSection;
  200. gdiInitialized: Boolean;
  201. gdiLibHandle: TLibHandle = 0;
  202. kernel32LibHandle: TLibHandle = 0;
  203. procedure InitGDI;
  204. function GetProcAddr(const aLibHandle: TLibHandle; const aName: String): Pointer;
  205. begin
  206. result := GetProcAddress(aLibHandle, PAnsiChar(aName));
  207. if not Assigned(result) then
  208. raise EtsException.Create('unable to load procedure from library: ' + aName);
  209. end;
  210. begin
  211. gdiCritSec.Enter;
  212. try try
  213. inc(gdiRefCount, 1);
  214. if gdiInitialized then
  215. exit;
  216. if (gdiLibHandle = 0) then begin
  217. gdiLibHandle := LoadLibrary(LIB_GDI32);
  218. if (gdiLibHandle = 0) then
  219. raise EtsException.Create('unable to load gdi lib: ' + LIB_GDI32);
  220. end;
  221. if (kernel32LibHandle = 0) then begin
  222. kernel32LibHandle := LoadLibrary(LIB_KERNEL32);
  223. if (kernel32LibHandle = 0) then
  224. raise EtsException.Create('unable to load kernel lib: ' + LIB_KERNEL32);
  225. end;
  226. CreateFontIndirectA := TCreateFontIndirectA( GetProcAddr(gdiLibHandle, 'CreateFontIndirectA'));
  227. AddFontResourceA := TAddFontResourceA( GetProcAddr(gdiLibHandle, 'AddFontResourceA'));
  228. AddFontResourceExA := TAddFontResourceExA( GetProcAddr(gdiLibHandle, 'AddFontResourceExA'));
  229. AddFontMemResourceEx := TAddFontMemResourceEx( GetProcAddr(gdiLibHandle, 'AddFontMemResourceEx'));
  230. RemoveFontResourceA := TRemoveFontResourceA( GetProcAddr(gdiLibHandle, 'RemoveFontResourceA'));
  231. RemoveFontResourceExA := TRemoveFontResourceExA( GetProcAddr(gdiLibHandle, 'RemoveFontResourceExA'));
  232. RemoveFontMemResourceEx := TRemoveFontMemResourceEx(GetProcAddr(gdiLibHandle, 'RemoveFontMemResourceEx'));
  233. GetTextMetricsW := TGetTextMetricsW( GetProcAddr(gdiLibHandle, 'GetTextMetricsW'));
  234. GetGlyphOutlineA := TGetGlyphOutlineA( GetProcAddr(gdiLibHandle, 'GetGlyphOutlineA'));
  235. GetCharacterPlacementW := TGetCharacterPlacementW( GetProcAddr(gdiLibHandle, 'GetCharacterPlacementW'));
  236. GetFontData := TGetFontData( GetProcAddr(gdiLibHandle, 'GetFontData'));
  237. CreateCompatibleDC := TCreateCompatibleDC( GetProcAddr(gdiLibHandle, 'CreateCompatibleDC'));
  238. DeleteDC := TDeleteDC( GetProcAddr(gdiLibHandle, 'DeleteDC'));
  239. SelectObject := TSelectObject( GetProcAddr(gdiLibHandle, 'SelectObject'));
  240. DeleteObject := TDeleteObject( GetProcAddr(gdiLibHandle, 'DeleteObject'));
  241. GetOutlineTextMetricsW := TGetOutlineTextMetricsW( GetProcAddr(gdiLibHandle, 'GetOutlineTextMetricsW'));
  242. GetLocaleInfoA := TGetLocaleInfoA(GetProcAddr(kernel32LibHandle, 'GetLocaleInfoA'));
  243. gdiInitialized := true;
  244. except
  245. gdiInitialized := false;
  246. FreeLibrary(gdiLibHandle);
  247. FreeLibrary(kernel32LibHandle);
  248. end;
  249. finally
  250. gdiCritSec.Leave;
  251. end;
  252. end;
  253. procedure QuitGDI;
  254. begin
  255. gdiCritSec.Enter;
  256. try
  257. dec(gdiRefCount, 1);
  258. if (gdiRefCount > 0) then
  259. exit;
  260. CreateFontIndirectA := nil;
  261. AddFontResourceA := nil;
  262. AddFontResourceExA := nil;
  263. RemoveFontResourceA := nil;
  264. RemoveFontResourceExA := nil;
  265. GetTextMetricsW := nil;
  266. GetGlyphOutlineA := nil;
  267. GetCharacterPlacementW := nil;
  268. GetFontData := nil;
  269. CreateCompatibleDC := nil;
  270. DeleteDC := nil;
  271. SelectObject := nil;
  272. DeleteObject := nil;
  273. GetLocaleInfoA := nil;
  274. if (gdiLibHandle <> 0) then begin
  275. FreeLibrary(gdiLibHandle);
  276. gdiLibHandle := 0;
  277. end;
  278. if (kernel32LibHandle <> 0) then begin
  279. FreeLibrary(kernel32LibHandle);
  280. kernel32LibHandle := 0;
  281. end;
  282. gdiInitialized := false;
  283. finally
  284. gdiCritSec.Leave;
  285. end;
  286. end;
  287. initialization
  288. gdiRefCount := 0;
  289. gdiInitialized := false;
  290. gdiCritSec := TCriticalSection.Create;
  291. finalization
  292. if gdiInitialized then
  293. QuitGDI;
  294. FreeAndNil(gdiCritSec);
  295. end.