#JavaScript (ES6) 163124 177163 177
Edit Totally different way, no need of an array to store visited cells. Using the fact that the side of the spiral increase of 1 after every 2 turns.
// GolfedNew way
f=(h,w,y,x)=>
(e=>{
for(o=[],d=i=t=l=0;l<w*h;i<t?i+=2:[i,d,e]=[1,-e,d,++t])
o[l]=y*w-w+x,l+=x>0&x<=w&y>0&y<=h,x+=d,y-=e
})(1)||o
// Golfed
g=(h,w,y,x)=>
(g=>{
for(e=n=0;n<h*w;)g[[n%w+1,-~(n/w)]]=++n;
for(o=[g[[x,y]]],l=d=1;l<n;l+=!!(o[l]=g[[x+=d,y+=e]]))
g[[x,y]]=0,
g[[x+e,y-d]]!=0&&([d,e]=[e,-d])
})([])||o
// Not golfed
u=(h,w,y,x)=>{
var i,j,dx,dy,kx,ky,o,n,
g={} // simulate a 2dimensional array using a hashtable with keys in the form 'x,y'
for(n=i=0; i++<h;) // fill grid (probably better done in a single loop)
for(j=0; j++<w;)
g[[j,i]] = ++n;
o=[g[[x,y]]] // starting point in output
dx=1, dy=0 // start headed right
for(; !o[w*h-1]; ) // loop until all w*h position are put in output
{
g[[x, y]] = 0 // mark current position to avoid reusing
kx=dy, ky=-dx // try turning left
if(g[[x+kx, y+ky]] != 0) // check if position marked
{ // found a valid position
dx=kx, dy=ky // change direction
}
x+=dx, y+=dy // move
k=g[[x, y]] // get current value
if (k) o.push(k) // put in output list if not 'undefined' (outside grid)
}
return o
}
// TEST - In FireFox
out=x=>O.innerHTML+=x+'\n';
[
[[5,5,3,3],'13 8 7 12 17 18 19 14 9 4 3 2 1 6 11 16 21 22 23 24 25 20 15 10 5'],
[[2,4,1,2],'2 1 5 6 7 3 8 4']
].forEach(t=>out(t[0] + '\n Result: ' + f(...t[0])+'\n Check: ' + t[1]))
test=()=>
{
var r, i=I.value.match(/\d+/g), h=i[0]|0, w=i[1]|0, y=i[2]|0, x=i[3]|0
if (y>h||x>w) r = 'Invalid input'
else r = f(h,w,y,x)
out(i+'\n Reault: ' +r)
}
<pre id=O></pre>
Your test:<input id=I><button onclick="test()">-></button>