fpfonttextmapping.pp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 2016 by Graeme Geldenhuys
  4. This unit defines classes that manage font glyph IDs and unicode
  5. character codes.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit FPFontTextMapping;
  13. {$mode objfpc}{$H+}
  14. interface
  15. uses
  16. Classes,
  17. SysUtils,
  18. contnrs;
  19. type
  20. TTextMapping = class(TObject)
  21. private
  22. FCharID: uint32;
  23. FGlyphID: uint32;
  24. FNewGlyphID: uint32;
  25. FGlyphData: TStream;
  26. FIsCompoundGlyph: boolean;
  27. public
  28. constructor Create;
  29. class function NewTextMap(const ACharID, AGlyphID: uint32): TTextMapping;
  30. property CharID: uint32 read FCharID write FCharID;
  31. property GlyphID: uint32 read FGlyphID write FGlyphID;
  32. property NewGlyphID: uint32 read FNewGlyphID write FNewGlyphID;
  33. property GlyphData: TStream read FGlyphData write FGlyphData;
  34. property IsCompoundGlyph: boolean read FIsCompoundGlyph write FIsCompoundGlyph;
  35. end;
  36. TTextMappingList = class(TObject)
  37. private
  38. FList: TFPObjectList;
  39. function GetCount: Integer;
  40. protected
  41. function GetItem(AIndex: Integer): TTextMapping; virtual;
  42. procedure SetItem(AIndex: Integer; AValue: TTextMapping); virtual;
  43. public
  44. constructor Create;
  45. destructor Destroy; override;
  46. function Add(AObject: TTextMapping): Integer; overload;
  47. function Add(const ACharID, AGlyphID: uint32): Integer; overload;
  48. function Contains(const AGlyphID: uint32): boolean;
  49. function ContainsCharID(const AID: uint32): boolean;
  50. function GetNewGlyphID(const ACharID: uint32): uint32;
  51. function GetMaxCharID: uint32;
  52. function GetMaxGlyphID: uint32;
  53. procedure Insert(const AIndex: integer; const ACharID, AGlyphID: uint32);
  54. procedure Sort;
  55. property Count: Integer read GetCount;
  56. property Items[AIndex: Integer]: TTextMapping read GetItem write SetItem; default;
  57. end;
  58. implementation
  59. { TTextMapping }
  60. constructor TTextMapping.Create;
  61. begin
  62. FGlyphData := nil;
  63. FCharID := 0;
  64. FGlyphID := 0;
  65. FNewGlyphID := 0;
  66. FIsCompoundGlyph := False;
  67. end;
  68. class function TTextMapping.NewTextMap(const ACharID, AGlyphID: uint32): TTextMapping;
  69. begin
  70. Result := TTextMapping.Create;
  71. Result.CharID := ACharID;
  72. Result.GlyphID := AGlyphID;
  73. end;
  74. { TTextMappingList }
  75. function TTextMappingList.GetCount: Integer;
  76. begin
  77. Result := FList.Count;
  78. end;
  79. function TTextMappingList.GetItem(AIndex: Integer): TTextMapping;
  80. begin
  81. Result := TTextMapping(FList.Items[AIndex]);
  82. end;
  83. procedure TTextMappingList.SetItem(AIndex: Integer; AValue: TTextMapping);
  84. begin
  85. FList.Items[AIndex] := AValue;
  86. end;
  87. constructor TTextMappingList.Create;
  88. begin
  89. FList := TFPObjectList.Create(True);
  90. end;
  91. destructor TTextMappingList.Destroy;
  92. begin
  93. FList.Free;
  94. inherited Destroy;
  95. end;
  96. function TTextMappingList.Add(AObject: TTextMapping): Integer;
  97. var
  98. i: integer;
  99. begin
  100. Result := -1;
  101. for i := 0 to FList.Count-1 do
  102. begin
  103. if TTextMapping(FList.Items[i]).CharID = AObject.CharID then
  104. Exit; // mapping already exists
  105. end;
  106. Result := FList.Add(AObject);
  107. end;
  108. function TTextMappingList.Add(const ACharID, AGlyphID: uint32): Integer;
  109. var
  110. o: TTextMapping;
  111. begin
  112. o := TTextMapping.Create;
  113. o.CharID := ACharID;
  114. o.GlyphID := AGlyphID;
  115. Result := Add(o);
  116. if Result = -1 then
  117. o.Free;
  118. end;
  119. function TTextMappingList.Contains(const AGlyphID: uint32): boolean;
  120. var
  121. i: integer;
  122. begin
  123. Result := False;
  124. for i := 0 to Count-1 do
  125. begin
  126. if Items[i].GlyphID = AGlyphID then
  127. begin
  128. Result := True;
  129. Exit;
  130. end;
  131. end;
  132. end;
  133. function TTextMappingList.ContainsCharID(const AID: uint32): boolean;
  134. var
  135. i: integer;
  136. begin
  137. Result := False;
  138. for i := 0 to Count-1 do
  139. begin
  140. if Items[i].CharID = AID then
  141. begin
  142. Result := True;
  143. Exit;
  144. end;
  145. end;
  146. end;
  147. function TTextMappingList.GetNewGlyphID(const ACharID: uint32): uint32;
  148. var
  149. i: integer;
  150. begin
  151. for i := 0 to Count-1 do
  152. begin
  153. if Items[i].CharID = ACharID then
  154. begin
  155. Result := Items[i].NewGlyphID;
  156. Exit;
  157. end;
  158. end;
  159. end;
  160. function TTextMappingList.GetMaxCharID: uint32;
  161. begin
  162. Sort;
  163. Result := Items[Count-1].CharID;
  164. end;
  165. function TTextMappingList.GetMaxGlyphID: uint32;
  166. var
  167. gid: uint32;
  168. i: integer;
  169. begin
  170. gid := 0;
  171. for i := 0 to Count-1 do
  172. begin
  173. if Items[i].GlyphID > gid then
  174. gid := Items[i].GlyphID;
  175. end;
  176. result := gid;
  177. end;
  178. procedure TTextMappingList.Insert(const AIndex: integer; const ACharID, AGlyphID: uint32);
  179. var
  180. o: TTextMapping;
  181. begin
  182. o := TTextMapping.Create;
  183. o.CharID := ACharID;
  184. o.GlyphID := AGlyphID;
  185. FList.Insert(AIndex, o);
  186. end;
  187. function CompareByCharID(A, B: TTextMapping): Integer; inline;
  188. begin
  189. if A.CharID < B.CharID then
  190. Result := -1
  191. else if A.CharID > B.CharID then
  192. Result := 1
  193. else
  194. Result := 0;
  195. end;
  196. function CompareByCharIDPtr(A, B: Pointer): Integer;
  197. begin
  198. Result := CompareByCharID(TTextMapping(A), TTextMapping(B));
  199. end;
  200. procedure TTextMappingList.Sort;
  201. begin
  202. FList.Sort(@CompareByCharIDPtr);
  203. end;
  204. end.