Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

343 righe
9.7 KiB

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