@@ -29,12 +29,12 @@ public partial class MainWindow : Window, INotifyPropertyChanged
2929 int canvasResolutionY = 16 ;
3030 int paletteResolutionX = 4 ;
3131 int paletteResolutionY = 16 ;
32- int canvasScaleX = 1 ;
32+ float canvasScaleX = 1 ;
3333 int paletteScaleX = 1 ;
3434 int paletteScaleY = 1 ;
3535 int dpiX = 96 ;
3636 int dpiY = 96 ;
37- byte gridAlpha = 16 ;
37+ byte gridAlpha = 32 ;
3838
3939 // simple undo
4040 Stack < WriteableBitmap > undoStack = new Stack < WriteableBitmap > ( ) ;
@@ -53,14 +53,9 @@ public partial class MainWindow : Window, INotifyPropertyChanged
5353 int prevY ;
5454
5555 // drawing lines
56- bool firstPixel = true ;
57- int startPixelX = 0 ;
58- int startPixelY = 0 ;
59- bool verticalLine = false ;
60- bool horizontalLine = false ;
61- bool diagonalLine = false ;
62- int lockedX = 0 ;
63- int lockedY = 0 ;
56+ bool leftShiftDown = false ;
57+ private readonly int ddaMODIFIER_X = 0x7fff ;
58+ private readonly int ddaMODIFIER_Y = 0x7fff ;
6459
6560 // smart fill with double click
6661 bool wasDoubleClick = false ;
@@ -105,8 +100,7 @@ public bool IsModified
105100 {
106101 window . Title = window . Title + "*" ;
107102 }
108- }
109- else // not modified, remove mark
103+ } else // not modified, remove mark
110104 {
111105 if ( window . Title . IndexOf ( "*" ) > - 1 )
112106 {
@@ -143,7 +137,7 @@ void Start()
143137 // build drawing area
144138 canvasBitmap = new WriteableBitmap ( canvasResolutionX , canvasResolutionY , dpiX , dpiY , PixelFormats . Bgra32 , null ) ;
145139 drawingImage . Source = canvasBitmap ;
146- canvasScaleX = ( int ) drawingImage . Width / canvasResolutionX ;
140+ canvasScaleX = ( float ) drawingImage . Width / ( float ) canvasResolutionX ;
147141
148142 // setup outline bitmap
149143 outlineBitmap = new WriteableBitmap ( canvasResolutionX , canvasResolutionY , dpiX , dpiY , PixelFormats . Bgra32 , null ) ;
@@ -199,71 +193,6 @@ void DrawPixel(int x, int y)
199193 if ( x < 0 || x > canvasResolutionX - 1 ) return ;
200194 if ( y < 0 || y > canvasResolutionY - 1 ) return ;
201195
202- // is using straight lines
203- if ( leftShiftDown == true )
204- {
205- // get first pixel, to measure direction
206- if ( firstPixel == true )
207- {
208- startPixelX = x ;
209- startPixelY = y ;
210- firstPixel = false ;
211- }
212- else // already drew before
213- {
214- // have detected linemode
215- if ( horizontalLine == false && verticalLine == false && diagonalLine == false )
216- {
217- // vertical
218- if ( x == startPixelX && y != startPixelY )
219- {
220- verticalLine = true ;
221- lockedX = x ;
222- }
223- // horizontal
224- else if ( y == startPixelY && x != startPixelX )
225- {
226- horizontalLine = true ;
227- lockedY = y ;
228- }
229- // diagonal
230- else if ( y != startPixelY && x != startPixelX )
231- {
232- diagonalLine = true ;
233- }
234- }
235-
236- // lock coordinates if straight lines
237- if ( verticalLine == true )
238- {
239- x = lockedX ;
240- }
241- else if ( horizontalLine == true )
242- {
243- y = lockedY ;
244- }
245- else if ( diagonalLine == true )
246- {
247- // force diagonal
248- int xx = x - startPixelX ;
249- int yy = y - startPixelY ;
250-
251- // stop drawing, if not in diagonal cell
252- if ( Math . Abs ( xx ) - Math . Abs ( yy ) != 0 )
253- {
254- return ;
255- }
256- }
257- }
258- }
259- else // left shift not down
260- {
261- verticalLine = false ;
262- horizontalLine = false ;
263- diagonalLine = false ;
264- firstPixel = true ;
265- }
266-
267196 PixelColor draw = new PixelColor ( ) ;
268197
269198 switch ( blendMode )
@@ -472,8 +401,7 @@ void DrawingLeftButtonDown(object sender, MouseButtonEventArgs e)
472401 previousToolMode = CurrentTool ;
473402 CurrentTool = ToolMode . Fill ;
474403 wasDoubleClick = true ;
475- }
476- else // keep old color
404+ } else // keep old color
477405 {
478406 previousPixelColor = GetPixel ( x , y ) ;
479407 }
@@ -482,7 +410,18 @@ void DrawingLeftButtonDown(object sender, MouseButtonEventArgs e)
482410 switch ( CurrentTool )
483411 {
484412 case ToolMode . Draw :
413+
414+ // check if shift is down, then do line to previous point
415+ if ( leftShiftDown == true )
416+ {
417+ //DrawLine(prevX, prevY, x, y);
418+ DrawLine ( prevX , prevY , x , y ) ;
419+ }
420+
485421 DrawPixel ( x , y ) ;
422+ prevX = x ;
423+ prevY = y ;
424+
486425 // mirror
487426 if ( chkMirrorX . IsChecked == true )
488427 {
@@ -569,17 +508,15 @@ void DrawingAreaMouseMoved(object sender, MouseEventArgs e)
569508 break ;
570509 }
571510
572- }
573- else if ( e . RightButton == MouseButtonState . Pressed )
511+ } else if ( e . RightButton == MouseButtonState . Pressed )
574512 {
575513 ErasePixel ( x , y ) ;
576514 // mirror
577515 if ( chkMirrorX . IsChecked == true )
578516 {
579517 ErasePixel ( canvasResolutionX - x , y ) ;
580518 }
581- }
582- else if ( e . MiddleButton == MouseButtonState . Pressed )
519+ } else if ( e . MiddleButton == MouseButtonState . Pressed )
583520 {
584521 currentColor = GetPixel ( x , y ) ;
585522 ResetCurrentBrightnessPreview ( currentColor ) ;
@@ -594,11 +531,13 @@ void DrawingAreaMouseMoved(object sender, MouseEventArgs e)
594531 }
595532
596533 // snap preview rectangle to grid
597- var left = x * canvasScaleX ;
598- var top = y * canvasScaleX ;
534+ int fix = 256 / canvasResolutionX ;
535+ var off = ( ( float ) 256 / ( float ) canvasResolutionX ) - fix ;
536+ var left = x * canvasScaleX + ( ( x * ( 16 / canvasResolutionX ) ) * ( off > 0 ? 1 : 0 ) ) ;
537+ var top = y * canvasScaleX + ( ( y * ( 16 / canvasResolutionY ) ) * ( off > 0 ? 1 : 0 ) ) ;
538+
599539 // NOTE: this causes palette pixels to distort/move?
600540 rectPixelPos . Margin = new Thickness ( 89 + left , 50 + top , 0 , 0 ) ;
601-
602541 } // drawingareamousemoved
603542
604543 void ShowMousePos ( int x , int y )
@@ -701,8 +640,7 @@ private void OnSaveButton(object sender, RoutedEventArgs e)
701640 {
702641 SaveImageAsPng ( saveFile ) ;
703642 IsModified = false ;
704- }
705- else // save as
643+ } else // save as
706644 {
707645 if ( saveFileDialog . ShowDialog ( ) == true )
708646 {
@@ -751,7 +689,7 @@ private void OnModeSelectionChanged(object sender, SelectionChangedEventArgs e)
751689 blendMode = ( BlendMode ) s . SelectedIndex ;
752690 }
753691
754- bool leftShiftDown = false ;
692+
755693
756694 // if key is pressed down globally
757695 void OnKeyDown ( object sender , KeyEventArgs e )
@@ -807,10 +745,6 @@ private void OnKeyUp(object sender, KeyEventArgs e)
807745 case Key . LeftShift :
808746 lblToolInfo . Content = "" ;
809747 leftShiftDown = false ;
810- verticalLine = false ;
811- horizontalLine = false ;
812- diagonalLine = false ;
813- firstPixel = true ;
814748 break ;
815749 default :
816750 break ;
@@ -1097,13 +1031,11 @@ void UpdateOutline()
10971031 if ( centerPix == 0 )
10981032 {
10991033 c . Alpha = 255 ;
1100- }
1101- else
1034+ } else
11021035 {
11031036 c . Alpha = 0 ;
11041037 }
1105- }
1106- else
1038+ } else
11071039 {
11081040 c . Alpha = 0 ;
11091041 }
@@ -1198,8 +1130,7 @@ private void chkOutline_Click(object sender, RoutedEventArgs e)
11981130 if ( chkOutline . IsChecked == true )
11991131 {
12001132 UpdateOutline ( ) ;
1201- }
1202- else // clear
1133+ } else // clear
12031134 {
12041135 ClearImage ( outlineBitmap , emptyRect , emptyPixels , emptyStride ) ;
12051136 }
@@ -1301,6 +1232,119 @@ private void OnHueRectangleMouseMoved(object sender, MouseEventArgs e)
13011232 if ( rectHueBar . IsMouseOver == false ) return ;
13021233 if ( e . LeftButton == MouseButtonState . Pressed ) rectHueBar_MouseDown ( null , null ) ;
13031234 }
1235+
1236+
1237+ private void DrawLine ( int startX , int startY , int endX , int endY )
1238+ {
1239+ int dx = endX - startX ;
1240+ int dy = endY - startY ;
1241+
1242+ int nx = Math . Abs ( dx ) ;
1243+ int ny = Math . Abs ( dy ) ;
1244+
1245+ // Calculate octant value
1246+ int octant = ( ( dy < 0 ) ? 4 : 0 ) | ( ( dx < 0 ) ? 2 : 0 ) | ( ( ny > nx ) ? 1 : 0 ) ;
1247+ int move = 0 ;
1248+ int frac = 0 ;
1249+ int mn = Math . Max ( nx , ny ) ;
1250+
1251+ if ( mn == 0 )
1252+ {
1253+ //yield return new Coord(startX, startY);
1254+ //yield break;
1255+ return ;
1256+ }
1257+
1258+ if ( ny == 0 )
1259+ {
1260+ if ( dx > 0 )
1261+ for ( int x = startX ; x <= endX ; x ++ )
1262+ DrawPixel ( x , startY ) ;
1263+ //yield return new Coord(x, startY);
1264+ else
1265+ for ( int x = startX ; x >= endX ; x -- )
1266+ DrawPixel ( x , startY ) ;
1267+ //yield return new Coord(x, startY);
1268+
1269+ //yield break;
1270+ return ;
1271+ }
1272+
1273+ if ( nx == 0 )
1274+ {
1275+ if ( dy > 0 )
1276+ for ( int y = startY ; y <= endY ; y ++ )
1277+ DrawPixel ( startX , y ) ;
1278+ //yield return new Coord(startX, y);
1279+ else
1280+ for ( int y = startY ; y >= endY ; y -- )
1281+ DrawPixel ( startX , y ) ;
1282+ // yield return new Coord(startX, y);
1283+
1284+ // yield break;
1285+ return ;
1286+ }
1287+
1288+ switch ( octant )
1289+ {
1290+ case 0 : // +x, +y
1291+ move = ( ny << 16 ) / nx ;
1292+ for ( int primary = startX ; primary <= endX ; primary ++ , frac += move )
1293+ //yield return new Coord(primary, startY + ((frac + MODIFIER_Y) >> 16));
1294+ DrawPixel ( primary , startY + ( ( frac + ddaMODIFIER_Y ) >> 16 ) ) ;
1295+ break ;
1296+
1297+ case 1 :
1298+ move = ( nx << 16 ) / ny ;
1299+ for ( int primary = startY ; primary <= endY ; primary ++ , frac += move )
1300+ //yield return new Coord(startX + ((frac + MODIFIER_X) >> 16), primary);
1301+ DrawPixel ( startX + ( ( frac + ddaMODIFIER_X ) >> 16 ) , primary ) ;
1302+ break ;
1303+
1304+ case 2 : // -x, +y
1305+ move = ( ny << 16 ) / nx ;
1306+ for ( int primary = startX ; primary >= endX ; primary -- , frac += move )
1307+ // yield return new Coord(primary, startY + ((frac + MODIFIER_Y) >> 16));
1308+ DrawPixel ( primary , startY + ( ( frac + ddaMODIFIER_Y ) >> 16 ) ) ;
1309+ break ;
1310+
1311+ case 3 :
1312+ move = ( nx << 16 ) / ny ;
1313+ for ( int primary = startY ; primary <= endY ; primary ++ , frac += move )
1314+ // yield return new Coord(startX - ((frac + MODIFIER_X) >> 16), primary);
1315+ DrawPixel ( startX - ( ( frac + ddaMODIFIER_X ) >> 16 ) , primary ) ;
1316+ break ;
1317+
1318+ case 6 : // -x, -y
1319+ move = ( ny << 16 ) / nx ;
1320+ for ( int primary = startX ; primary >= endX ; primary -- , frac += move )
1321+ // yield return new Coord(primary, startY - ((frac + MODIFIER_Y) >> 16));
1322+ DrawPixel ( primary , startY - ( ( frac + ddaMODIFIER_Y ) >> 16 ) ) ;
1323+ break ;
1324+
1325+ case 7 :
1326+ move = ( nx << 16 ) / ny ;
1327+ for ( int primary = startY ; primary >= endY ; primary -- , frac += move )
1328+ // yield return new Coord(startX - ((frac + MODIFIER_X) >> 16), primary);
1329+ DrawPixel ( startX - ( ( frac + ddaMODIFIER_X ) >> 16 ) , primary ) ;
1330+ break ;
1331+
1332+ case 4 : // +x, -y
1333+ move = ( ny << 16 ) / nx ;
1334+ for ( int primary = startX ; primary <= endX ; primary ++ , frac += move )
1335+ // yield return new Coord(primary, startY - ((frac + MODIFIER_Y) >> 16));
1336+ DrawPixel ( primary , startY - ( ( frac + ddaMODIFIER_Y ) >> 16 ) ) ;
1337+ break ;
1338+
1339+ case 5 :
1340+ move = ( nx << 16 ) / ny ;
1341+ for ( int primary = startY ; primary >= endY ; primary -- , frac += move )
1342+ DrawPixel ( startX + ( ( frac + ddaMODIFIER_X ) >> 16 ) , primary ) ;
1343+ // yield return new Coord(startX + ((frac + MODIFIER_X) >> 16), primary);
1344+ break ;
1345+ }
1346+ }
1347+
13041348 } // class
13051349
13061350} // namespace
0 commit comments