상세 컨텐츠

본문 제목

LED Display

etc

by ryujt 2012. 1. 18. 21:49

본문

http://codingdojang.com/scode/314 에 제시된 문제를 풀어 본 것 입니다.

[소스 1]
program Sample;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  TextCanvas in 'TextCanvas.pas',
  DigitFont in 'DigitFont.pas';

var
  DigitFont : TDigitFont;

begin
  DigitFont := TDigitFont.Create;
  try
    DigitFont.FontSize := 1;
    DigitFont.WriteDigit('01234');
    WriteLn;

    DigitFont.FontSize := 2;
    DigitFont.WriteDigit('56789');
  finally
    DigitFont.Free;
  end;

  Write('Press any key...');
  ReadLn;
end.
문제대로 파일을 읽고 등등은 생략 ^^;
문제의 핵심을 폰트 크기와 숫자를 LED 디스플레이로 표시하는 것으로 압축하고, 거기에 해당하는 인터페이스를 가진 클래스 제작하였습니다.  그리고, 실행 결과는 [그림 1]과 같습니다.

[그림 1] 실행 결과 

[소스 2] TDigitFont 클래스의 중요 부분
procedure TDigitFont.WriteDigit(Digit:string);
const
  _FontWidth  = 3;
  _FontHeight = 5;
var
  sFontData : string;
  Loop: Integer;
begin
  FCanvas.Width  := Length(Digit) * (FontSize + 1) * _FontWidth;
  FCanvas.Height := FontSize * _FontHeight;
  FCanvas.Clear;

  for Loop := 0 to Length(Digit)-1 do begin
    // 현재 폰트를 찍을 위치로
    FCanvas.MoveTo(Loop * (FontSize + 1) * _FontWidth, 0);

    // 현재 폰트의 벡터 정보 가져오기
    sFontData := _DigitFontData[Ord(Digit[Loop+1]) - Ord('0')];
    draw_Digit(sFontData);
  end;

  FCanvas.Draw;
end;

procedure TDigitFont.draw_Digit(FontData: string);
var
  Loop : Integer;
begin
  for Loop := 1 to Length(FontData) do begin
    case FontData[Loop] of
      'l': FCanvas.MoveLeft;
      'r': FCanvas.MoveRight;
      'd': FCanvas.MoveDown;
      'u': FCanvas.MoveUp;

      '<': FCanvas.MoveLeft(FontSize);
      '>': FCanvas.MoveRight(FontSize);
      '.': FCanvas.MoveDown(FontSize);
      '^': FCanvas.MoveUp(FontSize);

      'L': FCanvas.LineLeft(FontSize);
      'R': FCanvas.LineRight(FontSize);
      'D': FCanvas.LineDown(FontSize);
      'U': FCanvas.LineUp(FontSize);
    end;
  end;
end;

[소스 3] 벡터 정보
type
const
  _DigitFontData : array [0..9] of string = (
    'dDdDrRuUuUlL',      // 0
    'rrdDdD',            // 1
    'rRdDlLdDrR',        // 2
    'rRdDdDlL^urR',      // 3
    'dDrR^DdD',          // 4
    'rR<ldDrRdDlL',      // 5
    'rLdDrRdDlLuU',      // 6
    'rRdDdD',            // 7
    'rRdDlLdDrRuUl<uU',  // 8
    'd.rLuUrRdDdDlL'     // 9
  );

lrdu : 한 칸 이동 (각각 Left, Right, Down, Up)

<>,^ : 폰트 크기 만큼 이동 (각각 Left, Right, Down, Up)

LRDU : 폰트 크기 만큼 직선 그리기 (각각 Left, Right, Down, Up)


[소스 4]  위에서 사용되는 TTextCanvas 클래스의 인터페이스 (FCanvas) 
type
  TTextCanvas = class
  private
  public
    procedure Clear;

    procedure MoveTo(X,Y:integer);

    procedure MoveLeft(Count:integer = 1);
    procedure MoveRight(Count:integer = 1);
    procedure MoveDown(Count:integer = 1);
    procedure MoveUp(Count:integer = 1);

    procedure LineLeft(Count:integer = 1);
    procedure LineRight(Count:integer = 1);
    procedure LineDown(Count:integer = 1);
    procedure LineUp(Count:integer = 1);

    procedure Draw;

    property X : integer;
    property Y : integer;
    property Width : integer;
    property Height : integer;
  end;

그리고 아래는 전체 소스

디지털 숫자 출력.zip


관련글 더보기