unit adTextImages;

interface

uses windows,TextImages,ABitmaplight,Graphics,iniFiles,SysUtils,classes,types;

type

TJPXInf = record
 width,height,lineHeight,fontPixels:Integer;
 fontName:string;
 backColor,fontColor:TColor;
 autoWidth,autoHeight,smooth,autoLine,fontTrans:boolean;
end;

TADTextImage=class(TObject)
private
 function loadStrings(fileName:string):TStrings;
 function loadJPXInf(fileName:string):TJPXInf;
 function loadBitmap(sList:TStrings;inf:TJPXInf):TBitmap;
public
 bitmap:TBitmap;
 strings:TStringList;
 jInf:TJPXInf;
 nowFileName:string;
 procedure saveToFile(fileName:string);
 procedure setJPX(fileName:string);overload;
 procedure setJPX(sList:TStrings;inf:TJPXInf);overload;
 constructor create();
 destructor destroy();override;
end;

implementation

constructor TADTextImage.create();
begin
 inherited;
 self.bitmap:=TBitmap.Create();
 self.strings:=TStringList.Create();
end;

destructor TADTextImage.destroy();
begin
 self.bitmap.Free();
 self.strings.Free();
 inherited;
end;

procedure TADTextImage.saveToFile(fileName:string);
var
 sList:TStrings;
 ini:TIniFile;
 n,i,v:Integer;
 s:string;
 hasTag:boolean;
begin
 sList:=TStringList.Create();

 if fileExists(nowFileName)then
 begin
  sList.LoadFromFile(nowFileName);
  sList.SaveToFile(FileName);
 end;

 ini:=TIniFile.Create(fileName);

 ini.WriteInteger('jptx:init','backwidth',jinf.width);
 ini.WriteInteger('jptx:init','backheight',jinf.height);
 ini.WriteInteger('jptx:init','lineheight',jinf.lineHeight);

 v:=TTagText.covertColor(jinf.backColor);
 ini.WriteString('jptx:init','backcolor','$'+IntToHex(v,6));

 ini.WriteBool('jptx:init','autoline',jinf.autoLine);
 ini.WriteBool('jptx:init','antialias',jinf.smooth);
 ini.WriteBool('jptx:init','fonttransparent',jinf.fontTrans);

 ini.WriteInteger('jptx:init','fontpixels',jinf.fontPixels);
 ini.WriteString('jptx:init','fontface',jinf.fontName);

 v:=TTagText.covertColor(jinf.fontColor);
 ini.WriteString('jptx:init','fontcolor','$'+IntToHex(v,6));


 ini.UpdateFile();
 ini.Free();

 sList.LoadFromFile(fileName);

 n:=0;

 (*本文作成*)
 hasTag:=false;
 for  i:=0  to sList.Count-1 do
 begin
  s:=trim(sList.Strings[i]);
  if(s='[jptx:begin]')then
  begin
   hasTag:=true;
   n:=i+1;  //選択行を[init:begin]の行＋１に
   break;
  end
 end;

 if not(hasTag)then
 begin
  sList.Add('[jptx:begin]');
  n:=sList.Count;    //選択行を末尾行＋１に
 end;
// windows.MessageBox(0,PChar(sList.Strings[n]),'',MB_OK);

 hasTag:=false;

 (*[jptx:end]前までの文章を抹消*)
 while(n<sList.Count)do
 begin
  s:=trim(sList.Strings[n]);
  if(s='[jptx:end]')then
  begin
   hasTag:=true;
   break;
  end;
  sList.Delete(n);  //文章の長さがどんどん減っていく
 end;

 if not(hasTag)then
 begin
  sList.Add('[jptx:end]');
 end;

 if(strings.Count>0)then
 begin

  for i:=0 to strings.Count-1 do
  begin
   sList.Insert(n+i,strings.Strings[i]);
  end;

 end;

 sList.SaveToFile(fileName);
 sList.Free();

end;

procedure TADTextImage.setJPX(fileName:string);
var
// startLine:Integer;
 sList:TStrings;
 subBitmap:TBitmap;
begin

 if(fileExists(fileName))then
 begin
  nowFileName:=fileName;
  jInf:=self.loadJPXInf(fileName);

  strings.Clear;
  sList:=self.loadStrings(fileName);
  strings.AddStrings(sList);
  sList.Free();

  self.nowFileName:=fileName;

  subBitmap:=loadBitmap(strings,jInf);
  bitmap.Assign(subBitmap);
  subBitmap.Free();
 end;

end;

procedure TADTextImage.setJPX(sList:TStrings;inf:TJPXInf);
var
 subBitmap:TBitmap;
begin
 strings.Assign(sList);
 self.jInf:=inf;
 subBitmap:=loadBitmap(strings,inf);
 bitmap.Assign(subBitmap);

 subBitmap.Free();
end;

function TADTextImage.loadJPXInf(fileName:string):TJPXInf;
var
 ini:TiniFile;

 s:string;
begin

 ini:=TiniFile.Create(fileName);

 try
  result.width:=ini.ReadInteger('jptx:init','backwidth',-1);
  result.height:=ini.ReadInteger('jptx:init','backheight',-1);

  result.lineHeight:=ini.ReadInteger('jptx:init','lineheight',100);
  result.backColor:=TTagText.getColor(ini.ReadString('jptx:init','backcolor','0'));
  result.autoLine:=ini.ReadBool('jptx:init','autoline',true);

  result.smooth:=ini.ReadBool('jptx:init','antialias',false);
  result.fontTrans:=ini.ReadBool('jptx:init','fonttransparent',false);
  s:=ini.ReadString('jptx:init','fontpixels','');
  result.fontPixels:=TTagText.getInteger(s,12);

  result.fontName:=ini.ReadString('jptx:init','fontface','ＭＳ Ｐゴシック');
  result.fontColor:=TTagText.getColor(ini.ReadString('jptx:init','fontcolor','0'));
 finally
  ini.Free();
 end;

end;

function TADTextImage.loadStrings(fileName:string):TStrings;
var
 i,n:Integer;
 s:string;
 items:TStringList;
begin

 result:=TStringList.Create();
 items:=TStringList.Create();
 items.LoadFromFile(fileName);
 n:=0;

 for  i:=0  to items.Count-1 do
 begin
  s:=trim(items.Strings[i]);
  if(s='[jptx:begin]')then
  begin
   n:=i+1;
   break;
  end
 end;

 for i:=n to items.Count-1 do
 begin
  s:=trim(items.Strings[i]);
  if(s='[jptx:end]')then break;
  result.Add(items.Strings[i]);
 end;


end;

function TADTextImage.loadBitmap(sList:TStrings;inf:TJPXInf):TBitmap;
var
 i,widest,highest:Integer;
 check:shortInt;
// s:string;
 tagText:TTagText;
 tInf:TTextInf;
 pos:TPoint;
const
 padding=1;
begin

 tInf:=TTextInf.Create();
 tagText:=TTagtext.create();
        
 (*キャンバスの設定*)
  result:=TBitmap.Create();
  result.HandleType:=bmDIB;
  result.PixelFormat:=pf32bit;
  result.Width:=632;
  result.Height:=420;
  result.Canvas.Font.Color:=inf.fontColor;
  result.Canvas.Font.Height:=inf.fontPixels;
  result.Canvas.Brush.Color:=inf.backColor;
  result.Canvas.FillRect(result.Canvas.ClipRect);

  result.Canvas.Font.Charset:=DEFAULT_CHARSET;
  result.Canvas.Font.Name:=inf.fontName;
  result.Canvas.Brush.Style:=bsClear;

  if(inf.fontTrans)then
  begin
   result.Canvas.Pen.Color:=result.Canvas.Font.Color;
   result.Canvas.PenPos:=Point(0,0);
   result.Canvas.LineTo(result.Width,0);
  end;

  tInf.x:=0;
  tInf.y:=padding;
  tInf.lineHeight:=inf.lineHeight;
  tInf.font:=result.Canvas.Font;
  tInf.newline:=false;

  widest:=0;
  highest:=0;

 try

  (*実際の文字の入力*)

  tInf.x:=0;
  check:=ttNone;

  for  i:=0  to sList.Count-1 do
  begin

   if(trim(sList.Strings[i])='[jptx:end]')then
   begin
    break;
   end;

   if(inf.autoLine)then tInf.x:=0;

   check:=tagText.setText(sList.Strings[i],check);
   if(check=ttClose)then
   begin
    repeat

     (*タグの無い部分の描画*)
     if(tagText.lText<>'')then
     begin
      if(tinf.antialias)then
       pos:=SuperTextOut(result,tInf.x,tInf.y,result.Canvas.Font,tagText.lText)
      else
      begin
       result.Canvas.TextOut(tInf.x,tInf.y,tagText.lText);
       pos:=result.Canvas.PenPos;
      end;

      tInf.x:=Pos.X;
      widest:=max(widest,tInf.x);
      highest:=max(highest,pos.y+result.Canvas.Font.Height);
     end;
     tInf:=tagText.getTextInf(tInf,tagText.mText); //タグ情報の読み込み
     result.Canvas.Font:=tInf.font;


     (*強制改行*)
     if(tInf.newline)then
     begin
      tInf.newline:=false;
      tagText.lText:='';
      tInf.x:=0;
      inc(tInf.y,Round(result.Canvas.Font.Height*tinf.lineHeight/100));
     end;

     tagText.mText:='';
     check:=tagText.setText(tagText.rText,check);

    until(check<>ttClose);

    if(tagText.lText<>'')then
    begin
     if(tinf.antialias)then
       pos:=SuperTextOut(result,tInf.x,tInf.y,result.Canvas.Font,tagText.lText)
     else
     begin
      result.Canvas.TextOut(tInf.x,tInf.y,tagText.lText);
      pos:=result.Canvas.PenPos;
     end;

     tInf.x:=Pos.X;
     widest:=max(widest,tinf.x);
     highest:=max(highest,pos.y+result.Canvas.Font.Height);
    end;

   end
   else
   begin

    if(tagText.lText<>'')then
    begin
     if(tinf.antialias)then
       pos:=SuperTextOut(result,tInf.x,tInf.y,result.Canvas.Font,tagText.lText)
     else
     begin
      result.Canvas.TextOut(tInf.x,tInf.y,tagText.lText);
      pos:=result.Canvas.PenPos;
     end;

    tInf.x:=pos.x;
    widest:=max(widest,tInf.x);
    highest:=max(highest,pos.y+result.Canvas.Font.Height);
   end;

    if(inf.autoLine)then tInf.x:=1;

   end;

   if(tInf.x>0)and(inf.autoLine)then
   begin
    tInf.x:=0;
    inc(tInf.y,Round(result.Canvas.Font.Height*tinf.lineHeight/100));
   end;

  end;

  inc(tInf.y,result.Canvas.Font.Height+tinf.lineHeight);

  (*背景にサイズ設定が無い場合自動的に設定*)
  if(inf.width<1)then
  begin
   widest:=min(widest,632);
   result.Width:=widest;
  end
  else result.Width:=inf.width;

  if(inf.height<1)then
  begin
   highest:=min(highest,420);
   result.Height:=highest;
  end
  else
   result.Height:=inf.height;

  tagText.Free();
  tInf.Free();

 except
  tagText.Free();
  tInf.Free();
  windows.MessageBox(0,'','テキスト描画のエラー',MB_OK);
 end;
   
end;



end.
