X-Git-Url: https://git.stderr.nl/gitweb?p=matthijs%2Fmaster-project%2Freport.git;a=blobdiff_plain;f=Utils%2FMetapost.tex;h=a9b485a205f6b4959c480e96f9546a756512b244;hp=cac69ddbd68bac88ae4bbf2b8591e862376ea5f8;hb=b92b16b7e4ab854699bcd151bad0be7c5d73c0ae;hpb=48cad63619d532983939384e62e0921003a5a1cb diff --git a/Utils/Metapost.tex b/Utils/Metapost.tex index cac69dd..a9b485a 100644 --- a/Utils/Metapost.tex +++ b/Utils/Metapost.tex @@ -8,6 +8,7 @@ input metaobj; setObjectDefaultOption("Box")("framewidth")(.75mm); setObjectDefaultOption("Circle")("framewidth")(.75mm); setObjectDefaultOption("Circle")("circmargin")(3mm); +setObjectDefaultOption("Mux")("framewidth")(.75mm); %ahlength := 1.5mm; ahangle := 60; @@ -16,4 +17,145 @@ setCurveDefaultOption("linewidth",.75mm); % included in the bounding box for line cutoff. setCurveDefaultOption("nodesep",curve_linewidth_default); + +% Define a register. +% |v| is either a picture, a string or an object given by its number which +% will be contained inside the register. Supports the same options as Box, +% plus: +% reflect Reflect the register vertically, so input is right and output +% is left. (default: false) +% labels Show labels for the input and output ports. (default: false) +vardef newReg@#(expr v) text options= + ExecuteOptions(@#)(options); + assignObj(@#,"Reg"); + StandardInterface; + + % We contain a box (that contains the passed object in turn) + SubObject(box,obj(newobjstring_)); + newBox.obj(@#box)(v) options; + + % Some points for ports + ObjPoint ck,d,out; + + ObjCode StandardEquations, + % Align our bounding box with the enclosed box + "obj(@#box).c = @#c", + "obj(@#box).se = @#se", + "obj(@#box).nw = @#nw", + % Put the clock, data and output ports at the right spots + if OptionValue@#("reflect"): + "xpart @#out = xpart @#w", + "xpart @#d = xpart @#ck = xpart @#e", + else: + "xpart @#out = xpart @#e", + "xpart @#d = xpart @#ck = xpart @#w", + fi + "ypart @#out = ypart midpoint(@#n, @#s)", + "ypart @#d = ypart (@#sw * .25 + @#nw * .75)", + "ypart @#ck = ypart (@#sw * .75 + @#nw * .25)"; + + StandardTies; +enddef; + +% Draw a register +def drawReg(suffix reg)= + save clkwh, refl; + % Draw the box + drawObj(obj(reg.box)); + + % Fill refl with 1 or -1, to invert coordinates when reflected. + if OptionValue.reg("reflect"): + refl = -1; + else: + refl = 1; + fi; + + % Calculate (half of) the height and width of the triangle + clkwh = ypart((reg.n - reg.s)) * .1; + % Draw the "clock" triangle + draw ((0, clkwh) -- (refl * clkwh, 0) -- (0, -clkwh)) shifted reg.ck; + + % Draw input and output labels + if OptionValue.reg("labels"): + if OptionValue.reg("reflect"): + label.lft(\sometxt{D}, reg.d); + label.rt(\sometxt{O}, reg.out); + else: + label.rt(\sometxt{D}, reg.d); + label.lft(\sometxt{O}, reg.out); + fi; + fi +enddef; + +% Bounding path for a register +def BpathReg(suffix n)=BpathObj(obj(n.box)) enddef; + +% Define options +define_global_boolean_option("reflect"); +define_global_boolean_option("labels"); +setObjectDefaultOption("Reg")("reflect")(false); +setObjectDefaultOption("Reg")("labels")(false); + +% Define a Multiplexer. +vardef newMux@# text options= + ExecuteOptions(@#)(options); + assignObj(@#,"Mux"); + StandardInterface; + % Add ports + ObjPoint inpa, inpb, out, sel; + + ObjCode MinimumStandardEquations, + % Make it a parallel trapezium + "xpart(@#ne - @#nw) = xpart(@#se - @#sw)", + "ypart(@#ne - @#nw) = -1 * ypart(@#se - @#sw)", + % Use a 22.5 degree angle for the sides + "ypart(@#nw) - ypart(@#ne) = xpart(@#ne-@#nw) / 2", + % With a specific width and height + "@#e-@#w = (" & decimal OptionValue@#("width") & ", 0mm)", + "@#n-@#s = (0mm, " & decimal OptionValue@#("height") & ")", + % And space the input ports evenly + "@#inpa = midpoint(@#nw, @#w)", + "@#inpb = midpoint(@#w, @#sw)", + "@#out = @#e", + "@#sel = @#n"; + + StandardTies; +enddef; + +% Draw a multiplexer +def drawMux(suffix mux)= + draw mux.n -- mux.s; + % Use our bounding path to draw + drawFramedOrFilledObject_(mux); +enddef; + +% Bounding path for a multiplexer +def BpathMux(suffix n)=StandardBpath(n) enddef; + +% Define options +define_local_numeric_option("width"); +define_local_numeric_option("height"); +setObjectDefaultOption("Mux")("width")(5mm); +setObjectDefaultOption("Mux")("height")(15mm); +setObjectDefaultOption("Mux")("framed")(true); +% Overidden above +%setObjectDefaultOption("Mux")("framewidth")(.5bp); +setObjectDefaultOption("Mux")("framecolor")(black); +setObjectDefaultOption("Mux")("framestyle")(""); +setObjectDefaultOption("Mux")("shadow")(false); +setObjectDefaultOption("Mux")("shadowcolor")(black); +setObjectDefaultOption("Mux")("filled")(false); +setObjectDefaultOption("Mux")("fillcolor")(black); + + +def midpoint(expr a, b) = ((a + b) / 2) enddef; + \stopMPinclusions + +% Make \overrightarrow "unexpanded", to make it work within metapost. +% http://www.ntg.nl/pipermail/ntg-context/2009/043620.html. Will be fixed in +% context. +\let\normaloverrightarrow\overrightarrow +\unexpanded\def\overrightarrow{\normaloverrightarrow} + +% vim: set sw=2 sts=2 expandtab: