fpwritexpm.pp 3.8 KB

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