NMosContactsImpl.mesa (part of Chipndale)
by Christian Jacobi June 24, 1983 5:03 pm
last edited Christian Jacobi December 14, 1983 11:00 am
DIRECTORY
NMosContacts,
CD,
CDCallSpecific,
CDIO,
CDInline,
CDLRUCache,
CDOrient,
NMos,
Rope,
TokenIO;
NMosContactsImpl:
CEDAR
PROGRAM
IMPORTS CDCallSpecific, CDInline, CDIO, CDLRUCache, CDOrient, NMos, TokenIO
EXPORTS NMosContacts =
BEGIN OPEN NMos;
lambda: CD.DesignNumber = CD.lambda;
ContactType: TYPE = NMosContacts.ContactType;
ContactPtr: TYPE = NMosContacts.ContactPtr;
ContactRec: TYPE = NMosContacts.ContactRec;
wellSurround: CD.DesignNumber = 4*lambda;
wXExtension: CD.DesignNumber = 2*lambda;
lXExtension: CD.DesignNumber = 2*lambda;
butConSX: CD.DesignNumber = 4*lambda;
butConSY: CD.DesignNumber = 6*lambda;
difCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont];
polyCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont];
dsCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont];
butCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont];
burCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont];
mmCache: CDLRUCache.LRUCache = CDLRUCache.Create[size: 5, aequivalenceProc: Aequivalent, newProc: NewCont];
ToPosition:
PROC [x:
REF]
RETURNS [p:
CD.DesignPosition] =
--y field defaults to lambda, x field defaults to 0
--[0, 0] if not done
BEGIN
IF x=NIL THEN p ← [0, lambda]
ELSE
WITH x
SELECT
FROM
rp: REF CD.DesignPosition => p ← rp^;
rn: REF CD.DesignNumber => p ← [0, rn^];
ENDCASE => p ← [0, 0];
END;
Aequivalent:
PROC[mySpecific, other:
REF
ANY]
RETURNS [
BOOL] = {
WITH other
SELECT
FROM
p2: ContactPtr => RETURN [NARROW[mySpecific, ContactPtr]^=p2^];
ENDCASE => RETURN [FALSE]
};
NewCont:
PROC []
RETURNS [
CD.ObPtr] = {
ob: CD.ObPtr ← NEW[CD.ObjectDefinition];
ob.specificRef ← NEW[ContactRec];
RETURN [ob]
};
MatchContact:
PROC [me: CD.ObPtr, r: CD.DesignRect, level: CD.Level, prim:
BOOL, horz:
BOOL]
RETURNS [
BOOL] =
BEGIN
IF level=me.level THEN RETURN [TRUE]
ELSE {
cp: ContactPtr = NARROW[me.specificRef];
RETURN [
SELECT cp.typ
FROM
burr => (level=NMos.pol),
mDif => (level=NMos.met),
difShort => FALSE,
butt => (level=NMos.met OR level=NMos.pol),
mPol => (level=NMos.met),
mm2 => (level=NMos.met2),
ENDCASE => FALSE
]
}
END;
Describe:
PROC[me:
CD.ObPtr]
RETURNS [Rope.
ROPE] =
BEGIN
RETURN [
SELECT
NARROW[me.specificRef, ContactPtr].typ
FROM
burr => "buried contact",
mDif => "dif contact",
difShort => "dif-short contact",
butt => "button contact",
mPol => "poly contact",
mm2 => "via",
ENDCASE => "unknown contact"
]
END;
-- Dif and Pol -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
pForDifPolCon: REF CD.ObjectProcs ~ RegisterObjectType[$NMosContactDifAndPol];
difpolRimWidth: CD.DesignNumber = lambda;
CreateDifCon:
PUBLIC
PROC [l:
CD.DesignNumber]
RETURNS [
CD.ObPtr] =
--connect diffusion with metal
BEGIN
cob: CD.ObPtr ~ difCache.UnusedOrNew[];
cp: ContactPtr ~ NARROW[cob.specificRef];
l ← MAX[l, butConSX];
cp.typ ← mDif;
cob.p ← pForDifPolCon; -- does not use specicRef !
cob.level ← dif;
cob.size ← [butConSX, l];
RETURN [difCache.ReplaceByAequivalent[cob]]
END;
CreatePolyCon:
PUBLIC
PROC [l:
CD.DesignNumber]
RETURNS [
CD.ObPtr] =
--connect poly with metal
BEGIN
cob: CD.ObPtr ~ polyCache.UnusedOrNew[];
cp: ContactPtr ~ NARROW[cob.specificRef];
l ← MAX[l, butConSX];
cp.typ ← mPol;
cob.p ← pForDifPolCon; -- does not use specicRef !
cob.size ← [butConSX, l];
cob.level ← pol;
RETURN [polyCache.ReplaceByAequivalent[cob]]
END;
LengthenDifPol: CDCallSpecific.CallProc =
BEGIN
amount: CD.DesignPosition = ToPosition[x];
IF amount.y=0 OR amount.x#0 THEN done ← FALSE
ELSE {
cp: ContactPtr ← NARROW[aptr.ob.specificRef];
ap: CD.ApplicationPtr ← NEW[CD.Application ← aptr^];
sz: CD.DesignPosition ← CDInline.AddPoints[aptr.ob.size, amount];
IF sz.x<=0 OR sz.y<=0 THEN {done ← FALSE; RETURN};
IF aptr.ob.level=pol THEN ap.ob ← CreatePolyCon[sz.y] ELSE ap.ob ← CreateDifCon[sz.y];
include ← LIST[ap];
removeMe ← TRUE;
repaintMe ← amount.y<0;
repaintInclude ← amount.y>0;
}
END;
DefaultenDifPol: CDCallSpecific.CallProc =
BEGIN
cp: ContactPtr ← NARROW[aptr.ob.specificRef];
ap: CD.ApplicationPtr ← NEW[CD.Application𡤊ptr^];
IF aptr.ob.level=pol THEN ap.ob ← CreatePolyCon[4*lambda] ELSE ap.ob ← CreateDifCon[4*lambda];
include ← LIST[ap];
removeMe ← TRUE;
repaintMe ← TRUE;
repaintInclude ← TRUE;
END;
ReadDifPolCon:
CD.InternalReadProc
--PROC [] RETURNS [ObPtr]-- =
BEGIN
lev: CD.Level = CDIO.ReadLevel[];
IF lev=pol THEN RETURN [ CreatePolyCon[TokenIO.ReadInt[]] ]
ELSE RETURN [ CreateDifCon[TokenIO.ReadInt[]] ]
END;
WriteDifPolCon:
CD.InternalWriteProc
-- PROC [me: ObPtr] -- =
BEGIN
CDIO.WriteLevel[me.level];
TokenIO.WriteInt[me.size.y];
END;
SetLengthDifPol: CDCallSpecific.CallProc =
BEGIN
newLength: CD.DesignNumber ← NARROW[x, REF CD.DesignNumber]^;
oldLength: CD.DesignNumber ← aptr.ob.size.y;
ap: CD.ApplicationPtr ← NEW[CD.Application𡤊ptr^];
IF aptr.ob.level=dif
THEN
ap.ob ← CreateDifCon[newLength] ELSE ap.ob ← CreatePolyCon[newLength];
include←LIST[ap];
removeMe←TRUE;
IF newLength>oldLength THEN repaintInclude←TRUE ELSE repaintMe←TRUE;
END;
DrawDifAndPolContact:
PROC [aptr: CD.ApplicationPtr, pos:
CD.DesignPosition, orient:
CD.Orientation,
pr: CD.DrawRef] =
--does not read specificRef !!!!!!
BEGIN
IF CDInline.Intersect[CDOrient.RectAt[pos, aptr.ob.size, orient], pr.worldClip]
THEN
BEGIN
r: CD.DesignRect = CDOrient.RectAt[pos, aptr.ob.size, orient];
pr.drawRect[r, met, pr];
pr.drawRect[r, aptr.ob.level, pr];
pr.saveRect[CDInline.Extend[r, -difpolRimWidth], cut, pr];
END
END;
-- DifShort -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
pForDifShorts: REF CD.ObjectProcs ~ RegisterObjectType[$NMosContactDifShort];
difShortRimWidth: CD.DesignNumber = lambda;
CreateDifShortCon:
PUBLIC
PROC []
RETURNS [
CD.ObPtr] =
BEGIN
cob: CD.ObPtr ~ dsCache.UnusedOrNew[];
cp: ContactPtr ~ NARROW[cob.specificRef];
cp.typ ← difShort;
cob.p ← pForDifShorts;
cob.level ← dif;
cob.size ← [butConSX, 8*lambda];
RETURN [dsCache.ReplaceByAequivalent[cob]]
END;
ReadDifShortCon:
CD.InternalReadProc
--PROC [] RETURNS [ObPtr]-- =
BEGIN
RETURN [ CreateDifShortCon[] ]
END;
WriteDifShortCon:
CD.InternalWriteProc
-- PROC [me: ObPtr] -- =
BEGIN
END;
DrawDifShortContact:
PROC [aptr: CD.ApplicationPtr, pos:
CD.DesignPosition, orient:
CD.Orientation,
pr: CD.DrawRef] =
BEGIN
Draw:
PROC[r:
CD.DesignRect, l:
CD.Level] =
INLINE
uses outer stuff!!
BEGIN
pr.drawRect[
CDOrient.MapRect[
itemInCell: r,
cellSize: aptr.ob.size,
cellInstOrient: orient,
cellInstPos: pos],
l,
pr];
END;
Save:
PROC[r:
CD.DesignRect, l:
CD.Level] =
INLINE
uses outer stuff!!
BEGIN
pr.saveRect[
CDOrient.MapRect[
itemInCell: r,
cellSize: aptr.ob.size,
cellInstOrient: orient,
cellInstPos: pos],
l,
pr];
END;
IF CDInline.Intersect[CDOrient.RectAt[pos, aptr.ob.size, orient], pr.worldClip]
THEN
BEGIN
r: CD.DesignRect = CDOrient.RectAt[[0, 0], aptr.ob.size];
mr: CD.DesignRect = CDInline.Extend[r, -difShortRimWidth];
h: CD.DesignNumber = (r.y2-r.y1)/2;
Draw[r, met];
Draw[[x1: r.x1, y1: r.y1, x2: r.x2, y2: r.y1+h], aptr.ob.level];
Draw[[x1: r.x1, y1: r.y1+h, x2: r.x2, y2: r.y2], nwelCont];
Save[[x1: mr.x1, x2: mr.x2, y1: mr.y1, y2: mr.y1+2*lambda], cut];
Save[[x1: mr.x1, x2: mr.x2, y1: mr.y2-2*lambda, y2: mr.y2], cut];
END
END;
-- But -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
pForButContact: REF CD.ObjectProcs ~ RegisterObjectType[$NMosContactBut];
CreateButCon:
PUBLIC
PROC []
RETURNS [
CD.ObPtr] =
--connects metal with poly and diffusion
BEGIN
cob: CD.ObPtr ~ butCache.UnusedOrNew[];
cp: ContactPtr ~ NARROW[cob.specificRef];
cp.typ ← butt;
cob.p ← pForButContact;
cob.level ← dif;
cob.size ← [butConSX, butConSY];
RETURN [butCache.ReplaceByAequivalent[cob]]
END;
ReadButCon:
CD.InternalReadProc
--PROC [] RETURNS [ObPtr]-- =
BEGIN
RETURN [ CreateButCon[] ]
END;
WriteButCon:
CD.InternalWriteProc
-- PROC [me: ObPtr] -- =
BEGIN
END;
DrawButContact:
PROC [aptr: CD.ApplicationPtr, pos:
CD.DesignPosition, orient:
CD.Orientation,
pr: CD.DrawRef] =
BEGIN
Draw:
PROC[r:
CD.DesignRect, l:
CD.Level] =
INLINE
--uses outer stuff!!
BEGIN
pr.drawRect[
CDOrient.MapRect[
itemInCell: r,
cellSize: aptr.ob.size,
cellInstOrient: orient,
cellInstPos: pos],
l,
pr];
END;
Save:
PROC[r:
CD.DesignRect, l:
CD.Level] =
INLINE
--uses outer stuff!!
BEGIN
pr.drawRect[
CDOrient.MapRect[
itemInCell: r,
cellSize: aptr.ob.size,
cellInstOrient: orient,
cellInstPos: pos],
l,
pr];
END;
--DrawButContact
IF CDInline.Intersect[CDOrient.RectAt[pos, aptr.ob.size, orient], pr.worldClip]
THEN
BEGIN
rimWidth: CD.DesignNumber = lambda;
polySize: CD.DesignNumber = aptr.ob.size.y/2;
Draw[[0, 0, aptr.ob.size.x, aptr.ob.size.y], met];
Draw[[0, 0, aptr.ob.size.x, polySize], pol];
Draw[[0, polySize-lambda, aptr.ob.size.x, aptr.ob.size.y], aptr.ob.level];
Save[[rimWidth, rimWidth, aptr.ob.size.x-rimWidth, aptr.ob.size.y-rimWidth], cut];
END
END;
-- Bur -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
pForBurCon:
REF
CD.ObjectProcs ~ RegisterObjectType[$NMosBurContact];
CreateBurCon:
PUBLIC
PROC [w, l:
CD.DesignNumber,
wex: CD.DesignNumber←wXExtension,
lex: CD.DesignNumber←lXExtension] RETURNS [CD.ObPtr] =
-- connects diffusion with poly without accessing metal
BEGIN
cob: CD.ObPtr ~ burCache.UnusedOrNew[];
cp: ContactPtr ~ NARROW[cob.specificRef];
burAct: CD.DesignNumber = 2*lambda;
actWidth, xMargins: CD.DesignNumber;
wex ← MAX[0, wex];
lex ← MAX[0, lex];
xMargins ← burAct +
(IF wex< burAct THEN MAX[wex+lambda, burAct] ELSE wex);
actWidth ← MAX[2*lambda, w-xMargins];
w ← actWidth+xMargins;
l ←
MAX[l,
(IF lex<burAct THEN MAX[lex+lambda, burAct] ELSE lex)*2+lambda*MAX[6*lambda/actWidth, 2]
];
cp.typ ← burr;
cp.wExt ← wex;
cp.lExt ← lex;
cob.p ← pForBurCon;
cob.size ← [w, l];
cob.level ← dif;
RETURN [burCache.ReplaceByAequivalent[cob]]
END;
ReadBurCon:
CD.InternalReadProc
--PROC [] RETURNS [ObPtr]-- =
BEGIN
w: INT = TokenIO.ReadInt[];
l: INT = TokenIO.ReadInt[];
wex: INT = TokenIO.ReadInt[];
lex: INT = TokenIO.ReadInt[];
RETURN [ CreateBurCon[w, l, wex, lex] ]
END;
WriteBurCon:
CD.InternalWriteProc
-- PROC [me: ObPtr] -- =
BEGIN
cp: ContactPtr = NARROW[me.specificRef];
TokenIO.WriteInt[me.size.x];
TokenIO.WriteInt[me.size.y];
TokenIO.WriteInt[cp.wExt];
TokenIO.WriteInt[cp.lExt];
END;
DrawMeForBurrNMosContacts:
PROC [aptr: CD.ApplicationPtr, pos:
CD.DesignPosition, orient:
CD.Orientation,
pr: CD.DrawRef] =
BEGIN
Draw:
PROC[r:
CD.DesignRect, l:
CD.Level] =
INLINE
uses outer stuff!!
BEGIN
pr.drawRect[
CDOrient.MapRect[
itemInCell: r,
cellSize: aptr.ob.size,
cellInstOrient: orient,
cellInstPos: pos],
l,
pr];
END;
Save:
PROC[r:
CD.DesignRect, l:
CD.Level] =
INLINE
uses outer stuff!!
BEGIN
pr.saveRect[
CDOrient.MapRect[
itemInCell: r,
cellSize: aptr.ob.size,
cellInstOrient: orient,
cellInstPos: pos],
l,
pr];
END;
--DrawMeForBurrNMosContacts
p: ContactPtr = NARROW[aptr.ob.specificRef];
dBur: CD.DesignNumber = lambda/2;
burAct: CD.DesignNumber = lambda*2;
diffBur:
CD.DesignPosition = [
x: IF p.wExt<burAct THEN MAX[p.wExt+lambda, burAct] ELSE p.wExt-lambda,
y: IF p.lExt<burAct THEN MAX[p.lExt+lambda, burAct] ELSE p.lExt-lambda
];
Save[[dBur, dBur, aptr.ob.size.x-dBur, aptr.ob.size.y-dBur], bur];
Draw[[burAct, p.lExt, aptr.ob.size.x-p.wExt, aptr.ob.size.y-p.lExt], pol];
Draw[[lambda, diffBur.y, aptr.ob.size.x-diffBur.x, aptr.ob.size.y-diffBur.y], aptr.ob.level];
END;
LengthenBur: CDCallSpecific.CallProc =
BEGIN
amount: CD.DesignPosition = ToPosition[x];
IF amount.y=0 AND amount.x=0 THEN done ← FALSE
ELSE {
cp: ContactPtr = NARROW[aptr.ob.specificRef];
ap: CD.ApplicationPtr = NEW[CD.Application ← aptr^];
ap.ob ← CreateBurCon[
w: aptr.ob.size.x+amount.x,
l: aptr.ob.size.y+amount.y,
wex: cp.wExt,
lex: cp.lExt
];
include ← LIST[ap];
removeMe ← TRUE;
repaintMe ← amount.x<0 OR amount.y<0;
repaintInclude ← amount.x>0 OR amount.y>0;
};
END;
ChangeExtensionBur: CDCallSpecific.CallProc =
BEGIN
amount: CD.DesignPosition = ToPosition[x];
IF amount.y=0 AND amount.x=0 THEN done ← FALSE
ELSE {
cp: ContactPtr ← NARROW[aptr.ob.specificRef];
ap: CD.ApplicationPtr ← NEW[CD.Application𡤊ptr^];
ap.ob ← CreateBurCon[
w: aptr.ob.size.x+amount.x,
l: aptr.ob.size.y+amount.y,
wex: cp.wExt+amount.x,
lex: cp.lExt+amount.y
];
include ← LIST[ap];
removeMe ← TRUE;
repaintMe ← amount.x<0 OR amount.y<0;
repaintInclude ← amount.x>0 OR amount.y>0;
}
END;
SetLengthBur: CDCallSpecific.CallProc =
BEGIN
newLength: CD.DesignNumber ← NARROW[x, REF CD.DesignNumber]^;
oldLength: CD.DesignNumber ← aptr.ob.size.y;
cp: ContactPtr ← NARROW[aptr.ob.specificRef];
ap: CD.ApplicationPtr ← NEW[CD.Application𡤊ptr^];
ap.ob ← CreateBurCon[w: aptr.ob.size.x, l: newLength, wex: cp.wExt, lex: cp.lExt];
include ← LIST[ap];
removeMe ← TRUE;
IF newLength>oldLength THEN repaintInclude ← TRUE ELSE repaintMe ← TRUE;
END;
DefaultenBur: CDCallSpecific.CallProc =
BEGIN
cp: ContactPtr ← NARROW[aptr.ob.specificRef];
ap: CD.ApplicationPtr ← NEW[CD.Application𡤊ptr^];
ap.ob ← CreateBurCon[w: aptr.ob.size.x, l: 4*lambda, wex: cp.wExt, lex: cp.lExt];
include←LIST[ap];
removeMe←TRUE;
repaintMe←TRUE;
repaintInclude←TRUE;
END;
-- Mm -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
pForVia: REF CD.ObjectProcs ~ RegisterObjectType[$NMosMmContact];
mmRimWidth: CD.DesignNumber = 2*lambda;
cut2min: CD.DesignNumber = 3*lambda;
CreateMmCon:
PUBLIC
PROC [l:
CD.DesignNumber,
wex: CD.DesignNumber←wXExtension,
lex: CD.DesignNumber←lXExtension] RETURNS [CD.ObPtr] =
-- ignores wex and lex in chipmonk, why???
-- connects two layers of metal
BEGIN
cob: CD.ObPtr ~ mmCache.UnusedOrNew[];
cp: ContactPtr ~ NARROW[cob.specificRef];
mins: CD.DesignNumber = cut2min+2*mmRimWidth;
l ← MAX[l, mins];
cp.typ ← mm2;
--cp.wExt ← ;
--cp.wExt ← ;
cob.p ← pForVia;
cob.size ← [mins, l];
--cob.level ← ;
RETURN [mmCache.ReplaceByAequivalent[cob]]
END;
ReadVia:
CD.InternalReadProc
--PROC [] RETURNS [ObPtr]-- =
BEGIN
RETURN [ CreateMmCon[TokenIO.ReadInt[]] ]
END;
WriteVia:
CD.InternalWriteProc
-- PROC [me: ObPtr] -- =
BEGIN
TokenIO.WriteInt[me.size.y];
END;
ShortenMm: CDCallSpecific.CallProc =
BEGIN
cp: ContactPtr ← NARROW[aptr.ob.specificRef];
ap: CD.ApplicationPtr ← NEW[CD.Application𡤊ptr^];
ap.ob ← CreateMmCon[l: aptr.ob.size.y-lambda, wex: cp.wExt, lex: cp.lExt];
include←LIST[ap];
removeMe←TRUE;
repaintMe←TRUE;
END;
LengthenVia: CDCallSpecific.CallProc =
BEGIN
amount: CD.DesignPosition = ToPosition[x];
IF amount.y=0 OR amount.x#0 THEN done ← FALSE
ELSE {
cp: ContactPtr ← NARROW[aptr.ob.specificRef];
ap: CD.ApplicationPtr ← NEW[CD.Application𡤊ptr^];
sz: CD.DesignPosition ← CDInline.AddPoints[aptr.ob.size, amount];
IF sz.x<=0 OR sz.y<=0 THEN {done←FALSE; RETURN};
ap.ob ← CreateMmCon[l: sz.y, wex: cp.wExt, lex: cp.lExt];
include ← LIST[ap];
removeMe ← TRUE;
repaintMe ← amount.y<0;
repaintInclude ← amount.y>0;
}
END;
SetLengthVia: CDCallSpecific.CallProc =
BEGIN
newLength: CD.DesignNumber ← NARROW[x, REF CD.DesignNumber]^;
oldLength: CD.DesignNumber ← aptr.ob.size.y;
cp: ContactPtr ← NARROW[aptr.ob.specificRef];
ap: CD.ApplicationPtr ← NEW[CD.Application𡤊ptr^];
ap.ob ← CreateMmCon[l: newLength, wex: cp.wExt, lex: cp.lExt];
include ← LIST[ap];
removeMe ← TRUE;
IF newLength>oldLength THEN repaintInclude ← TRUE ELSE repaintMe ← TRUE;
END;
DefaultenVia: CDCallSpecific.CallProc =
BEGIN
cp: ContactPtr ← NARROW[aptr.ob.specificRef];
ap: CD.ApplicationPtr ← NEW[CD.Application𡤊ptr^];
ap.ob ← CreateMmCon[l: 4*lambda, wex: cp.wExt, lex: cp.lExt];
include ← LIST[ap];
removeMe ← TRUE;
repaintMe ← TRUE;
repaintInclude ← TRUE;
END;
DrawMeForMmNMosContacts:
PROC [aptr: CD.ApplicationPtr, pos:
CD.DesignPosition, orient:
CD.Orientation,
pr: CD.DrawRef] =
--does not read specificRef !!!!!!
BEGIN
IF CDInline.Intersect[CDOrient.RectAt[pos, aptr.ob.size, orient], pr.worldClip]
THEN
BEGIN
r: CD.DesignRect = CDOrient.RectAt[pos, aptr.ob.size, orient];
pr.drawRect[r, met, pr];
pr.drawRect[r, met2, pr];
pr.saveRect[CDInline.Extend[r, -mmRimWidth], cut2, pr];
END
END;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Init:
PROC [] =
BEGIN
pForDifPolCon.drawMe ← pForDifPolCon.quickDrawMe ← DrawDifAndPolContact;
CDCallSpecific.Register[$Lengthen, pForDifPolCon, LengthenDifPol];
CDCallSpecific.Register[$Default, pForDifPolCon, DefaultenDifPol];
CDCallSpecific.Register[$SetLength, pForDifPolCon, SetLengthDifPol];
pForDifPolCon.internalRead ← ReadDifPolCon;
pForDifPolCon.internalWrite ← WriteDifPolCon;
pForDifPolCon.describe ← Describe;
pForDifPolCon.match ← MatchContact;
pForButContact.drawMe ← pForButContact.quickDrawMe ← DrawButContact;
pForButContact.internalRead ← ReadButCon;
pForButContact.internalWrite ← WriteButCon;
pForButContact.describe ← Describe;
pForButContact.match ← MatchContact;
pForBurCon.drawMe ← pForBurCon.quickDrawMe ← DrawMeForBurrNMosContacts;
CDCallSpecific.Register[$Lengthen, pForBurCon, LengthenBur];
CDCallSpecific.Register[$Default, pForBurCon, DefaultenBur];
CDCallSpecific.Register[$SetLength, pForBurCon, SetLengthBur];
CDCallSpecific.Register[$ChangeExt, pForBurCon, ChangeExtensionBur];
pForBurCon.internalRead ← ReadBurCon;
pForBurCon.internalWrite ← WriteBurCon;
pForBurCon.describe ← Describe;
pForBurCon.match ← MatchContact;
pForVia.drawMe ← pForVia.quickDrawMe ← DrawMeForMmNMosContacts;
CDCallSpecific.Register[$Lengthen, pForVia, LengthenVia];
CDCallSpecific.Register[$Default, pForVia, DefaultenVia];
CDCallSpecific.Register[$SetLength, pForVia, SetLengthVia];
pForVia.internalRead ← ReadVia;
pForVia.internalWrite ← WriteVia;
pForVia.describe ← Describe;
pForVia.match ← MatchContact;
pForDifShorts.drawMe ← pForDifShorts.quickDrawMe ← DrawDifShortContact;
pForDifShorts.internalRead ← ReadDifShortCon;
pForDifShorts.internalWrite ← WriteDifShortCon;
pForDifShorts.describe ← Describe;
pForDifShorts.match ← MatchContact;
END;
Init[];
END.