% Some setup for metapost \startMPinclusions % Use metaobj for drawing objects input metaobj; % Set some defaults for pretty pictures setObjectDefaultOption("Box")("framewidth")(.75mm); setObjectDefaultOption("Circle")("framewidth")(.75mm); setObjectDefaultOption("Circle")("circmargin")(3mm); setObjectDefaultOption("Mux")("framewidth")(.75mm); %ahlength := 1.5mm; ahangle := 60; setCurveDefaultOption("linewidth",.75mm); % Add a nodesep that's equal to the linewidth, since the linewidth isn't % 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: