fpwritexpm.pp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2003 by the Free Pascal development team
  5. XPM writer implementation.
  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. {$mode objfpc}{$h+}
  13. unit FPWriteXPM;
  14. interface
  15. uses FPImage, classes, sysutils;
  16. type
  17. TFPWriterXPM = class (TFPCustomImageWriter)
  18. private
  19. FPalChars : string;
  20. FColorFormat : string;
  21. FColorShift : word;
  22. FColorSize : byte;
  23. procedure SetColorSize (AValue : byte);
  24. function ColorToHex (c:TFPColor) : string;
  25. protected
  26. procedure InternalWrite (Str:TStream; Img:TFPCustomImage); override;
  27. public
  28. constructor Create; override;
  29. property PalChars : string read FPalChars write FPalChars;
  30. property ColorCharSize : byte read FColorSize write SetColorSize;
  31. // number of characters to use for 1 colorcomponent
  32. end;
  33. implementation
  34. const
  35. DefPalChars = '.,-*abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#;:=+%$()[]';
  36. constructor TFPWriterXPM.create;
  37. begin
  38. inherited create;
  39. PalChars := DefPalChars;
  40. FColorSize := 4;
  41. end;
  42. procedure TFPWriterXPM.SetColorSize (AValue : byte);
  43. begin
  44. if AValue > 3 then
  45. FColorSize := 4
  46. else if AValue = 0 then
  47. FColorSize := 1
  48. else
  49. FColorSize := AValue;
  50. end;
  51. function TFPWriterXPM.ColorToHex (c:TFPColor) : string;
  52. var r,g,b : word;
  53. begin
  54. with c do
  55. begin
  56. r := red shr FColorShift;
  57. g := green shr FColorShift;
  58. b := blue shr FColorShift;
  59. end;
  60. result := format(FColorFormat,[r,g,b]);
  61. end;
  62. procedure TFPWriterXPM.InternalWrite (Str:TStream; Img:TFPCustomImage);
  63. var p, l : TStringList;
  64. c, len, r, t : integer;
  65. procedure BuildPaletteStrings;
  66. var r,c,e : integer;
  67. procedure MakeCodes (const head:string; charplace:integer);
  68. var r : integer;
  69. begin
  70. r := 1;
  71. dec (charplace);
  72. while (r <= e) and (c >= 0) do
  73. begin
  74. if Charplace = 1 then
  75. MakeCodes (head+PalChars[r],charplace)
  76. else
  77. p.Add (head+PalChars[r]);
  78. inc (r);
  79. dec(c);
  80. end;
  81. end;
  82. begin
  83. // Calculate length of codes
  84. len := 1;
  85. e := length(PalChars);
  86. r := e;
  87. c := img.palette.count;
  88. while (r <= c) do
  89. begin
  90. inc (len);
  91. r := r * e;
  92. end;
  93. MakeCodes ('',len);
  94. end;
  95. procedure InitConsts;
  96. var fmt : string;
  97. begin
  98. fmt := inttostr(FColorSize);
  99. fmt := '%'+fmt+'.'+fmt+'x';
  100. FColorFormat := fmt+fmt+fmt;
  101. case FColorSize of
  102. 1 : FColorShift := 12;
  103. 2 : FColorShift := 8;
  104. 3 : FColorShift := 4;
  105. else FColorShift := 0;
  106. end;
  107. end;
  108. var s : string;
  109. begin
  110. l := TStringList.Create;
  111. p := TStringList.Create;
  112. try
  113. l.Add ('/* XPM */');
  114. l.Add ('static char *graphic[] = {');
  115. c := img.palette.count;
  116. BuildPaletteStrings;
  117. l.add (format('"%d %d %d %d",',[img.width,img.height,c,len]));
  118. InitConsts;
  119. for r := 0 to c-1 do
  120. begin
  121. if img.palette[r] <> colTransparent then
  122. l.Add (format('"%s c #%s",',[p[r],ColorToHex(img.palette.color[r])]))
  123. else
  124. l.Add (format('"%s c None",',[p[r]]));
  125. end;
  126. for r := 0 to img.Height-1 do
  127. begin
  128. s := p[img.pixels[0,r]];
  129. for t := 1 to img.Width-1 do
  130. s := s + p[img.pixels[t,r]];
  131. s := '"'+s+'"';
  132. if r < img.Height-1 then
  133. s := s + ',';
  134. l.Add (s);
  135. end;
  136. l.Add ('};');
  137. finally
  138. l.SaveToStream (Str);
  139. p.Free;
  140. l.Free;
  141. end;
  142. end;
  143. initialization
  144. ImageHandlers.RegisterImageWriter ('XPM Format', 'xpm', TFPWriterXPM);
  145. end.