[Question]
  [
Write a program that inputs the dimensions of a painting, the matting width, and the frame width for a framed portrait. The program should output a diagram using the symbol `X` for the painting, `+` for the matting, and `#` for the framing. The symbols must be space-separated. Trailing whitespace is alright, as long as the output visually matches the criteria. The inputs can be `0`.
INPUT: 3 2 1 2
(Width, Height, Matte Width, Frame Width)
OUTPUT: 
[![First 3 and 2 are painting width and height. 1 is the matte width around it. 2 is the frame width around the whole thing.](https://i.stack.imgur.com/gVcgW.png)](https://i.stack.imgur.com/gVcgW.png)
In text form:
```
# # # # # # # # #
# # # # # # # # #
# # + + + + + # #
# # + X X X + # #
# # + X X X + # #
# # + + + + + # #
# # # # # # # # #
# # # # # # # # #
```
The winning code completes the conditions in the least possible bytes. 
  
[Answer]
# [Python 2](https://docs.python.org/2/), 98 bytes
```
w,h,a,b=input()
a*='+'
b*='#'
for c in b+a+h*'X'+a+b:print' '.join(min(c,d)for d in b+a+w*'X'+a+b)
```
[Try it online!](https://tio.run/##NcqxCoAgFEDR3a8QGp7mI8i2oP9o1SQ06ClhSF9vNjRc7nLSk30kXWtBjwbtEijdWUhm@gUUMNvWAdvjxTceiFtllO9hhXY7pytQBg7DEQOJs7Whkx92Py4/lrVOqHFE/QI "Python 2 – Try It Online")
Prints a space-separated grid, strictly following the spec. I'm amused that `*=` is used to convert `a` and `b` from numbers to strings.
Python 3 can save some bytes by avoiding `' '.join`, maybe more by using f-strings and assignment expressions. Thanks to Jo King for -2 bytes.
**[Python 3](https://docs.python.org/3/), 93 bytes**
```
def f(w,h,a,b):a*='+';b*='#';[print(*[min(c,d)for d in b+a+w*'X'+a+b])for c in b+a+h*'X'+a+b]
```
[Try it online!](https://tio.run/##Pci7CoAgFADQXxEaro@7pFvRfwTR4CPRIRMJoq83CWo6cPJ9hiOpWt3miacXBtRo2KD5BAJG0@hgXHKJ6aR82WOiFh3zRyGOxESM0OLiMEPTrO/b78P/1VOFEnuUrD4 "Python 3 – Try It Online")
[Answer]
# JavaScript (ES6), ~~118 113~~ 107 bytes
```
(w,h,M,F)=>(g=(c,n)=>'01210'.replace(/./g,i=>c(i).repeat([F,M,n][i])))(y=>g(x=>'#+X'[x<y?x:y]+' ',w)+`
`,h)
```
[Try it online!](https://tio.run/##VcuxCoMwFEDRvV9R6JD38FWNpUtp7ObWvSCCIY0xRRJRqfr1qY7dLgfuR37lqAbbT2fn3zo0IsBMLT2pQJGDEaDIbcVSnvGUxYPuO6k0JHFiyIpcgcUdtZygLLbNVaWtEBFWkRtYtvMUvVi53NfHcluriB0ZzRjVh5paDMq70Xc67ryBBi6UEacM8fDv112JI4Yf "JavaScript (Node.js) – Try It Online")
### Commented
```
(w, h, M, F) => (       // given the 4 input variables
  g = (                 // g = helper function taking:
    c,                  //   c = callback function returning a string to repeat
    n                   //   n = number of times the painting part must be repeated
  ) =>                  //
    '01210'             // string describing the picture structure, with:
    .replace(           //   0 = frame, 1 = matte, 2 = painting
      /./g,             // for each character in the above string:
      i =>              //   i = identifier of the current area
        c(i)            //   invoke the callback function
        .repeat         //   and repeat the result ...
        ([F, M, n][i])  //   ... either F, M or n times
    )                   // end of replace()
)(                      // outer call to g:
  y =>                  //   callback function taking y:
    g(                  //     inner call to g:
      x =>              //       callback function taking x:
        '#+X'           //         figure out which character to use
        [x < y ? x : y] //         according to the current position
        + ' ',          //         append a space
      w                 //       repeat the painting part w times
    )                   //     end of inner call
    + '\n',             //     append a line feed
  h                     //   repeat the painting part h times
)                       // end of outer call
```
[Answer]
# [MATL](https://github.com/lmendo/MATL), 24 bytes
```
&l,ithYaQ]'#+X'w)TFX*cYv
```
Input is: Height, Width, Matte Width, Frame Width.
[Try it online!](https://tio.run/##y00syfn/Xy1HJ7MkIzIxMFZdWTtCvVwzxC1CKzmy7P9/Iy5jLkMuIwA)
### Explanation
```
&l      % Take height and width implicitly. Push matrix of that size with all
        % entries equal to 1
,       % Do twice
  i     %   Take input
  th    %   Duplicate, concatenate: gives a 1×2 vector with the number repeated
  Ya    %   Pad matrix with those many zeros vertically and horizontally
  Q     %   Add 1 to each entry 
]       % End
'#+X'   % Push this string
w)      % Index into the string with the padded matrix
TF      % Push row vector [1 0]
X*      % Kronecker product. This inserts columns of zeros
c       % Convert to char again. Char 0 is will be displayed as space
Yv      % Remove trailing spaces in each line. Implicitly display
```
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 142 bytes
```
(t=(p=Table)["# ",2(c=#4+#3)+#2,2c+#];p[t[[i,j]]="+ ",{j,z=#4+1,c+#3+#},{i,z,c+#3+#2}];p[t[[i,j]]="X ",{j,#3+z,c+#},{i,#3+z,c+#2}];""<>#&/@t)&
```
[Try it online!](https://tio.run/##VcuxCsIwFIXhVym5UBJyofTGTSN9BAcHIWSIodSUVopkaumzx7Tq4Hj4vzO6@GhHF4N3qdOJR80nfXX3oRWGQcGQuNdwkKCEBELyEuxxMtGYgL21mslslh7nDdWYs5Kw4hJw/g5a/w@3zyGnXez2NzbL2OkMZdVEUabLKzxjUTVFZxQS1kg2pTc "Wolfram Language (Mathematica) – Try It Online")
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), ~~48~~ ~~47~~ 44 bytes
```
≔×ＮXθ≔×ＮXηＦＥ+#×Ｎι«≔⁺ι⁺θιθ≔⁺ι⁺ηιη»Ｅη⪫⭆θ⌊⟦ιλ⟧ 
```
[Try it online!](https://tio.run/##hY2xDoIwEIZneYpLXa4RB3FkctQEQ6KDiXFAgnJJW6ClLsZnrwcykrjcJf99/31lXdiyKVQIO@foafBMunK4N63vj17fK4syBnERPDuZRv@pmqlHYwGzokWxWooYZmmSUsI7Wkwfc@UdUgzj7sbzzzgL1BMwyD5Rbsn0o4/zQ0MGTz1HzyHhVxkZ0l7jldvqNtQECLanIWwhgQ0kYf1SXw "Charcoal – Try It Online") Link is to verbose version of code. Note: Trailing space. Edit: Now uses @xnor's algorithm. Explanation:
```
≔×ＮXθ≔×ＮXη
```
Input the width and height and convert them into strings of `X`s.
```
ＦＥ+#×Ｎι
```
Loop over the characters `+` and `#`, converting them into strings of length given by the remaining two inputs. Then loop over those two strings.
```
«≔⁺ι⁺θιθ≔⁺ι⁺ηιη»
```
Prefix and suffix the painting with the strings for the matting and framing.
```
Ｅη⪫⭆θ⌊⟦ιλ⟧ 
```
Loop over the strings, taking the minimum of the horizontal and vertical characters, and then double-spacing the rows, implicitly printing each row on its own line.
[Answer]
# [05AB1E (legacy)](https://github.com/Adriandmen/05AB1E/wiki/Commands) / [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands) `--no-lazy`, ~~32~~ 31 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
и'X×„+#vyI©×UεX.ø}®FDнgy×.ø]€S»
```
Takes the input in the order `height, width, matte, frame`. If the input order specified in the challenge is strict (still waiting on OP for verification), a leading `s` (swap) can be added for +1 byte.
Required the `--no-lazy` Elixir compiler flag in the new version of 05AB1E, since Elixir has some odd behavior due to lazy evaluation for nested maps/loops ([here the result without this flag](https://tio.run/##AT8AwP9vc2FiaWX//9C4J1jDl@KAnisjdnlJwqnDl1XOtVguw7h9wq5GRNC9Z3nDly7DuF3igqxTwrv//zMKNwozCjI)).
[Try it online in the legacy version of 05AB1E.](https://tio.run/##AT8AwP8wNWFiMWX//9C4J1jDl@KAnisjdnlJwqnDl1XOtVguw7h9wq5GRNC9Z3nDly7DuF3igqxTwrv//zMKNwozCjI)  
[Try it online in the new version of 05AB1E with added `--no-lazy` flag.](https://tio.run/##AUkAtv9vc2FiaWX//9C4J1jDl@KAnisjdnlJwqnDl1XOtVguw7h9wq5GRNC9Z3nDly7DuF3igqxTwrv//zMKNwozCjL/LS1uby1sYXp5)
**Explanation:**
```
и              # Repeat the second (implicit) input the first (implicit) input amount of
               # times as list
 'X×          '# Repeat "X" that many times
„+#v           # Loop `y` over the characters ["+","#"]:
    y          #  Push character `y`
     I         #  Push the next input (matte in the first iteration; frame in the second)
      ©        #  And store it in the register (without popping)
       ×       #  Repeat character `y` that input amount of times
        U      #  Pop and store that string in variable `X`
    εX.ø}      #  Surround each string in the list with string `X`
    ®F         #  Inner loop the value from the register amount of times:
      Dнg      #   Get the new width by taking the length of the first string
         y×    #   Repeat character `y` that many times
           .ø  #   And surround the list with this leading and trailing string
   ]           # Close both the inner and outer loops
    €S         # Convert each inner string to a list of characters
      »        # Join every list of characters by spaces, and then every string by newlines
               # (and output the result implicitly)
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 17 bytes
```
;ŒB“#+X+#”xʋⱮ«Ɱ/G
```
[Try it online!](https://tio.run/##y0rNyan8/9/66CSnRw1zlLUjtJUfNcytONX9aOO6Q6uBhL77////o410FAxj/0cb6ygYxQIA "Jelly – Try It Online")
Argument 1: `[Frame width, Matte width]`  
Argument 2: `[Width, Height]`
[Answer]
# [Canvas](https://github.com/dzaima/Canvas), 24 [bytes](https://github.com/dzaima/Canvas/blob/master/files/chartable.md)
```
Ｘ；«［ｌｘ＊ｅ⤢｝
X×＊+⁸#⁸ ＊Ｊ ×Ｏ
```
[Try it here!](https://dzaima.github.io/Canvas/?u=JXVGRjM4JXVGRjFCJUFCJXVGRjNCJXVGRjRDJXVGRjU4JXVGRjBBJXVGRjQ1JXUyOTIyJXVGRjVEJTBBWCVENyV1RkYwQSsldTIwNzglMjMldTIwNzglMjAldUZGMEEldUZGMkElMjAlRDcldUZGMkY_,i=MyUwQTIlMEExJTBBMg__,v=8)
Should be 5 bytes shorter, but isn't because Canvas is buggy..
[Answer]
# [R](https://www.r-project.org/), 119 bytes
```
function(w,h,m,f)write(Reduce(function(x,y)rbind(y,cbind(y,x,y),y),rep(c("+","#"),c(m,f)),matrix("X",w,h)),1,w+2*f+2*m)
```
[Try it online!](https://tio.run/##PYzBCsIwEER/RdbLrp0ejFe/wpPXmiY1h0RZUtJ@fUygCDMMvIGndTndx@rXZHP4JC54I8JL0ZAdP9y8Wsf/d8Mu@gpp5h322M561H3ZMg0EOpPActcI4pQ1bExPQnM3cEUZzMW3RqkL32AaMlJ/ "R – Try It Online")
[Answer]
# [Python 3.8 (pre-release)](https://docs.python.org/3.8/), ~~116~~ ~~115~~ 113 bytes
```
lambda a,b,c,d:"\n".join((g:=['#'*(a+2*c+2*d)]*d+[(h:='#'*d)+'+'*(a+c*2)+h]*c)+[h+'+'*c+'X'*a+'+'*c+h]*b+g[::-1])
```
[Try it online!](https://tio.run/##LYnLCsMgEEV/JaQLZxxbiNkUwf8oGBc@QkxpjYRs@vXWhi7u4XJO@Rxpy@O97HXWU325t4@uc8KLIKLqp9zfntuaARalDbswDo4kD20RLY9kICn98xGJ0ZkDl0jJ8oBk0ikDsQfj7v9b8rQYpa6DxVr2NR8wwyg6KbqhEbF@AQ "Python 3.8 (pre-release) – Try It Online")
First attempt at golfing, will be improved soon.
`a` is width, `b` is height, `c` is matte width, and `d` is frame width.
*-1 bytes using the `:=` operator to define `h` as `e * d`*
*-2 bytes thanks to Jo King suggesting me to remove the e and f parameters*
**EXPLANATION:**
```
lambda a,b,c,d:          Define a lambda which takes in arguments a, b, c, and d (The width of the painting, the height of the painting, the padding of the matte, and the padding of the frame width, respectively).
    "\n".join(                       Turn the list into a string, where each element is separated by newlines
        (g:=                         Define g as (while still evaling the lists)...
            ['#'*(a+2*c+2*d)]*d+       Form the top rows (the ones filled with hashtags)
            [(h:='#'*d)+'+'*(a+c*2)+h]*c Form the middle-top rows (uses := to golf this section)
        )+
        [h+'+'*c+'X'*a+'+'*c+h]*b+       Form the middle row
        g[::-1]                      Uses g to golf the code (forms the entire middle-bottom-to-bottom)
    )
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~35~~ ~~31~~ ~~28~~ 24 bytes
```
Dịx@“#+X+#”
⁽-Fç«þ⁽-ȥç$G
```
[Try it online!](https://tio.run/##y0rNyan8/9/l4e7uCodHDXOUtSO0lR81zOV61LhX1@3w8kOrD@8DMU8sPbxcxf3///9GOiY6ZjpGAA "Jelly – Try It Online")
Takes the input in the order frame, matte, width, height; comma separated. Outputs the ASCII-art picture with frame and matte. If the input order is strict I’d need to add more bytes (as per my original post). 
Couple of golfs based on @EriktheOutgolfer’s answer; I’d realised the characters were in ASCII order but hadn’t thought how best to take advantage of that, and had forgotten about `G`. His is still a better answer though!
[Answer]
# [Husk](https://github.com/barbuz/Husk), ~~29~~ 25 bytes
```
mm;₁'#⁰₁'+²RR'X
‼‼(m↔Tm+R
```
[Try it online!](https://tio.run/##yygtzv7/PzfX@lFTo7ryo8YNIFr70KagIPUIrkcNe4BII/dR25SQXO2g////G/43@m/83wgA "Husk – Try It Online")
Ah, this was convoluted.
The input order is `Matte,Frame,Width,Height`.
-4 bytes after simplifying function 2 & 3.
## Explanation
```
Function ₁: framing function
‼‼(m↔Tm+R parameters a(char),n(int),m(matrix)
      m+R add a side
     T    Transpose
   m↔     reverse each row
‼‼(       repeat that 3 more times
Function ₀: main
mm;₁'#⁰₁'+²RR'X 
           RR'X make width × height matrix of 'X'es
       ₁'+²     add the matte of '+'es
   ₁'#⁰         add the frame of '#'es
mm;             nest each character(adds spaces)
```
[Answer]
# Javascript, 158 bytes
```
(w,h,m,f)=>(q="repeat",(z=("#"[q](w+2*(m+f)))+`
`)[q](f))+(x=((e="#"[q](f))+(r="+"[q](m))+(t="+"[q](w))+r+e+`
`)[q](m))+(e+r+"X"[q](w)+r+e+`
`)[q](h)+x+z)
```
Can probably be trimmed down a little bit
```
f=
(w,h,m,f)=>(q="repeat",(z=("# "[q](w+2*(m+f))+`
`)[q](f))+(x=((e="# "[q](f))+(r="+ "[q](m))+(t="+ "[q](w))+r+e+`
`)[q](m))+(e+r+"X "[q](w)+r+e+`
`)[q](h)+x+z)
console.log(f(3,2,1,2))
```
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), 98 bytes
```
{map(&min,[X] map (($_='#'x$^d~'+'x$^c)~'X'x*~.flip).comb,$^a,$^b).rotor($b+2*($c+$d)).join("\n")}
```
[Try it online!](https://tio.run/##JYfRCoIwFEDf@4qxhrtXx8AJvYj/IVTGpg0mzon1oET@@lLicDic6TkPl@hXklhSkfjxeoLEu1Fc6zvZhwCwR8XPfGFNt/HsaIsbr/mSbtIObkLZBm8Ea/SuQTmHd5iBmUylwNqMdYiyD24EehspfuNLr8RCIZTIhcLydDyl/1pQotjJsYw/ "Perl 6 – Try It Online")
This is a port of [xnor's Python answer](https://codegolf.stackexchange.com/a/181785/76162).
# [Perl 6](https://github.com/nxadm/rakudo-pkg), 115 bytes
```
->\a,\b,\c,\d{$_=['#'xx$!*2+a]xx($!=c+d)*2+b;.[d..^*-d;d..^a+$!+c]='+'xx*;.[$!..^*-$!;$!..^a+$!]='X'xx*;.join("
")}
```
[Try it online!](https://tio.run/##JcvLCsIwEAXQfb8iicHmMS00BTchfofQVEkbC4ovdJMifntMWmZx7@Uwr/P7tov3GW0nZFCs9taBHcCOYP2XnkxXbsoQKBZKuj4ERrEZpedpDrrufF0fReV1TicplmNvSpkeREKKF6VYLy170sOq1@flwUhB@C9@3Iwm1oKCBhTXRd6ErDkxBW26huv4Bw "Perl 6 – Try It Online")
Roughly golfed anonymous codeblock utilising Perl 6's multi-dimensional list assignment. For example, `@a[1;2] = 'X';` will assign `'X'` to the element with index 2 from the list with index 1, and `@a[1,2,3;3,4,5]='X'xx 9;` will replace all the elements with indexes `3,4,5` of the lists with indexes `1,2,3` with `'X'`. 
### Explanation:
First, we initialise the list as a `a+2*(c+d)` by `b+2*(c+d)` rectangle of `#`s.
```
$_=['#'xx$!*2+a]xx($!=c+d)*2+a;
State:
# # # # # # # # #
# # # # # # # # #
# # # # # # # # #
# # # # # # # # #
# # # # # # # # #
# # # # # # # # #
# # # # # # # # #
# # # # # # # # #
```
Then we assign the inner rectangle of `+`s
```
.[d..^*-d;d..^a+$!+c]='+'xx*;
State:
# # # # # # # # #
# # # # # # # # #
# # + + + + + # #
# # + + + + + # #
# # + + + + + # #
# # + + + + + # #
# # # # # # # # #
# # # # # # # # #
```
Finally, the innermost rectangle of `X`s.
```
.[$!..^*-$!;$!..^a+$!]='X'xx*;
# # # # # # # # #
# # # # # # # # #
# # + + + + + # #
# # + X X X + # #
# # + X X X + # #
# # + + + + + # #
# # # # # # # # #
# # # # # # # # #
```
[Answer]
# Perl 5, 115 bytes
```
$_=(X x$F[0].$/)x$F[1];sub F{s,^|\z,/.*/;$_[0]x"@+".$/,ge,s/^|(?=
)/$_[0]/gm while$_[1]--}F('+',$F[2]);F('#',$F[3])
```
[TIO](https://tio.run/##K0gtyjH9/18l3lYjQqFCxS3aIFZPRV8TxDKMtS4uTVJwqy7WiauJqdLR19PSt1aJB6qoUHLQVgIq00lP1SnWj6vRsLfl0tQHS@mn5yqUZ2TmpAJ5hrG6urVuGura6jpA44xiNa2BHGUwxzhW8/9/YwUjBUMFIy5DBRMgy@hffkFJZn5e8X/dxIIcAA)
[Answer]
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), 132 bytes
```
param($w,$h,$m,$f)filter l{"$(,'#'*$f+,$_[0]*$m+,$_[1]*$w+,$_[0]*$m+,'#'*$f)"}($a=@('##'|l)*$f)
($b=@('++'|l)*$m)
@('+X'|l)*$h
$b
$a
```
[Try it online!](https://tio.run/##TcrBCgIhFIXhvU8h4wF1vIuamGXQYwQR4YBioDRY4KJ6dsvctPvPx1lvxeV7cDHWutpsk0IhBEIieO2v8eEyj88BiqSQI7whXE6b84j0q@23yr/1lx7eCnZ/UFII@Yq6EVNYmhjTJWnW1rGvwLAw2FrrzCe@49MH "PowerShell – Try It Online")
]