www.pudn.com > GetZM.rar > Main.pas


unit Main; 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, ComCtrls, StdCtrls, ExtCtrls, Buttons, Spin, Menus, MyClasses, 
  jpeg; 
 
const 
  DrawStep = 10; 
  MouseMoveTimer = 5; 
  HZ_16x16 = 1; 
  HZ_24x24 = 2; 
  HZ_32x32 = 3; 
  ZF_8x16  = 4; 
  ZF_12x24 = 5; 
  ZF_16x32 = 6; 
 
type 
  TFrm_Main = class(TForm) 
    PageControl1: TPageControl; 
    TabSheet1: TTabSheet; 
    TabSheet2: TTabSheet; 
    Meo_ShowData: TMemo; 
    MainMenu1: TMainMenu; 
    Menu_File: TMenuItem; 
    Sub_Menu_Open: TMenuItem; 
    Menu_Save: TMenuItem; 
    N1: TMenuItem; 
    Menu_Exit: TMenuItem; 
    SaveDialog1: TSaveDialog; 
    OpenDialog1: TOpenDialog; 
    GroupBox1: TGroupBox; 
    Label2: TLabel; 
    Label3: TLabel; 
    Label1: TLabel; 
    Label4: TLabel; 
    SpnEdt_Width: TSpinEdit; 
    SpnEdt_Height: TSpinEdit; 
    Btn_Apply: TBitBtn; 
    SpnEdt_OutputWidth: TSpinEdit; 
    Label5: TLabel; 
    Edt_Note: TEdit; 
    Btn_DoOperation: TBitBtn; 
    GroupBox2: TGroupBox; 
    RBn_HZ: TRadioButton; 
    RBn_ZF: TRadioButton; 
    GroupBox3: TGroupBox; 
    RBn_hz16x16: TRadioButton; 
    RBn_hz24x24: TRadioButton; 
    RBn_hz32x32: TRadioButton; 
    Btn_ClearWorkspace: TBitBtn; 
    Btn_Exit: TBitBtn; 
    Label6: TLabel; 
    Edt_ZMSource: TEdit; 
    Btn_GetZM: TBitBtn; 
    Btn_ClearGetZM: TBitBtn; 
    RBn_zf16x32: TRadioButton; 
    RBn_zf12x24: TRadioButton; 
    RBn_zf8x16: TRadioButton; 
    Lbl_DrawBack: TLabel; 
    Img_Draw: TImage; 
    Label7: TLabel; 
    Label8: TLabel; 
    SpnEdt_OutputWidth1: TSpinEdit; 
    CmB_ReadDirect: TComboBox; 
    Label9: TLabel; 
    Label10: TLabel; 
    CmB_GetDirect: TComboBox; 
    procedure Btn_DoOperationClick(Sender: TObject); 
    procedure FormActivate(Sender: TObject); 
    procedure Img_DrawMouseMove(Sender: TObject; Shift: TShiftState; X, 
      Y: Integer); 
    procedure Img_DrawMouseDown(Sender: TObject; Button: TMouseButton; 
      Shift: TShiftState; X, Y: Integer); 
    procedure Btn_ApplyClick(Sender: TObject); 
    procedure SpnEdt_WidthChange(Sender: TObject); 
    procedure Btn_ClearWorkspaceClick(Sender: TObject); 
    procedure Sub_Menu_OpenClick(Sender: TObject); 
    procedure Menu_SaveClick(Sender: TObject); 
    procedure FormClose(Sender: TObject; var Action: TCloseAction); 
    procedure Menu_ExitClick(Sender: TObject); 
    procedure PageControl1Change(Sender: TObject); 
    procedure RBn_HZClick(Sender: TObject); 
    procedure RBn_hz16x16Click(Sender: TObject); 
    procedure Btn_GetZMClick(Sender: TObject); 
    procedure Btn_ClearGetZMClick(Sender: TObject); 
    procedure RBn_hz24x24Click(Sender: TObject); 
    procedure RBn_hz32x32Click(Sender: TObject); 
    procedure RBn_zf8x16Click(Sender: TObject); 
    procedure RBn_zf12x24Click(Sender: TObject); 
    procedure RBn_zf16x32Click(Sender: TObject); 
    procedure Img_DrawMouseUp(Sender: TObject; Button: TMouseButton; 
      Shift: TShiftState; X, Y: Integer); 
    procedure SpnEdt_WidthExit(Sender: TObject); 
    procedure SpnEdt_HeightExit(Sender: TObject); 
    procedure CmB_GetDirectChange(Sender: TObject); 
    procedure CmB_ReadDirectChange(Sender: TObject); 
  private 
    { Private declarations } 
    DataGroup:array[0..128] of Byte; 
    DataPointer:Integer; 
    mystr:MyString; 
    Modified:Boolean; 
    Read_Direct:Integer; 
    Get_Direct:Integer; 
    Cur_GetDirect:Integer; 
    Cur_ReadDirect:Integer; 
//if previous draw width,height and step is same as current, don't draw again 
    preDrawWidth:Integer; 
    preDrawHeight:Integer; 
    preDrawStep:Integer; 
    preGetText:String; 
 
    SecondPageInit:Boolean; 
//    MouseDown:Boolean; //for mouse move to draw grid 
    MouseMove:Boolean; //for mouse move to draw grid 
    MouseMoveCounter:Integer;     
 
    procedure DrawGrid(width:Integer;height:Integer;step:Integer); 
//    procedure FillGrid(X:Integer;Y:Integer;step:Integer); 
    procedure FillDataGroup(X:Integer;Y:Integer;step:Integer;mark:Boolean); 
    procedure GetDataInFile(source:TMemo); 
    procedure DrawZMWithData(width:Integer;height:Integer;inputdata:Array of Byte; 
      step:Integer); 
    procedure Menu_Enable(mark:Boolean); 
    procedure ShowZMDataInGroup(gridwidth:Integer;gridheight:Integer; 
      linewidth:Byte); 
    procedure ClearGrid(); 
 
    function GetParamInFile(source:TMemo):Boolean; 
    function GetChineseLattice(InputText:String;out LatticeData: array of Byte; 
      inputsize:Byte): Boolean; 
    function FillGrid(X:Integer;Y:Integer;step:Integer):Byte; 
    function IsPixelInFillGroup(xstart:Integer;ystart:Integer):Boolean; 
 
  public 
    { Public declarations } 
  end; 
 
var 
  Frm_Main: TFrm_Main; 
 
implementation 
 
{$R *.dfm} 
 
procedure TFrm_Main.FormActivate(Sender: TObject); 
var 
  counter:Integer; 
begin 
  for counter := 0 to 128 do 
    DataGroup[counter] := 0; 
  DataPointer := 0; 
  preDrawWidth := 0; 
  preDrawHeight := 0; 
  preDrawStep := 0; 
  SpnEdt_OutputWidth.Value := 8; 
  SpnEdt_OutputWidth1.Value := 8; 
  SecondPageInit := True; 
  Modified := False; 
  preGetText := ''; 
//  MouseDown := False; 
  MouseMove := False; 
  MouseMoveCounter := 0; 
  Frm_Main.DoubleBuffered := True; //let the image control don't flash 
  DrawGrid(SpnEdt_Width.Value,SpnEdt_Height.Value,DrawStep); 
  mystr := MyString.Create; 
  Read_Direct := CmB_ReadDirect.ItemIndex; 
  Cur_ReadDirect := CmB_ReadDirect.ItemIndex; 
  Get_Direct := CmB_GetDirect.ItemIndex; 
  Cur_GetDirect := CmB_GetDirect.ItemIndex; 
  if(PageControl1.TabIndex = 1) then 
  begin 
    RBn_hz16x16.Checked := True; 
    SecondPageInit := False; 
    RBn_HZ.SetFocus; 
  end 
  else 
    SpnEdt_Width.SetFocus; 
end; 
 
procedure TFrm_Main.FormClose(Sender: TObject; var Action: TCloseAction); 
begin 
  mystr.Destroy; 
end; 
 
procedure TFrm_Main.ClearGrid(); 
var 
  counter:Integer; 
begin 
  if Modified then 
  begin 
    for counter := 0 to 128 do 
      DataGroup[counter] := 0; 
    Modified := False; 
  end; 
end; 
 
procedure TFrm_Main.ShowZMDataInGroup(gridwidth:Integer;gridheight:Integer; 
  linewidth:Byte); 
var 
  tmpstr:String; 
  tmpstr1:String; 
  width:Byte; 
  height:Byte; 
  counter:Integer; 
  counter1:Integer; 
  counter2:Integer; 
  counter3:Integer; 
  counter4:Integer; 
  counter5:Integer; 
  temvalue:Integer; 
  size:Integer; 
  Note:String; 
  pos:Integer; 
  value:Byte; 
  width1:Byte; 
  height1:Byte; 
  starty:Integer; 
  endH:Integer; 
  toH:Integer; 
  direct:Integer; 
begin 
  if(PageControl1.TabIndex = 1) then 
    direct := CmB_GetDirect.ItemIndex 
  else 
    direct := CmB_ReadDirect.ItemIndex; 
  if(direct = 1) then  //纵向 
  begin 
    width := gridwidth; 
    height := gridheight div 8; 
    if(PageControl1.TabIndex = 1) then 
      direct := 0; 
  end 
  else 
  begin 
    width := gridwidth div 8; 
    height := gridheight; 
  end; 
  size := width * height; 
  tmpstr := 'unsigned char ID' + inttostr(DataPointer) + '_' + inttostr(width) + 
              'x' + inttostr(height) + '[] ='; 
  Note := ''; 
  if Edt_Note.Text <> '' then 
    Note := Edt_Note.Text; 
  if Edt_ZMSource .Text <> '' then 
    Note := Edt_ZMSource.Text; 
  if Note <> '' then 
    tmpstr := tmpstr + '  /* ' + Note + ' */'; 
  Meo_ShowData.Lines.Add(tmpstr); 
  Meo_ShowData.Lines.Add('{'); 
  tmpstr := ' '; 
  if(direct = 1) then 
  begin 
    width1 := gridwidth div 8; 
    height1 := gridheight; 
    counter3 := 0; 
    counter5 := 0; //to count the byte counter 
    if((gridheight mod 8) = 0) then 
      toH := gridheight div 8 
    else 
      toH := (gridheight div 8) + 1; 
    for counter4 := 0 to toH do 
    begin 
      endH := (counter4 + 1) * 8; 
      if endH > height1 then 
        endH := height1; 
      for counter := 0 to (width1 - 1) do 
      begin 
        starty := counter4 * 8;       
        value := 0; 
        for counter2 := 0 to 7 do    //8 bit 
        begin       
          for counter1 := starty to (endH - 1) do 
          begin     
            pos := counter1 * width1 + counter; 
            temvalue := 1 shl (7 - counter2); 
            if((DataGroup[pos] and temvalue) = temvalue) then 
            begin 
              temvalue := 1 shl (counter1 mod 8); 
              value := value or temvalue; 
            end; 
            if((counter1 mod 8) = 7) then 
            begin 
              if(value < 16) then 
                tmpstr1 := Format('0x0%x',[value]) 
              else 
                tmpstr1 := Format('0x%x',[value]); 
              counter3 := counter3 + 1; 
              counter5 := counter5 + 1; 
              value := 0; 
              if(counter5 = size) then //last byte 
                tmpstr := tmpstr + tmpstr1 
              else 
                tmpstr := tmpstr + tmpstr1 + ','; 
            end; 
            if(counter3 = linewidth) then 
            begin 
              Meo_ShowData.Lines.Add(tmpstr); 
              counter3 := 0; 
              tmpstr := ' '; 
            end;         
          end; 
        end;       
      end; 
    end; 
  end 
  else 
  begin 
    for counter := 0 to (size - 1) do 
    begin 
      if(DataGroup[counter] < 16) then 
        tmpstr1 := Format('0x0%x',[DataGroup[counter]]) 
      else 
        tmpstr1 := Format('0x%x',[DataGroup[counter]]); 
      if counter = (size - 1) then //last byte 
        tmpstr := tmpstr + tmpstr1 
      else 
        tmpstr := tmpstr + tmpstr1 + ','; 
      if (counter <> 0) and 
         ((counter mod linewidth) = (linewidth - 1)) then 
      begin 
        Meo_ShowData.Lines.Add(tmpstr); 
        tmpstr := ' '; 
      end; 
    end; 
  end; 
  if (size mod linewidth) <> 0 then 
    Meo_ShowData.Lines.Add(tmpstr); 
  Meo_ShowData.Lines.Add('}'); 
  DataPointer := DataPointer + 1; 
end;   
       
//hz: font size: 12: 16x16    17:24x24   23:32x32  (宋体) 
//zf: font size: 11:8x16    16:12x24   22:16x32  (MS Sans Serif) 
//CharSize: define for size: HZ_16x16, HZ_24x24, HZ_32x32, ZF_8x16, ZF_12x24, 
//                           ZF_16x32 
//CharType: 1: chinese      2: charactor 
//LatticeData: output data group 
function TFrm_Main.GetChineseLattice(InputText:String;out LatticeData: array of Byte; 
         inputsize:Byte): Boolean; 
var    
  bmp_Text:TBitmap; 
  chartype:String; 
  charsize:Byte; 
  c_temp: Byte; 
  shiftbit:Byte; 
  counter,counter1,counter2: Integer; 
  color:TColor; 
  value:Byte; 
  linewidth:Byte; 
begin 
  if(inputsize > ZF_16x32) or (inputsize = 0) then 
    Result := False 
  else 
  begin 
	bmp_Text := TBitmap.Create; //创建背景扫描图 
    with bmp_Text do 
    begin 
      PixelFormat := pf8bit; 
      case inputsize of 
        HZ_16x16: begin 
                    Width := 16; 
                    Height := 16; 
                    chartype := '宋体'; 
                    charsize := 12; 
                  end; 
        HZ_24x24: begin 
                    Width := 24; 
                    Height := 24; 
                    chartype := '宋体'; 
                    charsize := 17; 
                  end; 
        HZ_32x32: begin 
                    Width := 32; 
                    Height := 32; 
                    chartype := '宋体'; 
                    charsize := 23; 
                  end; 
        ZF_8x16: begin 
                    Width := 8; 
                    Height := 16; 
                    chartype := 'MS Sans Serif'; 
                    charsize := 11; 
                 end; 
        ZF_12x24: begin 
                    Width := 12; 
                    Height := 24; 
                    chartype := 'MS Sans Serif'; 
                    charsize := 16; 
                  end; 
        ZF_16x32: begin 
                    Width := 16; 
                    Height := 32; 
                    chartype := 'MS Sans Serif'; 
                    charsize := 22; 
                  end 
      else 
        Width := 16; 
        Height := 16; 
        chartype := '宋体'; 
        charsize := 12; 
      end; 
      Canvas.Font.Name := chartype; 
      Canvas.Font.Size := charsize; 
      Canvas.Font.Color := clBlack; 
      Canvas.TextRect(Rect(0,0,Width,Height),0,0,InputText); 
      if(CmB_GetDirect.ItemIndex = 1) then //纵向 
      begin 
        linewidth := Height div 8; 
        for counter := 0 to (linewidth - 1) do 
        begin 
          for counter1 := 0 to (Width - 1) do 
          begin 
            for counter2 := 0 to 7 do 
            begin 
              color := Canvas.Pixels[counter1,counter * 8 + counter2]; 
              if color = clBlack then 
              begin 
                c_temp := counter * Width + counter1; 
                shiftbit := counter2 mod 8; 
                value := (1 shl shiftbit); 
                LatticeData[c_temp] := LatticeData[c_temp] or value; 
              end; 
            end; 
          end; 
        end; 
      end 
      else 
      begin 
        linewidth := Width div 8; 
        for counter := 0 to Height do //开始扫描 
        begin 
          for counter1 := 0 to Width do 
          begin 
            color := Canvas.Pixels[counter1,counter]; 
            if color = clBlack then 
            begin 
              c_temp := (counter1 div 8) + counter * linewidth; 
              shiftbit := 7 - (counter1 mod 8); 
              value := (1 shl shiftbit); 
              LatticeData[c_temp] := LatticeData[c_temp] or value; 
            end; 
          end; 
        end; 
      end; 
      Free; 
    end; 
    Result := true; 
  end; 
end; 
 
procedure TFrm_Main.Menu_Enable(mark:Boolean); 
begin 
  Sub_Menu_Open.Enabled := mark; 
end; 
 
procedure TFrm_Main.DrawZMWithData(width:Integer;height:Integer;inputdata:Array of Byte; 
                                   step:Integer); 
var 
  counter,counter1,total:Integer; 
  linewidth:Integer; 
  linehieght:Integer; 
  mark:Byte; 
  X,Y:Integer; 
begin 
  linewidth := width div 8; //change to byte 
  linehieght := height; 
  total := linewidth * linehieght; 
  for counter := 0 to total do 
  begin 
    for counter1 := 0 to 7 do 
    begin 
      mark := 1 shl (7 - counter1); 
      if ((inputdata[counter] and mark) = mark) then 
      begin 
        X := ((counter mod linewidth) * 8 + counter1) * step + 3; 
        Y := (counter div linewidth) * step + 3; 
        FillGrid(X,Y,step); 
      end; 
    end; 
  end; 
end; 
 
procedure TFrm_Main.GetDataInFile(source:TMemo); 
var 
  tmpstr:String; 
  counter,total:Integer; 
  counter1,counter2:Integer; 
  counter3,counter4:Integer; 
  counter5:Integer; 
  pos:Integer; 
  tmpvalue:Integer; 
  value:Integer; 
  width:Integer; 
//  height:Integer; 
  total1:Integer; 
  direct:Integer; 
  linebyte:Integer; 
begin 
  total := source.Lines.Count - 2; 
  for counter := 0 to 128 do 
    DataGroup[counter] := 0; 
  if(PageControl1.TabIndex = 1) then 
  begin 
    direct := CmB_GetDirect.ItemIndex; 
    linebyte := SpnEdt_OutputWidth1.Value; 
  end 
  else 
  begin 
    direct := CmB_ReadDirect.ItemIndex; 
    linebyte := SpnEdt_OutputWidth.Value; 
  end; 
  if(direct = 1) then 
  begin 
    width := SpnEdt_Width.Value div 8; 
    counter3 := 0; 
    total1 := 8; 
    counter5 := 0; 
    for counter := 2 to total do 
    begin 
      mystr.Text := source.Lines[counter]; 
      for counter1 := 1 to linebyte do 
      begin 
        tmpstr := mystr.GetStringWithSpCharCount('0x',counter1,2); 
        if tmpstr <> '' then 
        begin 
          tmpstr := '0x' + tmpstr; 
          value := StrToInt(tmpstr);  //get the value 
          counter4 := total1 - 8; 
          for counter2 := 0 to 7 do 
          begin 
            tmpvalue := 1 shl counter2; 
            pos := counter4 * width + counter3; 
            if(value and tmpvalue) = tmpvalue then 
              DataGroup[pos] := DataGroup[pos] or (1 shl (7 - counter5)); 
            counter4 := counter4 + 1; 
          end; 
          counter5 := counter5 + 1; 
          if(counter5 = 8) then 
          begin 
            counter5 := 0; 
            counter3 := counter3 + 1; 
            if(counter3 = width) then 
            begin 
              counter3 := 0; 
              total1 := total1 + 8; 
            end; 
          end; 
        end; 
      end; 
    end; 
  end 
  else 
  begin 
    counter2 := 0; 
    for counter := 2 to total do 
    begin 
      mystr.Text := source.Lines[counter]; 
      for counter1 := 1 to linebyte do 
      begin 
        tmpstr := mystr.GetStringWithSpCharCount('0x',counter1,2); 
        if tmpstr <> '' then 
        begin 
          tmpstr := '0x' + tmpstr; 
          DataGroup[counter2] := StrToInt(tmpstr); 
          counter2 := counter2 + 1; 
        end; 
      end; 
    end; 
  end; 
end; 
 
Function TFrm_Main.GetParamInFile(source:TMemo):Boolean; 
var 
  tmpstr:String; 
  tmpint:Integer; 
begin 
  mystr.Text := source.Lines[0]; 
  try 
    tmpstr := mystr.GetStringBetweenChar('_','x'); 
    tmpint := StrToInt(tmpstr); 
    if(tmpint >= 8) then//表示纵向,因为最大的字32x32,横向最大为4 
    begin 
      SpnEdt_Width.Value := tmpint; 
      CmB_ReadDirect.ItemIndex := 1; 
    end 
    else 
    begin 
      SpnEdt_Width.Value := tmpint * 8; 
      CmB_ReadDirect.ItemIndex := 0; 
    end; 
    Read_Direct := CmB_ReadDirect.ItemIndex; 
    Cur_ReadDirect := CmB_ReadDirect.ItemIndex; 
    tmpstr := mystr.GetStringBetweenChar('x','['); 
    tmpint := StrToInt(tmpstr); 
    if(CmB_ReadDirect.ItemIndex = 1) then 
      SpnEdt_Height.Value := tmpint * 8 
    else 
      SpnEdt_Height.Value := tmpint; 
    tmpstr := mystr.GetStringBetweenChar('*','*'); 
    tmpint := Length(tmpstr) - 2; 
    Edt_Note.Text := Copy(tmpstr,2,tmpint); 
    mystr.Text := source.Lines[2]; 
    tmpint := mystr.GetSpecialCharCount('0x'); 
    SpnEdt_OutputWidth.Value := tmpint; 
    Result := True; 
  except 
    Result := False; 
  end; 
end; 
 
procedure TFrm_Main.Btn_DoOperationClick(Sender: TObject); 
begin 
  if (Sender <> nil) then 
  begin 
    if(Read_Direct <> CmB_ReadDirect.ItemIndex) then 
    begin 
      Modified := True; 
      Read_Direct := CmB_ReadDirect.ItemIndex; 
    end; 
  end; 
  if Modified then 
  begin 
    Meo_ShowData.Clear; 
    if(PageControl1.TabIndex = 1) then 
      ShowZMDataInGroup(preDrawWidth,preDrawHeight,SpnEdt_OutputWidth1.Value) 
    else 
      ShowZMDataInGroup(preDrawWidth,preDrawHeight,SpnEdt_OutputWidth.Value); 
  end; 
end; 
//to know the pixel is in a fill grid, 
//if true return true ,else reture false 
function TFrm_Main.IsPixelInFillGroup(xstart:Integer;ystart:Integer):Boolean; 
var 
  pointer1:Integer; 
  width:Byte; 
  value:Byte; 
begin 
  pointer1 := 7 - (xstart mod 8); //get x 
  value := (1 shl pointer1); 
  width := SpnEdt_Width.Value div 8; 
  pointer1 := ystart * width + xstart div 8; 
  if(DataGroup[pointer1] and value) = value then 
    Result := True 
  else 
   Result := False; 
end; 
//mark: True : add the bit        False: clear this bit  
procedure TFrm_Main.FillDataGroup(X:Integer;Y:Integer;step:Integer;mark:Boolean); 
var 
  xstart:Integer; 
  ystart:Integer; 
  pointer1:Integer; 
  width:Byte; 
  value:Byte; 
begin 
  xstart := X div step; //get the x bit 
  ystart := Y div step; 
  pointer1 := 7 - (xstart mod 8); //get x 
  value := (1 shl pointer1); 
  width := SpnEdt_Width.Value div 8; 
  pointer1 := ystart * width + xstart div 8; 
  if mark then 
    DataGroup[pointer1] := DataGroup[pointer1] or value 
  else 
    DataGroup[pointer1] := DataGroup[pointer1] xor value; 
end; 
 
procedure TFrm_Main.DrawGrid(width:Integer;height:Integer;step:Integer); 
var 
  counter:Integer; 
  rect:TRect; 
begin 
//draw the back color 
  if(preDrawWidth <> width) or (preDrawHeight <> height) or 
    (preDrawStep <> step) then 
  begin 
    preDrawWidth := width; 
    preDrawHeight := height; 
    preDrawStep := step; 
    Img_Draw.Width := width * step + 1; 
    Img_Draw.Height := height * step + 1; 
    Img_Draw.Left := Lbl_DrawBack.Left + (Lbl_DrawBack.Width - Img_Draw.Width) div 2; 
    Img_Draw.Top := Lbl_DrawBack.Top + (Lbl_DrawBack.Height - Img_Draw.Height) div 2; 
    Img_Draw.Picture.Bitmap.Width := Img_Draw.Width; 
    Img_Draw.Picture.Bitmap.Height := Img_Draw.Height; 
    Img_Draw.Canvas.Brush.Color := $006A9B46;//clGray; 
    rect.Left := 0; 
    rect.Top := 0; 
    rect.Right := Img_Draw.ClientWidth; 
    rect.Bottom := Img_Draw.ClientHeight; 
    Img_Draw.Canvas.FillRect(rect); 
     
//  draw grid 
    Img_Draw.Canvas.Pen.Color := ClWhite; 
//   draw vertical line 
    for counter := 0 to width do 
    begin 
      Img_Draw.Canvas.MoveTo(counter * step,0); 
      Img_Draw.Canvas.LineTo(counter * step,Img_Draw.ClientHeight); 
    end; 
//  draw horizontal line 
    for counter := 0 to height do 
    begin 
      Img_Draw.Canvas.MoveTo(0,counter * step); 
      Img_Draw.Canvas.LineTo(Img_Draw.ClientWidth,counter * step); 
    end; 
  end; 
end; 
 
//return 0: must clear this bit 
//       1: must set this bit 
//       2: do nothing with this bit 
function TFrm_Main.FillGrid(X:Integer;Y:Integer;step:Integer):Byte; 
var 
  xstart:Integer; 
  ystart:Integer; 
  rect:TRect; 
  color:TColor; 
begin 
  xstart := X div step; 
  ystart := Y div step; 
  rect.Left := xstart * step + 1; 
  rect.Top := ystart * step + 1; 
  rect.Right := rect.Left + step - 2; 
  rect.Bottom := rect.Top + step - 2; 
  color := Img_Draw.Canvas.Pixels[X,Y]; 
  if(color = ClBlack) then 
  begin 
    if not MouseMove then 
    begin 
      Img_Draw.Canvas.Brush.Color := $006A9B46;//clGray 
      Result := 0; 
    end 
    else 
      Result := 2; 
  end 
  else 
  begin 
    Img_Draw.Canvas.Brush.Color := ClBlack; 
    Result := 1; 
  end; 
  if(Result <> 2) then 
    Img_Draw.Canvas.FillRect(rect); 
end; 
 
procedure TFrm_Main.Img_DrawMouseMove(Sender: TObject; Shift: TShiftState; 
  X, Y: Integer); 
var 
  xstart:Integer; 
  ystart:Integer; 
  rect:TRect; 
  addmark:Boolean; 
begin 
  if(Shift = [ssLeft])then 
  begin 
    if(MouseMoveCounter >= MouseMoveTimer) then 
    begin 
      MouseMove := True; 
      xstart := X div DrawStep; 
      ystart := Y div DrawStep; 
      if not IsPixelInFillGroup(xstart,ystart) then 
      begin 
        rect.Left := xstart * DrawStep + 1; 
        rect.Top := ystart * DrawStep + 1; 
        rect.Right := rect.Left + DrawStep - 2; 
        rect.Bottom := rect.Top + DrawStep - 2; 
        Img_Draw.Canvas.Brush.Color := ClBlack; 
        addmark := True; 
        Img_Draw.Canvas.FillRect(rect); 
        FillDataGroup(X,Y,DrawStep,addmark); 
        if not Modified then 
          Modified := True; 
      end; 
    end 
    else 
      MouseMoveCounter := MouseMoveCounter + 1; 
  end 
  else 
  begin 
    MouseMoveCounter := 0; 
    MouseMove := False; 
  end; 
end; 
 
procedure TFrm_Main.Img_DrawMouseDown(Sender: TObject; 
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 
var 
  bret:Byte; 
begin 
  if PageControl1.ActivePageIndex = 0 then 
  begin 
    if not MouseMove then 
    begin 
      bret := FillGrid(X,Y,DrawStep); 
      if bret = 1 then 
      begin 
        FillDataGroup(X,Y,DrawStep,True); 
        if not Modified then 
          Modified := True; 
      end 
      else if bret = 0 then 
        FillDataGroup(X,Y,DrawStep,False); 
    end; 
  end; 
end; 
 
procedure TFrm_Main.Img_DrawMouseUp(Sender: TObject; Button: TMouseButton; 
  Shift: TShiftState; X, Y: Integer); 
begin 
  MouseMove := False; 
  MouseMoveCounter := 0; 
end; 
 
 
procedure TFrm_Main.Btn_ApplyClick(Sender: TObject); 
begin 
  Btn_Apply.Enabled := False; 
  Btn_ClearWorkspaceClick(Sender); 
end; 
 
procedure TFrm_Main.SpnEdt_WidthChange(Sender: TObject); 
begin 
  Btn_Apply.Enabled := True; 
end; 
 
procedure TFrm_Main.Btn_ClearWorkspaceClick(Sender: TObject); 
begin 
  preDrawWidth := 0; 
  preDrawHeight := 0; 
  preDrawStep := 0; 
  DrawGrid(SpnEdt_Width.Value,SpnEdt_Height.Value,DrawStep); 
  if Sender <> nil then 
  begin 
    Meo_ShowData.Clear; 
    Edt_Note.Text := ''; 
  end; 
  Modified := True; 
  ClearGrid(); 
  DataPointer := 0; 
end; 
 
procedure TFrm_Main.Sub_Menu_OpenClick(Sender: TObject); 
begin 
  if OpenDialog1.Execute then 
  begin 
    Meo_ShowData.Lines.LoadFromFile(OpenDialog1.FileName); 
    if GetParamInFile(Meo_ShowData) then 
    begin 
      Btn_ApplyClick(nil); 
      GetDataInFile(Meo_ShowData); 
      DrawZMWithData(SpnEdt_Width.Value,SpnEdt_Height.Value,DataGroup,DrawStep); 
      PageControl1.ActivePageIndex := 0; 
    end; 
  end; 
end; 
 
procedure TFrm_Main.Menu_SaveClick(Sender: TObject); 
begin 
  if Meo_ShowData.Lines.Count > 0 then 
  begin 
    if SaveDialog1.Execute then 
      Meo_ShowData.Lines.SaveToFile(SaveDialog1.FileName); 
  end 
  else 
    Application.MessageBox('操作无法完成','提示',MB_OK); 
end; 
 
procedure TFrm_Main.Menu_ExitClick(Sender: TObject); 
begin 
  Close; 
end; 
 
procedure TFrm_Main.PageControl1Change(Sender: TObject); 
begin 
  preDrawWidth := 0; 
  preDrawHeight := 0; 
  preDrawStep := 0; 
  if(PageControl1.TabIndex = 1) then 
  begin 
    Edt_ZMSource.Text := ''; 
    SecondPageInit := True; 
    Menu_Enable(False); 
    RBn_zf8x16.Checked := True; 
    RBn_hz16x16.Checked := True; 
    RBn_HZ.Checked := True; 
    SecondPageInit := False; 
    Get_Direct := CmB_GetDirect.ItemIndex; 
    Cur_GetDirect := CmB_GetDirect.ItemIndex; 
    RBn_hz16x16.SetFocus; 
  end 
  else 
  begin 
    ClearGrid(); 
    Meo_ShowData.Clear; 
    Menu_Enable(True); 
    Edt_Note.Text := ''; 
    DrawGrid(SpnEdt_Width.Value,SpnEdt_Height.Value,DrawStep); 
    RBn_HZ.Checked := False; 
    Read_Direct := CmB_ReadDirect.ItemIndex; 
    Cur_ReadDirect := CmB_ReadDirect.ItemIndex; 
    SpnEdt_Width.SetFocus; 
  end; 
end; 
 
procedure TFrm_Main.RBn_HZClick(Sender: TObject); 
begin 
  RBn_hz16x16.Enabled := RBn_HZ.Checked; 
  RBn_hz24x24.Enabled := RBn_HZ.Checked; 
  RBn_hz32x32.Enabled := RBn_HZ.Checked; 
  RBn_zf8x16.Enabled  := RBn_ZF.Checked; 
  RBn_zf12x24.Enabled := RBn_ZF.Checked; 
  RBn_zf16x32.Enabled := RBn_ZF.Checked; 
  Meo_ShowData.Clear; 
  Edt_ZMSource.Text := ''; 
  preGetText := ''; 
  ClearGrid(); 
  if RBn_HZ.Checked then 
  begin 
    if RBn_hz32x32.Checked then 
      DrawGrid(32,32,DrawStep) 
    else if RBn_hz24x24.Checked then 
      DrawGrid(24,24,DrawStep) 
    else 
      DrawGrid(16,16,DrawStep); 
  end 
  else 
  begin 
    if RBn_zf16x32.Checked then 
      DrawGrid(16,32,DrawStep) 
    else if RBn_zf12x24.Checked then 
      DrawGrid(12,24,DrawStep) 
    else 
      DrawGrid(8,16,DrawStep); 
  end; 
end; 
 
procedure TFrm_Main.Btn_GetZMClick(Sender: TObject); 
var 
  inputstr:String; 
  size:Integer; 
  width:Integer; 
  height:Integer; 
begin 
  if(Edt_ZMSource.Text <> '') then 
  begin 
    if (Edt_ZMSource.Text <> preGetText) or 
       (Get_Direct <> CmB_GetDirect.ItemIndex) then 
    begin 
//clear workspace 
    for size := 0 to 128 do 
      DataGroup[size] := 0; 
    width := preDrawWidth; 
    height := preDrawHeight; 
    preDrawWidth := 0; 
    DrawGrid(width,height,DrawStep);       
    preGetText := Edt_ZMSource.Text; 
    Get_Direct := CmB_GetDirect.ItemIndex; 
    inputstr := Edt_ZMSource.Text; 
    if RBn_HZ.Checked and (Length(Edt_ZMSource.Text) > 2)then 
      inputstr := Copy(Edt_ZMSource.Text,1,2); 
    if RBn_ZF.Checked and (Length(Edt_ZMSource.Text) > 1)then 
      inputstr := Copy(Edt_ZMSource.Text,1,1); 
    if RBn_HZ.Checked then 
    begin 
      if RBn_hz32x32.Checked then 
      begin 
        size := HZ_32x32; 
        width := 32; 
        height := 32; 
        SpnEdt_Width.Value := 32; 
        SpnEdt_Height.Value := 32; 
      end 
      else if RBn_hz24x24.Checked then 
      begin 
        size := HZ_24x24; 
        width := 24; 
        height := 24; 
        SpnEdt_Width.Value := 24; 
        SpnEdt_Height.Value := 24; 
      end 
      else 
      begin 
        size := HZ_16x16; 
        width := 16; 
        height := 16; 
        SpnEdt_Width.Value := 16; 
        SpnEdt_Height.Value := 16; 
      end; 
    end 
    else 
    begin 
      if RBn_zf16x32.Checked then 
      begin 
        size := ZF_16x32; 
        width := 16; 
        height := 32; 
        SpnEdt_Width.Value := 16; 
        SpnEdt_Height.Value := 32; 
      end 
      else if RBn_zf12x24.Checked then 
      begin 
        size := ZF_12x24; 
        width := 12; 
        height := 24; 
        SpnEdt_Width.Value := 12; 
        SpnEdt_Height.Value := 24; 
      end 
      else 
      begin 
        size := ZF_8x16; 
        width := 8; 
        height := 16; 
        SpnEdt_Width.Value := 8; 
        SpnEdt_Height.Value := 16; 
      end; 
    end; 
    GetChineseLattice(inputstr,DataGroup,size); 
    Modified := True; 
    Btn_DoOperationClick(nil); 
    GetDataInFile(Meo_ShowData); 
    DrawZMWithData(width,height,DataGroup,DrawStep); 
  end; 
  end; 
end; 
 
procedure TFrm_Main.Btn_ClearGetZMClick(Sender: TObject); 
var 
  width:Integer; 
  height:Integer; 
begin 
  Meo_ShowData.Clear; 
  Edt_ZMSource.Text := ''; 
  preGetText := ''; 
  Modified := True; 
  ClearGrid(); 
  DataPointer := 0; 
  width := preDrawWidth; 
  height := preDrawHeight; 
  preDrawWidth := 0; 
  preDrawHeight := 0; 
  preDrawStep := 0; 
  DrawGrid(width,height,DrawStep); 
end; 
 
procedure TFrm_Main.RBn_hz16x16Click(Sender: TObject); 
begin 
  if not SecondPageInit then 
  begin 
    ClearGrid(); 
    DrawGrid(16,16,DrawStep); 
    Btn_ClearGetZMClick(nil); 
  end; 
end; 
 
procedure TFrm_Main.RBn_hz24x24Click(Sender: TObject); 
begin 
  if not SecondPageInit then 
  begin 
    ClearGrid(); 
    DrawGrid(24,24,DrawStep); 
    Btn_ClearGetZMClick(nil); 
  end; 
end; 
 
procedure TFrm_Main.RBn_hz32x32Click(Sender: TObject); 
begin 
  if not SecondPageInit then 
  begin 
    ClearGrid(); 
    DrawGrid(32,32,DrawStep); 
    Btn_ClearGetZMClick(nil); 
  end; 
end; 
 
procedure TFrm_Main.RBn_zf8x16Click(Sender: TObject); 
begin 
  if not SecondPageInit then 
  begin 
    ClearGrid(); 
    DrawGrid(8,16,DrawStep); 
    Btn_ClearGetZMClick(nil); 
  end; 
end; 
 
procedure TFrm_Main.RBn_zf12x24Click(Sender: TObject); 
begin 
  if not SecondPageInit then 
  begin 
    ClearGrid(); 
    DrawGrid(12,24,DrawStep); 
    Btn_ClearGetZMClick(nil); 
  end; 
end; 
 
procedure TFrm_Main.RBn_zf16x32Click(Sender: TObject); 
begin 
  if not SecondPageInit then 
  begin 
    ClearGrid(); 
    DrawGrid(16,32,DrawStep); 
    Btn_ClearGetZMClick(nil); 
  end; 
end; 
 
procedure TFrm_Main.SpnEdt_WidthExit(Sender: TObject); 
begin 
  if((SpnEdt_Width.Value mod 8) <> 0) then 
    SpnEdt_Width.Value := 8; 
end; 
 
procedure TFrm_Main.SpnEdt_HeightExit(Sender: TObject); 
begin 
  if((SpnEdt_Height.Value mod 8) <> 0) then 
    SpnEdt_Height.Value := 8; 
end; 
 
procedure TFrm_Main.CmB_GetDirectChange(Sender: TObject); 
begin 
  if(Cur_GetDirect <> CmB_GetDirect.ItemIndex) then 
  begin 
    Meo_ShowData.Clear; 
    Cur_GetDirect := CmB_GetDirect.ItemIndex; 
  end; 
end; 
 
procedure TFrm_Main.CmB_ReadDirectChange(Sender: TObject); 
begin 
  if(Cur_ReadDirect <> CmB_ReadDirect.ItemIndex) then 
  begin 
    Meo_ShowData.Clear; 
    Cur_ReadDirect := CmB_ReadDirect.ItemIndex; 
  end; 
end; 
 
end.