{ Ukazka zdrojoveho textu knihovny pro program Genlib }
{ PH 2002, 2003 }

{------------------------------------------------------------------------------}

{ vseobecne vyuzitelne funkce }

function Min (a, b: integer) : integer;
begin
  if a < b then Result := a else Result := b;
end;

function Max (a, b: integer) : integer;
begin
  if a > b then Result := a else Result := b;
end;

function Avg (a, b: integer) : integer;
begin
  Result := (a + b) div 2;
end;

function GetPoint (x, y: integer) : Point;
begin
  Result.x := x;
  Result.y := y;
end;

function GetRect (x1, y1, x2, y2: integer) : Rect;
begin
  Result.Left   := x1;
  Result.Bottom := y1;
  Result.Right  := x2;
  Result.Top    := y2;
end;

function GetRect0 (w, h: integer) : Rect;
begin
  Result.Left   := -w;
  Result.Bottom := -h;
  Result.Right  :=  w;
  Result.Top    :=  h;
end;

function RectCenter (r: Rect) : Point;
begin
  Result.x := Avg (r.Left, r.Right);
  Result.y := Avg (r.Top,  r.Bottom);
end;

function StretchRect (r: Rect; dx, dy: integer) : Rect;
begin
  Result.Left   := r.Left   - dx;
  Result.Bottom := r.Bottom - dy;
  Result.Right  := r.Right  + dx;
  Result.Top    := r.Top    + dy;
end;

{------------------------------------------------------------------------------}

procedure DrawRect (r: Rect; LineType, Layer: integer);
begin
  Line (r.Left,  r.Top,
        r.Right, r.Top, LineType, Layer);
  Line (r.Right, r.Bottom);
  Line (r.Left,  r.Bottom);
  Line (r.Left,  r.Top);
end;

procedure DrawSquare (Center: Point; Size: integer; LineType, Layer: integer);
begin
  Line (Center.x - Size div 2, Center.y - Size div 2,
        Center.x + Size div 2, Center.y - Size div 2, LineType, Layer);
  Line (Center.x + Size div 2, Center.y + Size div 2);
  Line (Center.x - Size div 2, Center.y + Size div 2);
  Line (Center.x - Size div 2, Center.y - Size div 2);
end;

procedure DrawCircle (Center: Point; Size: integer; LineType, Layer: integer);
begin
  Arc (0, Center.x, Center.y, Size div 2, LineType, Layer);
  Arc (1, Center.x, Center.y, Size div 2, LineType, Layer);
  Arc (2, Center.x, Center.y, Size div 2, LineType, Layer);
  Arc (3, Center.x, Center.y, Size div 2, LineType, Layer);
end;

procedure MitreRect (r: Rect; Corner: integer; LineType, Layer: integer);
begin
  Line (r.Left, r.Top, r.Right, r.Top, LineType, Layer);
  Line (r.Right, r.Bottom);
  Line (r.Left + Corner, r.Bottom);
  Line (r.Left, r.Bottom + Corner);
  Line (r.Left, r.Top);
end;

procedure InnerOutLine (r: Rect; NotchW, NotchH: integer; LineType, Layer: integer);
var
  NotchTop, NotchBottom: integer;
begin
  NotchTop    := (r.Bottom + r.Top - NotchH) div 2;
  NotchBottom := (r.Bottom + r.Top + NotchH) div 2;
  Line (r.Left,          r.Bottom, r.Right, r.Bottom, LineType, Layer);
  Line (r.Right,         r.Top);
  Line (r.Left,          r.Top);
  Line (r.Left,          NotchTop);
  Line (r.Left + NotchW, NotchTop);
  Line (r.Left + NotchW, NotchBottom);
  Line (r.Left,          NotchBottom);
  Line (r.Left,          r.Bottom);
end;

procedure InnerOutLineSO (r: Rect; Width: integer; LineType, Layer: integer);
begin
  Line (r.Left,          r.Bottom, r.Left  + Width, r.Bottom, LineType, Layer);
  Line (r.Left,          r.Bottom);
  Line (r.Left,          r.Top);
  Line (r.Left  + Width, r.Top);
  Line (r.Right,         r.Bottom, r.Right - Width, r.Bottom, LineType, Layer);
  Line (r.Right,         r.Bottom);
  Line (r.Right,         r.Top);
  Line (r.Right - Width, r.Top);
end;

{------------------------------------------------------------------------------}

var OutLineLayer, InnerLayer, LegendLayer: integer;
    FrameLine, LegendLine: integer;

procedure CentralName (Center: Point; LineType, Layer: integer);
begin
  ComponentName    (Center.x, Center.y, 10, 0, LineType, Layer);
{ ComponentValue   (Center.x, Center.y,  0, 0, LineType, Layer);  {nebo posunout kousek dolu?}
{ ComponentPackage (Center.x, Center.y,  0, 0, LineType, Layer);  {dtto}
end;

procedure CentralName0 (LineType, Layer: integer);
begin
  ComponentName    (0, 0, 10, 0, LineType, Layer);
{ ComponentValue   (0, 0,  0, 0, LineType, Layer);  {nebo posunout kousek dolu?}
{ ComponentPackage (0, 0,  0, 0, LineType, Layer);  {dtto}
end;

procedure DrawDILPins (n: integer; PadType: integer; SpacingX, SpacingY: integer);
var
  i, x1: integer;
begin
  x1 := -(n div 2 - 1) * SpacingX div 2;
  for i := 1 to n div 2 do
    Pin (i, x1 + (i - 1) * SpacingX, -SpacingY div 2, PadType);
  for i := n div 2 + 1 to n do
    Pin (i, x1 + (n - i) * SpacingX,  SpacingY div 2, PadType);
end;

{ vytvareni pouzder DIP a SO_ }

procedure DIP (n: integer; SpacingY: integer; Suffix: string);
var
  Name: string;
  MarginX, MarginY, SpacingX, x1: integer;
  Frame: Rect;
begin
  Name := 'DIP' + n + Suffix;
  SpacingX := 100;
  MarginX  := 100;
  MarginY  :=  50;
  Component (Name, 'VALUE', Name) begin
    x1 := -(n div 2 - 1) * SpacingX div 2;  {vypocet se opakuje; v DrawDILPins byl stejny}
    Frame := GetRect0 (-x1 + MarginX, SpacingY div 2 + MarginY);
    CentralName0 (LegendLine, LegendLayer);
    MitreRect (Frame, 50, FrameLine, OutlineLayer);
    DrawDILPins (n, 4 {pad prumeru 1.5 mm}, SpacingX, SpacingY);
    InnerOutline (StretchRect (Frame, 0, - MarginY - MarginY), 60, 60, FrameLine, InnerLayer);
    DrawSquare (GetPoint (x1, -SpacingY div 2 + 85), 30, FrameLine, InnerLayer);
  end;
end;

procedure SO (Prefix: string; n: integer; MarginX, MarginY, SpacingY: integer);
var
  Name: string;
  SpacingX, x1: integer;
  Frame: Rect;
begin
  Name := Prefix + n;
  SpacingX := 50;
  Component (Name, 'VALUE', Name) begin
    x1 := -(n div 2 - 1) * SpacingX div 2;  {vypocet se opakuje; v DrawDILPins byl stejny}
    Frame := GetRect0 (-x1 + MarginX, SpacingY div 2 + MarginY);
    CentralName (RectCenter (Frame), LegendLine, LegendLayer);
    MitreRect (Frame, MarginX - 5, FrameLine, OutlineLayer);
    DrawDILPins (n, 45 {ovalny pad 2.235 mm} + 64 {rotace}, SpacingX, SpacingY);
    InnerOutlineSO (StretchRect (Frame, 0, - MarginY), MarginX - 20, FrameLine, InnerLayer);
    DrawSquare (GetPoint (x1, -SpacingY div 2 + 70), 20, FrameLine, InnerLayer);
  end;
end;

{------------------------------------------------------------------------------}

{ vytvareni diodovych pouzder }

function TwoPinCompBox (Length, Height, MarginX, Corner: integer; PadType: integer) : Rect;
begin
  Result := GetRect0 (Length div 2 + MarginX, Height div 2);
  CentralName0 (LegendLine, LegendLayer);
  Pin (1, -Length div 2, 0, PadType);
  Pin (2,  Length div 2, 0, PadType);
  MitreRect (Result, Corner, FrameLine, OutlineLayer);
end;

procedure TwoPinCompBody (Frame: Rect; WireLength: integer);
begin
  DrawRect (Frame, FrameLine, InnerLayer);
  Line (Frame.Left  - WireLength, (Frame.Bottom + Frame.Top) div 2,
        Frame.Left,               (Frame.Bottom + Frame.Top) div 2,
        FrameLine, InnerLayer);
  Line (Frame.Right + WireLength, (Frame.Bottom + Frame.Top) div 2,
        Frame.Right,              (Frame.Bottom + Frame.Top) div 2,
        FrameLine, InnerLayer);
end;

procedure Diode (Name: string; Length, Height, MarginX, Corner: integer; PadType: integer);
var
  OuterFrame, InnerFrame: Rect;
  HalfHeight: integer;
begin
  Component (Name, 'VALUE', Name) begin  {vytvori prvni podobu diody}
    OuterFrame := TwoPinCompBox (Length, Height, MarginX, Corner, PadType);
    InnerFrame := GetRect0 (0.3 * Length, 0.38 * Height);
    TwoPinCompBody (InnerFrame, 0.2 * Length - MarginX);
    Line (InnerFrame.Left + 15, InnerFrame.Top,
          InnerFrame.Left + 15, InnerFrame.Bottom,
          FrameLine, InnerLayer);  {prouzek}
  end;
  Component (Name + 'S', 'VALUE', Name + 'S') begin  {vytvori druhou podobu diody, se sch. znackou}
    OuterFrame := TwoPinCompBox (Length, Height, MarginX, Corner, PadType);
    HalfHeight := (1/2 - 0.12) * Height;
    InnerFrame := GetRect0 (0.8660254 {= SqRt (3) / 2} * HalfHeight, HalfHeight);
    Line (-Length div 2 + MarginX, 0,
          InnerFrame.Left,         0,
          FrameLine, InnerLayer);  {dratek}
    Line (+Length div 2 - MarginX, 0,
          InnerFrame.Right,        0,
          FrameLine, InnerLayer);  {dratek}
    Line (InnerFrame.Left, InnerFrame.Top,
          InnerFrame.Left, InnerFrame.Bottom,
          FrameLine, InnerLayer);  {katoda}
    Line (InnerFrame.Right, InnerFrame.Top,
          InnerFrame.Right, InnerFrame.Bottom,
          FrameLine, InnerLayer);  {anoda}
    Line (InnerFrame.Left,  0);
    Line (InnerFrame.Right, InnerFrame.Top);
  end;
end;

{------------------------------------------------------------------------------}

begin
  OutlineLayer := 15;
  InnerLayer   := 14;
  LegendLayer  := 13;
  FrameLine  := 1;
  LegendLine := 1;
  DIP ( 2, 3 * 100, '');
  DIP ( 4, 3 * 100, '');
  DIP ( 6, 3 * 100, '');
  DIP ( 8, 3 * 100, '');
  DIP (10, 3 * 100, '');
  DIP (12, 3 * 100, '');
  DIP (14, 3 * 100, '');
  DIP (16, 3 * 100, '');
  DIP (18, 3 * 100, '');
  DIP (20, 3 * 100, '');
  DIP (22, 3 * 100, '');
  DIP (24, 3 * 100, 'N');
  DIP (24, 6 * 100, '');
  DIP (28, 3 * 100, 'N');
  DIP (28, 6 * 100, '');
  DIP (32, 6 * 100, '');
  DIP (40, 6 * 100, '');
  DIP (48, 6 * 100, '');
  DIP (64, 6 * 100, 'N');
  DIP (64, 9 * 100, '');
  Writeln ('Vytvorena pouzdra DIP');
  SO ('SOP',  6, 25, 50, 220);
  SO ('SOP',  8, 25, 50, 220);
  SO ('SOP', 14, 25, 50, 220);
  SO ('SOP', 16, 25, 50, 220);
  SO ('SOL', 14, 35, 50, 380);
  SO ('SOL', 16, 35, 50, 380);
  SO ('SOL', 20, 35, 50, 380);
  SO ('SOL', 24, 35, 50, 380);
  SO ('SOL', 28, 35, 50, 380);
  SO ('SOJ', 14, 35, 45, 270);
  SO ('SOJ', 16, 35, 45, 270);
  SO ('SOJ', 18, 35, 45, 270);
  SO ('SOJ', 20, 35, 45, 270);
  SO ('SOJ', 22, 35, 45, 270);
  SO ('SOJ', 24, 35, 45, 270);
  SO ('SOJ', 26, 35, 45, 270);
  SO ('SOJ', 28, 35, 45, 270);
  Writeln ('Vytvorena pouzdra SOP, SOL, SOJ');
  Diode ('D75',  300, 100, 50, 25, 4);
  Diode ('D035', 400, 100, 50, 25, 4);
  Diode ('D125', 500, 100, 50, 25, 4);
  Diode ('D041', 400, 150, 50, 30, 6);
  Diode ('P1',   500, 150, 50, 30, 6);
  Diode ('D015', 500, 200, 50, 30, 7);
  Diode ('D027', 600, 250, 50, 40, 8);
  Diode ('P2',   600, 250, 50, 40, 8);
  Diode ('P6',   800, 400, 75, 50, 9);
  Writeln ('Vytvorena diodova pouzdra');  
end.

