Protel库文件导入设计

本文详细介绍了Protel库文件的ascii格式,包括库头、字体表和元件节的内容结构,并阐述了如何处理这些部分,特别是元件的各个子图元如Pin、Ellipse等。在导入过程中,对不同部分进行了相应的解析和操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
Protel库文件后缀名为.lib,可存为binary与ascii两种格式,本文针对ascii格式的Protel库文件进行导入处理。对于binary格式的Protel库文件,需进行相应处理,请参阅《图形博士(通用平台系统)-使用手册.pdf》中的相关说明。
1.2      Ascii格式的Protel库文件
用任意文本编辑器打开ascii格式的Protel库文件。
Protel for Windows - Schematic Library Editor Ascii File Version 1.2 - 2.0
5348
 Organization
 Miscellaneous Devices
 
 
 
 
 
 
 
 0 0
 End
[Font_Table]
     3
     10 0 0 0 0 0 Times New Roman
     8 0 0 0 0 0 Arial
     8 0 0 0 0 0 Times New Roman
EndFont
Library 0 9 0 1 0 0 15269887 1 10 1 10 1000 800 0 0
   269
   Component
      1
      1
     
      RCA Connector
     
     
     
     
     
     
     
     
     
     
     
     
      P?
     
      RCA
      Part
         0 0
         Pin 0 0 4 0 0 0 20 20 -10 0 0 'X' '1'
         Pin 0 0 4 0 0 0 20 10 -20 3 0 'Y' '2'
         Ellipse 10 -10 2 2 1 16711680 16711680 1 0
         EllipticalArc 10 -10 10 10 1 0.000 0.000 16711680 0
      EndNormalPart
      EndDeMorganPart
      EndIEEEPart
   EndComponent
可以猜测,凡是以End开头的单词,将表示某一个部分的结束。
大致推导其中内容含义如下:
1.         库头部分:
Protel for Windows - Schematic Library Editor Ascii File Version 1.2 - 2.0
5348
 Organization
 Miscellaneous Devices
 
 
 
 
 
 
 
 0 0
 End
本部分在导入时可以忽略不处理。
2.         字体表
[Font_Table]
     3
     10 0 0 0 0 0 Times New Roman
     8 0 0 0 0 0 Arial
     8 0 0 0 0 0 Times New Roman
EndFont
其中[Font_Table]为开始,EndFont为结束。
第二行的数字表示共有多少种字体
第三行以后到EndFont之前,一行表示一种字体。每行有6个整数,最后为字体名称。第一个数表示字体大小,后续5个应为诸如字形、风格、颜色等,如果不处理后5个整数,大致能满足要求。
3.       元件节
本节第一二行内容
Library 0 9 0 1 0 0 15269887 1 10 1 10 1000 800 0 0
   269
其中第一行表示库实质内容开始,第二行表示本库中共有的元件数目。
本节后续内容将以元件为单位重复,各元件内容结构如下
   Component
      1
      1
     
      RCA Connector
     
     
     
     
     
     
     
     
     
     
     
     
      P?
     
      RCA
      Part
         0 0
         Pin 0 0 4 0 0 0 20 20 -10 0 0 'X' '1'
         Pin 0 0 4 0 0 0 20 10 -20 3 0 'Y' '2'
         Ellipse 10 -10 2 2 1 16711680 16711680 1 0
         EllipticalArc 10 -10 10 10 1 0.000 0.000 16711680 0
      EndNormalPart
      EndDeMorganPart
      EndIEEEPart
   EndComponent
其第1行表示元件开始
第2、3行表示组及其序号
第5行表示元件描述
第18行表示元件的缺省名称
第20行表示元件的类型名称
第21行表示开始说明该元件各子图元
第22行,0 0不明白其中含义,不过也无关紧要。
后续各行直至End…Part之间,一行说明一个子图元。这是元件图形模型的核心所在。
void __fastcall TLibEditForm::LoadProtelLibFile(AnsiString fileName)
{
   if(!FileExists(fileName)) return;
   TStrings * list = new TStringList;
   list->LoadFromFile(fileName);
   int count = list->Count;
   for(int i = 0; i < count; ++i)
   {
      AnsiString str = list->Strings[i].Trim();
      if(SameText(str, "Component"))
         ReadComponent(list, i);
      else if(SameText(str, "[Font_Table]"))
         ReadFont(list, i);
   }
   delete list;
}
 
不需要处理
读入处理到[Font_Table]时,进入字体处理
void __fastcall ReadFont(TStrings * list, int& index)
{
   CBW_ITERATOR(vector<TFont *>, ProtelFontList)
   {
      TFont * font = *it;
      if(font)
      {
         ::DeleteObject(font->Handle);
         delete font;
      }
   }
   ProtelFontList.clear();
  
   ++index;
   AnsiString str = list->Strings[index++];
   int fontNumber = str.ToInt();
 
   FlushVector(ProtelFontList, true);
   for(int i = 0; i < fontNumber; ++i)
   {
      str = list->Strings[index++];
     TStrings * fontContents = String2List(str, " ");
      if(fontContents->Count > 6)
      {
         AnsiString fontName = fontContents->Strings[6];
         for(int j = 7; j < fontContents->Count; ++j)
            fontName += " " + fontContents->Strings[j];
         TFont * font = new TFont;
         font->Name = fontName;
         font->Size = fontContents->Strings[0].ToInt();
         ProtelFontList.push_back(font);
      }
      delete fontContents;
   }
   ++index;
}
读入遇到Component时,进行元件处理
void __fastcall TLibEditForm::ReadComponent(TStrings * list, int& index)
{
   NewUnit();
   TText * unitName = cCurrentUnit->UnitName;
   unitName->Top = 385;
   unitName->Left = 400;
   int count = list->Count;
   bool partFlag = false;
   for(int i = index; i < count; ++i)
   {
      AnsiString str = list->Strings[i].Trim();
      CBW_CONDITION_CONTINUE(str.Length() == 0);
      if(SameText(str, "Part")) partFlag = true;
      int offset = i - index;     
      if(offset > 19 && SameText(str, "EndComponent"))
      {
         index = i;
         break;
      }
      if(offset == 4)
         cCurrentUnit->Description = str;
      else if(offset == 17)
         cCurrentUnit->UnitName->Caption = str;
      else if(offset == 19)
      {
         cCurrentUnit->TypeName = str;   
         TreeView1->Items->Item[TreeView1->Items->Count - 1]->Text = str;
      }
      else if(partFlag)
         AddProtelLibObject(str);
   }
   if(cCurrentUnit->MetaNumber == 1)
      DeleteUnit();
}
具体处理各子图元
void __fastcall TLibEditForm::AddProtelLibObject(AnsiString itemContent)
{
   cCurrentMeta = NULL;
   TStrings * contentList = String2List(itemContent, " ");
   if(contentList->Count < 3)
   {
      delete contentList;
      return;
   }
   int index = 0;
   AnsiString metaName = contentList->Strings[0];
if(cCurrentMeta && cCurrentMeta->AllDoneFlag)
   {
      LibPropertyForm->NewObject(cCurrentMeta);     // 加入对象浏览器,显示属性
      cObjectList->Add(cCurrentMeta);
      CurrentUnit->AddObject(cCurrentMeta);
      TPin * pin = dynamic_cast<TPin *>(cCurrentMeta);
      if(pin)
      {
         vector<TPin *> pins;
         for(int i = 0; i < cCurrentUnit->MetaNumber; ++i)
         {
            TPin * p = dynamic_cast<TPin *>(cCurrentUnit->Meta(i));
            if(p && p != pin)
               pins.push_back(p);
         }
         bool checkFlag = true;
         while(checkFlag)
         {
            checkFlag = false;
            CBW_ITERATOR(vector<TPin *>, pins)
            {
               bool sameNameFlag = SameText( (*it)->PinName, pin->PinName );
               bool sameNumberFlag = SameText( (*it)->PinNumber, pin->PinNumber);
               if(sameNameFlag || sameNumberFlag)
                  checkFlag = true;
               if(sameNameFlag)
                  pin->PinName = pin->PinName + "1";
               if(sameNumberFlag)                            
                  pin->PinNumber = pin->PinNumber + "1";
            }
         }
      }
   }
   delete contentList;
}
TPin * pin = dynamic_cast<TPin *>(NewMeta(cctPin));
      if(contentList->Count == 14)
      {                     
         bool dotFlag = contentList->Strings[++index].ToInt();
         bool clkFlag = contentList->Strings[++index].ToInt();
         int electricalType = contentList->Strings[++index].ToInt();
         bool hiddenFlag = contentList->Strings[++index].ToInt();
         bool showNameFlag = contentList->Strings[++index].ToInt();
         bool showNumberFlag = contentList->Strings[++index].ToInt();
         int pinLength = contentList->Strings[++index].ToInt();
         int xPos = ProtelGetPos(contentList->Strings[++index], 'x');
         int yPos = ProtelGetPos(contentList->Strings[++index], 'y');
         int degree = contentList->Strings[++index].ToInt();
         int color = contentList->Strings[++index].ToInt();
         AnsiString pinName = contentList->Strings[++index];
         AnsiString pinNumber = contentList->Strings[++index];
 
         if(electricalType == 1) electricalType = 2;
         else if(electricalType == 2) electricalType = 1;
         ReplaceStringInStr(pinName, "'", "");
         ReplaceStringInStr(pinNumber, "'", "");
 
         ProtelAddPoint(cCurrentMeta, xPos, yPos);
         pin->PinLength = pinLength;
         pin->PinName = pinName;
         pin->PinNumber = pinNumber;
         pin->PinDirection = electricalType;
         pin->ShowPinName = showNameFlag;
         pin->ShowPinNumber = showNumberFlag;
         pin->Color = color;
        
         TText * cPinName = dynamic_cast<TText *>(pin->Meta(0));
         TText * cPinNumber = dynamic_cast<TText *>(pin->Meta(1));
         if(ProtelFontList.size())
         {
            cPinName->Font = ProtelFontList[ProtelFontList.size() - 1];
            cPinNumber->Font = ProtelFontList[ProtelFontList.size() - 1];
         }
        
         double dx = pin->PinLine->Points[1].x - (cPinNumber->Left + cPinNumber->Width);
         double dy = pin->PinLine->Points[1].y - (cPinNumber->Top + cPinNumber->Height);
         if(degree % 4 == 2)
            dy = pin->PinLine->Points[1].y - cPinNumber->Top - 2;
         cPinNumber->DragBy(dx, dy, true);
        
         dx = pin->PinLine->Points[0].x - (cPinName->Left + cPinName->Width) - 3;
         dy = pin->PinLine->Points[0].y - cPinName->CentralPoint.y;
         cPinName->DragBy(dx, dy, true);
 
         if(degree)
         {                                                 
            pin->Rotate(degree * 90);
            int theta = 0;
            if(degree % 2) theta = 90;
            cPinName->Theta = theta;
            cPinNumber->Theta = theta;      
            pin->DragBy(xPos - pin->PinLine->Points[0].x, yPos - pin->PinLine->Points[0].y, true);
         }
         dx = 0; dy = 0;
         int delta = 3;
         if(degree == 0)
            dx = pin->PinLine->Points[0].x - delta - (cPinName->Left + cPinName->Width);
         else if(degree == 2)
            dx = pin->PinLine->Points[0].x + delta - cPinName->Left;
         else if(degree == 1)
            dy = pin->PinLine->Points[0].y + delta - cPinName->Top;
         else if(degree == 3)
            dy = pin->PinLine->Points[0].y - delta - (cPinName->Top + cPinName->Height);
         cPinName->DragBy(dx, dy, true);
         pin->Visible = !hiddenFlag;
         pin->ProtelPinFlag = true;
      }
TEllipse * ellipse = dynamic_cast<TEllipse *>(NewMeta(cctEllipse));
      if(contentList->Count == 10)  
      {
         int xPos = ProtelGetPos(contentList->Strings[++index], 'x');
         int yPos = ProtelGetPos(contentList->Strings[++index], 'y');
         int xRadius = contentList->Strings[++index].ToInt();
         int yRadius = contentList->Strings[++index].ToInt();
         int borderWidth = ProtelGetBorderWidth(contentList->Strings[++index]);
         int borderColor = contentList->Strings[++index].ToInt();
         int fillColor = contentList->Strings[++index].ToInt();
         bool drawSolidFlag = contentList->Strings[++index].ToInt();
         bool selectionFlag = contentList->Strings[++index].ToInt();    
 
         ProtelAddPoint(cCurrentMeta, xPos, yPos, 2);
         ellipse->HorzAxis = xRadius;
         ellipse->VertAxis = yRadius;
         ellipse->LineWidth = borderWidth;
         ellipse->LineColor = borderColor;
         ellipse->FillColor = fillColor;                  
         ellipse->Transparent = !drawSolidFlag;
         cCurrentMeta->DragBy(xPos - cCurrentMeta->CentralPoint.x, yPos - cCurrentMeta->CentralPoint.y, true);
      }
TArc * arc = dynamic_cast<TArc *>(NewMeta(cctArc));
      if(contentList->Count == 10)
      {
         int xPos = ProtelGetPos(contentList->Strings[++index], 'x');
         int yPos = ProtelGetPos(contentList->Strings[++index], 'y');
         int xRadius = contentList->Strings[++index].ToInt();
         int yRadius = contentList->Strings[++index].ToInt();
         int borderWidth = ProtelGetBorderWidth(contentList->Strings[++index]);
         double beginTheta = contentList->Strings[++index].ToDouble();
         double endTheta = contentList->Strings[++index].ToDouble();
         int borderColor = contentList->Strings[++index].ToInt();
         bool selectionFlag = contentList->Strings[++index].ToInt();
 
         ProtelAddPoint(cCurrentMeta, xPos, yPos, 4);
         arc->HorzAxis = xRadius;
         arc->VertAxis = yRadius;
         arc->LineWidth = borderWidth;
         arc->LineColor = borderColor;
         arc->BeginTheta = beginTheta;
         arc->EndTheta = endTheta;
         cCurrentMeta->DragBy(xPos - cCurrentMeta->CentralPoint.x, yPos - cCurrentMeta->CentralPoint.y, true);
      }
TText * text = dynamic_cast<TText *>(NewMeta(cctText));
      if(contentList->Count == 8)
      {
         int xPos = ProtelGetPos(contentList->Strings[++index], 'x');
         int yPos = ProtelGetPos(contentList->Strings[++index], 'y');
         int orientation = contentList->Strings[++index].ToInt();
         int color = contentList->Strings[++index].ToInt();
         int fontIndex = ProtelGetBorderWidth(contentList->Strings[++index]);
         bool selectionFlag = contentList->Strings[++index].ToInt();
         AnsiString caption = contentList->Strings[++index];
 
         ReplaceStringInStr(caption, "'", "");
        
         ProtelAddPoint(cCurrentMeta, xPos, yPos);
         if(orientation)
            text->Theta = orientation * 90;
         if(ProtelFontList.size() >= fontIndex)
            text->Font = ProtelFontList[fontIndex - 1];
         text->SetPenFont("TFont", "Color", color);
         text->Caption = caption;
         cCurrentMeta->DragBy(
            xPos - cCurrentMeta->Left,
            yPos - (cCurrentMeta->Top + cCurrentMeta->Height - 5),
            true);                                                   
         cCurrentMeta->Height = text->Font->Size;
      } 
TRectangle * rectangle = dynamic_cast<TRectangle *>(NewMeta(cctRectangle));
      if(contentList->Count == 10)
      {
         int x1Pos = ProtelGetPos(contentList->Strings[++index], 'x');
         int y1Pos = ProtelGetPos(contentList->Strings[++index], 'y');
         int x2Pos = ProtelGetPos(contentList->Strings[++index], 'x');
         int y2Pos = ProtelGetPos(contentList->Strings[++index], 'y');
         int borderWidth = ProtelGetBorderWidth(contentList->Strings[++index]);
         int borderColor = contentList->Strings[++index].ToInt();
         int fillColor = contentList->Strings[++index].ToInt();
         bool selectionFlag = contentList->Strings[++index].ToInt();
         bool drawSolidFlag = contentList->Strings[++index].ToInt();
 
         ProtelAddPoint(cCurrentMeta, x1Pos, y1Pos);
         ProtelAddPoint(cCurrentMeta, x2Pos, y2Pos);
         rectangle->LineWidth = borderWidth;
         rectangle->LineColor = borderColor;
         rectangle->FillColor = fillColor;
         rectangle->Transparent = !drawSolidFlag;
      }
TPolygon * polygon = dynamic_cast<TPolygon *>(NewMeta(cctPolygon));
      if(contentList->Count > 6)
      {
         int borderWidth = ProtelGetBorderWidth(contentList->Strings[++index]);
         int borderColor = contentList->Strings[++index].ToInt();
         int fillColor = contentList->Strings[++index].ToInt();
         bool drawFlag = contentList->Strings[++index].ToInt();
         bool selectionFlag = contentList->Strings[++index].ToInt();
         int pointNumber = contentList->Strings[++index].ToInt();
 
         for(int i = 0; i < pointNumber; ++i)
         {
            int xPos = ProtelGetPos(contentList->Strings[++index], 'x');
            int yPos = ProtelGetPos(contentList->Strings[++index], 'y');
            if(i == (pointNumber - 1))
               polygon->AddAllPoint(TFloatPoint(xPos, yPos));
            else
               ProtelAddPoint(cCurrentMeta, xPos, yPos);
         }
         polygon->LineWidth = borderWidth;
         polygon->LineColor = borderColor;
         polygon->FillColor = fillColor;
        polygon->Transparent = !drawFlag;
         // lineStyle
      }
TCurve * curve = dynamic_cast<TCurve *>(NewMeta(cctCurve));
      if(contentList->Count > 5)
      {
         int borderWidth = ProtelGetBorderWidth(contentList->Strings[++index]);
         int lineStyle = ProtelLineStyle(contentList->Strings[++index]);
         int color = contentList->Strings[++index].ToInt();
         bool selectionFlag = contentList->Strings[++index].ToInt();
         int pointNumber = contentList->Strings[++index].ToInt();
 
         for(int i = 0; i < pointNumber; ++i)
         {
            int xPos = ProtelGetPos(contentList->Strings[++index], 'x');
            int yPos = ProtelGetPos(contentList->Strings[++index], 'y');
            if(i == (pointNumber - 1))
               curve->AddAllPoint(TFloatPoint(xPos, yPos));
            else
               ProtelAddPoint(cCurrentMeta, xPos, yPos);
         }              
         curve->LineWidth = borderWidth;
         curve->LineColor = color;
         // lineStyle
      }
TLine * line = dynamic_cast<TLine *>(NewMeta(cctLine));
      if(contentList->Count == 9)
      {
         int x1Pos = ProtelGetPos(contentList->Strings[++index], 'x');
         int y1Pos = ProtelGetPos(contentList->Strings[++index], 'y');
         int x2Pos = ProtelGetPos(contentList->Strings[++index], 'x');
         int y2Pos = ProtelGetPos(contentList->Strings[++index], 'y');
         int lineWidth = ProtelGetBorderWidth(contentList->Strings[++index]);
         int lineStyle = ProtelLineStyle(contentList->Strings[++index]);
         int lineColor = contentList->Strings[++index].ToInt();
         bool selectionFlag = contentList->Strings[++index].ToInt();
 
         ProtelAddPoint(cCurrentMeta, x1Pos, y1Pos);
         ProtelAddPoint(cCurrentMeta, x2Pos, y2Pos);
         line->LineWidth = lineWidth;
         line->LineColor = lineColor;
         // lineStyle
      }
TArc * arc = dynamic_cast<TArc *>(NewMeta(cctArc));
      if(contentList->Count == 9)
      {
         int xPos = ProtelGetPos(contentList->Strings[++index], 'x');
         int yPos = ProtelGetPos(contentList->Strings[++index], 'y');
         int xRadius = contentList->Strings[++index].ToInt();
         int yRadius = xRadius;
         int borderWidth = ProtelGetBorderWidth(contentList->Strings[++index]);
         double beginTheta = contentList->Strings[++index].ToDouble();
         double endTheta = contentList->Strings[++index].ToDouble();
         int borderColor = contentList->Strings[++index].ToInt();
         bool selectionFlag = contentList->Strings[++index].ToInt();
 
         ProtelAddPoint(cCurrentMeta, xPos, yPos, 4);        
         arc->HorzAxis = xRadius;
         arc->VertAxis = yRadius;
         arc->LineWidth = borderWidth;
         arc->LineColor = borderColor;
         arc->BeginTheta = beginTheta;                 
         arc->EndTheta = endTheta;
         cCurrentMeta->DragBy(xPos - cCurrentMeta->CentralPoint.x, yPos - cCurrentMeta->CentralPoint.y, true);
      }
 
TCbwObject * __fastcall TLibEditForm::NewMeta(CbwClassType type)
{
   cCurrentMeta = (TCbwObject *)Build[type]();
   cCurrentMeta->XMLFile = cXmlFile;
   cCurrentMeta->Ratio = Ratio;
   cCurrentMeta->Canvas = PaintBox->Canvas;
   return cCurrentMeta;
}
 
void __fastcall ProtelAddPoint(TCbwObject * object, double x, double y, int times = 1)
{
   for(int i = 0; i < times; ++i)
      object->AddPoint(TFloatPoint(x, y));
}
 
int __fastcall ProtelGetPos(AnsiString str, char type)
{
   int result = str.ToInt();
   if(type == 'x' || type == 'X')
      result = 400 + result;
   if(type == 'y' || type == 'Y')
      result = 400 - result;
   return result;
}
 
int __fastcall ProtelGetBorderWidth(AnsiString str)
{
   int result = str.ToInt();
   return result;
}
 
int __fastcall ProtelLineStyle(AnsiString str)
{
   int result = str.ToInt();
   return result;
}
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值