Q:

Draw boxes from box drawing characters

In the old DOS operating system, a number of characters were provided to draw boxes. Here is a selection of these characters and their code points:
B3 B4 BF C0 C1 C2 C3 C4 C5 D9 DA
│  ┤  ┐  └  ┴  ┬  ├  ─  ┼  ┘  ┌

You can use these characters to draw boxes like this:
┌─────────┐
│         │
└─────────┘

Boxes can be attached to each other:
        ┌───┐
        │   │
┌───┬───┤   │
│   │   │   │
│   ├───┴───┘
│   │
└───┘

or intersect each other:
┌─────┐
│     │
│  ┌──┼──┐
│  │  │  │
└──┼──┘  │
   │     │
   └─────┘

or overlap each other partially or completely:
┌─────┐
├──┐  │
│  │  │
├──┘  │
└─────┘

Challenge description
Write a program that receives a series of positive decimal integers separated by whitespace from standard input. The number of integers you receive is a multiple of four, each set of four integers x1 x2 y1 y2 is to be interpreted as the coordinates of two points x1 y1 and x2 y2 forming opposing corners of a box. You may assume that for each set of coordinates, x1 ≠ x2 and y1 ≠ y2.
The coordinate system originates in the top left corner with x coordinates progressing to the right and y coordinates progressing downwards. You can assume that no x coordinate larger than 80 and no y coordinate larger than 25 appears.
Your program shall output in either UTF-8, UTF-16, or Codepage 437 a series of whitespace, carriage returns, line feeds, and box drawing characters such that the output shows the boxes described in the input. There may be extraneous whitespace at the end of lines. You may terminate lines either with CR/LF or just LF but stick to one, stray CR characters are not allowed. You may output any number of lines filled with an arbitrary amount of whitespace at the end of the output.
Examples
The following input draws the first diagram from the question:
1 11  1 3

The second diagram is offset a little bit, the leading whitespace and empty lines must be reproduced correctly:
17 13   3  7
 9  5   5  9
 9 13   5  7

The third diagram also tests that input is parsed correctly:
1 7 1
5 4 10
3 7

The fourth diagram:
11 5 2 6
5 8 3 5

As a final test case, try this fifth diagram:
    ┌─────┬─────┐
┌───┼───┬─┼─┬───┴───┐
│   │   │ │ │       │
└───┼───┴─┼─┴───┬───┘
    └─────┴─────┘

Which looks like this:
9 21 2 4 1
13 4 2 11 5
1 5 17 11 1
2 11 17 4 5

Winning condition
This is code golf. The shortest solution in octets (bytes) wins. Standard loopholes apply, (worthless) bonus points for writing a solution that works on DOS.

A:

PHP>=7.1, 820 Bytes
<?preg_match_all("#(\d+(\s+\d+){3})#s",$_GET[0],$t);$r=($w="array_fill")(1,25,$w(1,80," "));function u($n,$y,$x){global$r;$u=[$z=[" ","│",$c="┤","┐","└",$d="┴",$e="┬",$b="├","─","┘","┌",$a="┼"],["│",$c,$b,$a],[$c,$a],["┐",$c,$e,$a],["└",$d,$b,$a],[$d,$a],[$e,$a],[$b,$a],["─",$d,$e,$a],["┘",$c,$d,$a],["┌",$e,$b,$a],[$a]];$o=$r[$y][$x];$s=array_intersect($u[($k="array_search")($n,$z)],$u[$k($o,$z)]);$r[$y][$x]=reset($s);}foreach($t[1]as$e){[$a,$b,$c,$d]=explode(" ",preg_replace("#\s+#"," ",$e));u("┌",$h=min($c,$d),$f=min($a,$b));u("┐",$h,$g=max($a,$b));u("└",$i=max($c,$d),$f);u("┘",$i,$g);foreach(($l="array_slice")(range($f,$g),1,-1)as$x){u("─",$h,$x);u("─",$i,$x);}foreach($l(range($h,$i),1,-1)as$y){u("│",$y,$f);u("│",$y,$g);}}foreach($r as$v)echo join($v)."\n";

-6 Bytes for use "array_fill","array_search", "array_slice" without "
+19 Bytes echo ltrim(rtrim(join($v))."\n","\n"); instead of echo join($v)."\n"; to print only the necessary Chars
Online Version 
Expanded
preg_match_all("#(\d+(\s+\d+){3})#s",$_GET[0],$t); # find all rects
$r=($w="array_fill")(1,25,$w(1,80," ")); # fill a empty 2 D array with spaces 
function u($n,$y,$x){ # Char , Y Coordinate, X Coordinate as parameter
global$r; # result array must be global to make changes
# The following array based on Set Theory
$u=[
$z=[" ","│",$c="┤","┐","└",$d="┴",$e="┬",$b="├","─","┘","┌",$a="┼"],
["│",$c,$b,$a],
[$c,$a],
["┐",$c,$e,$a],
["└",$d,$b,$a],
[$d,$a],
[$e,$a],
[$b,$a],
["─",$d,$e,$a],
["┘",$c,$d,$a],
["┌",$e,$b,$a]
,[$a]];
$o=$r[$y][$x]; # old value for YX
$s=array_intersect($u[($k="array_search")($n,$z)],$u[$k($o,$z)]); # make the Cut quantity
$r[$y][$x]=reset($s); # Take the first value Cut quantity and set it as new value
}
foreach($t[1]as$e){ # for each rect
[$a,$b,$c,$d]=explode(" ",preg_replace("#\s+#"," ",$e)); #split the four coordinates
# next 4 rows make edges and set minimum and maximum for X an Y values
u("┌",$h=min($c,$d),$f=min($a,$b)); 
u("┐",$h,$g=max($a,$b));
u("└",$i=max($c,$d),$f);
u("┘",$i,$g);
foreach(($l="array_slice")(range($f,$g),1,-1)as$x){u("─",$h,$x);u("─",$i,$x);} # make the X lines
foreach($l(range($h,$i),1,-1)as$y){u("│",$y,$f);u("│",$y,$g);} # make the  Y lines
}
foreach($r as$v)echo join($v)."\n"; # Output

Order of the array Set Theory
foreach($u as $k0=>$v0)
foreach($u as $k1=>$v1)
echo "\n\n'".$z[$k0]."' + '".$z[$k1]."' = '". join("','",array_intersect($v0,$v1))."'";

Examples Set Theory all possible values
The array without the use of variables to short it
$u=[
$z=[" ","│","┤","┐","└","┴","┬","├","─","┘","┌","┼"],
["│","┤","├","┼"],
["┤","┼",],
["┐","┤","┬","┼"],
["└","┴","├","┼"],
["┴","┼"],
["┬","┼"],
["├","┼"],
["─","┴","┬","┼"],
["┘","┤","┴","┼"],
["┌","┬","├","┼"]
,["┼"]];');

A:

CJam, 129
0a80*a25*[q~]4/{:(2/:$_::-+e_534915808 6b3/\ff=C2b.+{):A;)z{_A)+\[A!A].+_A)4*+\}*;}%{~:A;_3$=@_2$=A|tt}/}/"   ┌ ─┐┬ └│├┘┴┤┼"ff=N*

Try it online
Notes:

If the boxes don't look quite right, it's possible that your browser is using a fallback font for box drawing characters.
CJam doesn't specify an encoding for source files. In UTF-8, this code has 151 bytes, but you can save it using CP437 or CP850 instead (and run it with the same encoding), then it will use 1 byte/character.

Overview:
0a80*a25* creates a matrix of 80×25 zeros
[q~]4/ reads the input, converts to numbers and splits into quadruplets
:(2/:$_::-+e_ converts an [x1 x2 y1 y2] quadruplet to [xmin xmax ymin ymax -width -height] (negative values will be corrected later)
534915808 6b3/ generates [[1 2 5] [0 2 5] [0 3 4] [0 2 4]], to be used as indices in the previous array for extracting data about the 4 sides of the current box
\ff= extracts the data for each side, e.g. [1 2 5] -> [xmax ymin -height] for the right side
C2b.+ appends 1, 1, 0, 0 respectively to the arrays for the 4 sides (right, left, bottom, top); this number indicates the direction (0=horizontal, 1=vertical)
):A;)z{_A)+\[A!A].+_A)4*+\}*; generates line pieces for a side, as [x y bitmask] triplets; each piece is a line going from the center of the cell to one of 4 directions: 1=right, 2=bottom, 4=left, 8=top; e.g. [4 2 -3 0] (a horizontal line of length 3 starting at x=4, y=2) results in [4 2 1] [5 2 4] [5 2 1] [6 2 4] [6 2 1] [7 2 4]
{~:A;_3$=@_2$=A|tt}/ bitwise-OR's all these line pieces into the matrix, resulting in bitmasks from 0..15
"   ┌ ─┐┬ └│├┘┴┤┼"ff= converts these bitmasks to the corresponding box-drawing characters
N* joins with newlines for display

A:

Haskell, 399 340 398 bytes
-59 (!) bytes thanks to Ørjan Johansen
import Data.Bits
import Data.Array
(&)=(,)
z=maximum
r x=[minimum x..z x-1]
l=map(+1).r
e(a:b:c:d:q)=[x&y&n|(n,(f,g))<-zip[0..][id&l,id&r,l&id,r&id],x<-f[a,b],y<-g[c,d]]++e q;e[]=[]
f a|m<-z a=unlines[[" UD│L┘┐┤R└┌├─┴┬┼"!!(accumArray setBit 0(1&1,m&m)(e a)!(x,y))|x<-[1..m]]|y<-[1..m]]
main=interact$f.map read.words

Try it online!
Ungolfed
import Data.Bits
import Data.Array
import Data.List.Split

(&) = (,) -- Alias for tuples

-- Given [a,b], returns a list of all x: a <= x < b 
halfOpenLeft x = [minimum x..maximum x-1::Int]

-- Same as above, but for all x: a < x <= b
halfOpenRight = map(+1).halfOpenLeft

up    = ((id, halfOpenRight), 0) -- Coordinates that should have a line upwards
down  = ((id, halfOpenLeft),  1) -- Coordinates that should have a line downwards
left  = ((halfOpenRight, id), 2) -- Coordinates that should have a line leftwards
right = ((halfOpenLeft, id),  3) -- Coordinates that should have a line rightwards

-- Create a map between coordinates and line-segments. Each coordinate can have multiple line-segments.
lineSegments :: [[Int]] -> [((Int,Int),Int)]
lineSegments rects = [ ((x,y),n) | [x1,x2,y1,y2] <- rects, ((f,g),n) <- [up,down,left,right], x <- f [x1,x2], y <- g [y1,y2]]

-- Convert an array of bit-fields into a list of lines. 
printBitfieldArray :: Int -> Array (Int,Int) Int -> [String]
printBitfieldArray size a = [[" UD│L┘┐┤R└┌├─┴┬┼"!!(a!(x,y))|x<-[1..size]]|y<-[1..size]]

-- Merge all the line-segments for each coordinate into a bitfield
createBitFieldArray :: Int -> [((Int,Int),Int)] -> Array (Int,Int) Int
createBitFieldArray m = accumArray setBit 0 ((1,1),(m,m))

-- First split the input for each rectangle,
-- then create a list of pairs of coordinates and directions,
-- then merge all directions for each coordinate into a bitfield
-- and finally use the bitfield as an index to find out which shape to draw.
drawRectangles :: Int -> [Int] -> [String]
drawRectangles m=printBitFieldArray m.createBitFieldArray m.lineSegments.chunksOf 4

-- Parse the input, solve the problem and format the output. Use the largest number as both width and height.
main=interact$unlines.(drawRectangles=<<maximum).map read.words

Explanation

First, lineSegments (or d in the golfed version) will loop over all rectangles, all directions and all coordinates that should have a line-segment in that direction from that rectangle and create a list of coordinates paired with directions.
Then createBitFieldArry merges all entries with identical coordinates into an array of bitfields. Here, the 0th bit means up, 1st means down, 2nd means left and the 3rd means right. In other words, 5 is rendered as "┘", 0 is " " and 15 is "┼".
Lastly, printBitFieldArray (or p) converts the bitfields into box-drawing characters by using them as indices.

