@@ -27,7 +27,9 @@ import android.graphics.Paint
2727import  android.graphics.PointF 
2828import  android.graphics.Typeface 
2929import  android.widget.EditText 
30+ import  android.widget.RelativeLayout 
3031import  androidx.core.content.res.ResourcesCompat 
32+ import  androidx.core.view.isVisible 
3133import  androidx.recyclerview.widget.RecyclerView 
3234import  androidx.test.espresso.Espresso 
3335import  androidx.test.espresso.Espresso.onView 
@@ -61,6 +63,7 @@ import org.catrobat.paintroid.tools.FontType
6163import  org.catrobat.paintroid.tools.ToolReference 
6264import  org.catrobat.paintroid.tools.ToolType 
6365import  org.catrobat.paintroid.tools.implementation.BOX_OFFSET 
66+ import  org.catrobat.paintroid.tools.implementation.DEFAULT_TEXT_OUTLINE_WIDTH 
6467import  org.catrobat.paintroid.tools.implementation.MARGIN_TOP 
6568import  org.catrobat.paintroid.tools.implementation.TEXT_SIZE_MAGNIFICATION_FACTOR 
6669import  org.catrobat.paintroid.tools.implementation.TextTool 
@@ -90,6 +93,8 @@ class TextToolIntegrationTest {
9093    private  var  underlinedToggleButton:  MaterialButton ?  =  null 
9194    private  var  italicToggleButton:  MaterialButton ?  =  null 
9295    private  var  boldToggleButton:  MaterialButton ?  =  null 
96+     private  var  outlineToggleButton:  MaterialButton ?  =  null 
97+     private  var  outlineWidthLayout:  RelativeLayout ?  =  null 
9398    private  var  textSize:  EditText ?  =  null 
9499    private  var  layerModel:  LayerContracts .Model ?  =  null 
95100    private  lateinit  var  activity:  MainActivity 
@@ -116,6 +121,8 @@ class TextToolIntegrationTest {
116121            activity.findViewById(R .id.pocketpaint_text_tool_dialog_toggle_underlined)
117122        italicToggleButton =  activity.findViewById(R .id.pocketpaint_text_tool_dialog_toggle_italic)
118123        boldToggleButton =  activity.findViewById(R .id.pocketpaint_text_tool_dialog_toggle_bold)
124+         outlineToggleButton =  activity.findViewById(R .id.pocketpaint_text_tool_dialog_toggle_outline)
125+         outlineWidthLayout =  activity.findViewById(R .id.pocketpaint_outline_width_layout)
119126        textSize =  activity.findViewById(R .id.pocketpaint_font_size_text)
120127        textTool?.resetBoxPosition()
121128    }
@@ -125,6 +132,7 @@ class TextToolIntegrationTest {
125132        selectFormatting(FormattingOptions .ITALIC )
126133        selectFormatting(FormattingOptions .BOLD )
127134        selectFormatting(FormattingOptions .UNDERLINE )
135+         selectFormatting(FormattingOptions .OUTLINE )
128136        enterTestText()
129137        onView(withId(R .id.pocketpaint_text_tool_dialog_input_text)).perform(click())
130138        onView(withId(R .id.pocketpaint_text_tool_dialog_input_text)).perform(
@@ -135,12 +143,14 @@ class TextToolIntegrationTest {
135143        italicToggleButton?.let  { Assert .assertTrue(it.isChecked) }
136144        boldToggleButton?.let  { Assert .assertTrue(it.isChecked) }
137145        underlinedToggleButton?.let  { Assert .assertTrue(it.isChecked) }
146+         outlineToggleButton?.let  { Assert .assertTrue(it.isChecked) }
138147        Assert .assertEquals(TEST_TEXT_ADVANCED , textEditText?.text?.toString())
139148        onView(withId(R .id.pocketpaint_text_tool_dialog_input_text)).check(matches(isDisplayed()))
140149        onView(withId(R .id.pocketpaint_text_tool_dialog_list_font)).check(matches(isDisplayed()))
141150        onView(withId(R .id.pocketpaint_text_tool_dialog_toggle_underlined)).check(matches(isDisplayed()))
142151        onView(withId(R .id.pocketpaint_text_tool_dialog_toggle_italic)).check(matches(isDisplayed()))
143152        onView(withId(R .id.pocketpaint_text_tool_dialog_toggle_bold)).check(matches(isDisplayed()))
153+         onView(withId(R .id.pocketpaint_text_tool_dialog_toggle_outline)).check(matches(isDisplayed()))
144154        onView(withId(R .id.pocketpaint_font_size_text)).check(matches(isDisplayed()))
145155    }
146156
@@ -149,13 +159,15 @@ class TextToolIntegrationTest {
149159        selectFormatting(FormattingOptions .ITALIC )
150160        selectFormatting(FormattingOptions .BOLD )
151161        selectFormatting(FormattingOptions .UNDERLINE )
162+         selectFormatting(FormattingOptions .OUTLINE )
152163        enterTestText()
153164        onDrawingSurfaceView()
154165            .perform(UiInteractions .touchAt(DrawingSurfaceLocationProvider .MIDDLE ))
155166
156167        italicToggleButton?.let  { Assert .assertTrue(it.isChecked) }
157168        boldToggleButton?.let  { Assert .assertTrue(it.isChecked) }
158169        underlinedToggleButton?.let  { Assert .assertTrue(it.isChecked) }
170+         outlineToggleButton?.let  { Assert .assertTrue(it.isChecked) }
159171        Assert .assertEquals(TEST_TEXT , textEditText?.text?.toString())
160172        onView(withId(R .id.pocketpaint_text_tool_dialog_input_text))
161173            .check(matches(not (isDisplayed())))
@@ -167,6 +179,8 @@ class TextToolIntegrationTest {
167179            .check(matches(not (isDisplayed())))
168180        onView(withId(R .id.pocketpaint_text_tool_dialog_toggle_bold))
169181            .check(matches(not (isDisplayed())))
182+         onView(withId(R .id.pocketpaint_text_tool_dialog_toggle_outline))
183+             .check(matches(not (isDisplayed())))
170184        onView(withId(R .id.pocketpaint_font_size_text))
171185            .check(matches(not (isDisplayed())))
172186    }
@@ -247,6 +261,8 @@ class TextToolIntegrationTest {
247261        textTool?.let  { Assert .assertFalse(it.underlined) }
248262        textTool?.let  { Assert .assertFalse(it.italic) }
249263        textTool?.let  { Assert .assertFalse(it.bold) }
264+         textTool?.let  { Assert .assertFalse(it.outlined) }
265+         outlineWidthLayout?.let  { Assert .assertFalse(it.isVisible) }
250266    }
251267
252268    @Test
@@ -292,6 +308,20 @@ class TextToolIntegrationTest {
292308        Assert .assertFalse(toolMemberBold)
293309        boldToggleButton?.let  { Assert .assertFalse(it.isChecked) }
294310        Assert .assertEquals(getFormattingOptionAsString(FormattingOptions .BOLD ), boldToggleButton?.text.toString())
311+         selectFormatting(FormattingOptions .OUTLINE )
312+         textTool?.let  { Assert .assertTrue(it.outlined) }
313+         outlineToggleButton?.let  { Assert .assertTrue(it.isChecked) }
314+         Assert .assertEquals(
315+             getFormattingOptionAsString(FormattingOptions .OUTLINE ),
316+             outlineToggleButton?.text.toString()
317+         )
318+         selectFormatting(FormattingOptions .OUTLINE )
319+         textTool?.let  { Assert .assertFalse(it.outlined) }
320+         outlineToggleButton?.let  { Assert .assertFalse(it.isChecked) }
321+         Assert .assertEquals(
322+             getFormattingOptionAsString(FormattingOptions .OUTLINE ),
323+             outlineToggleButton?.text.toString()
324+         )
295325    }
296326
297327    @Test
@@ -301,6 +331,7 @@ class TextToolIntegrationTest {
301331        selectFormatting(FormattingOptions .UNDERLINE )
302332        selectFormatting(FormattingOptions .ITALIC )
303333        selectFormatting(FormattingOptions .BOLD )
334+         selectFormatting(FormattingOptions .OUTLINE )
304335        onToolBarView().performCloseToolOptionsView()
305336
306337        val  oldBoxWidth =  toolMemberBoxWidth
@@ -318,6 +349,7 @@ class TextToolIntegrationTest {
318349        underlinedToggleButton?.let  { Assert .assertTrue(it.isChecked) }
319350        italicToggleButton?.let  { Assert .assertTrue(it.isChecked) }
320351        boldToggleButton?.let  { Assert .assertTrue(it.isChecked) }
352+         outlineToggleButton?.let  { Assert .assertTrue(it.isChecked) }
321353        Assert .assertTrue(oldBoxWidth ==  toolMemberBoxWidth &&  oldBoxHeight ==  toolMemberBoxHeight)
322354    }
323355
@@ -328,6 +360,7 @@ class TextToolIntegrationTest {
328360        selectFormatting(FormattingOptions .UNDERLINE )
329361        selectFormatting(FormattingOptions .ITALIC )
330362        selectFormatting(FormattingOptions .BOLD )
363+         selectFormatting(FormattingOptions .OUTLINE )
331364
332365        val  toolMemberBoxPosition =  toolMemberBoxPosition
333366        val  expectedPosition =  toolMemberBoxPosition?.y?.let  { PointF (toolMemberBoxPosition.x, it) }
@@ -344,6 +377,7 @@ class TextToolIntegrationTest {
344377        underlinedToggleButton?.let  { Assert .assertTrue(it.isChecked) }
345378        italicToggleButton?.let  { Assert .assertTrue(it.isChecked) }
346379        boldToggleButton?.let  { Assert .assertTrue(it.isChecked) }
380+         outlineToggleButton?.let  { Assert .assertTrue(it.isChecked) }
347381        Assert .assertEquals(expectedPosition, toolMemberBoxPosition)
348382        Assert .assertEquals(oldBoxWidth.toDouble(), toolMemberBoxWidth.toDouble(), EQUALS_DELTA )
349383        Assert .assertEquals(oldBoxHeight.toDouble(), toolMemberBoxHeight.toDouble(), EQUALS_DELTA )
@@ -750,6 +784,7 @@ class TextToolIntegrationTest {
750784                selectFormatting(FormattingOptions .ITALIC )
751785                selectFormatting(FormattingOptions .BOLD )
752786                selectFormatting(FormattingOptions .UNDERLINE )
787+                 selectFormatting(FormattingOptions .OUTLINE )
753788            }
754789            val  boxWidth =  toolMemberBoxWidth
755790            val  boxHeight =  toolMemberBoxHeight
@@ -759,10 +794,120 @@ class TextToolIntegrationTest {
759794            selectFormatting(FormattingOptions .ITALIC )
760795            selectFormatting(FormattingOptions .BOLD )
761796            selectFormatting(FormattingOptions .UNDERLINE )
797+             selectFormatting(FormattingOptions .OUTLINE )
762798            Assert .assertTrue(boxWidth <  toolMemberBoxWidth &&  boxHeight <  toolMemberBoxHeight)
763799        }
764800    }
765801
802+     @Test
803+     fun  testTextOutlineMode () {
804+         enterTestText()
805+         val  canvasPoint =  centerBox()
806+         onTopBarView().performClickCheckmark()
807+         val  surfaceBitmapWidth =  layerModel?.width
808+         val  pixelsDrawingSurface =  surfaceBitmapWidth?.let  { IntArray (it) }
809+         if  (surfaceBitmapWidth !=  null  &&  canvasPoint !=  null ) {
810+             layerModel?.currentLayer?.bitmap?.getPixels(
811+                 pixelsDrawingSurface, 0 , surfaceBitmapWidth, 0 ,
812+                 canvasPoint.y.toInt(), surfaceBitmapWidth, 1 
813+             )
814+         }
815+         val  blackPixelAmountNoOutline =  pixelsDrawingSurface?.let  { countPixelsWithColor(it, Color .BLACK ) }
816+         val  whitePixelAmountNoOutline =  pixelsDrawingSurface?.let  { countPixelsWithColor(it, Color .WHITE ) }
817+         onTopBarView().performUndo()
818+ 
819+         selectFormatting(FormattingOptions .OUTLINE )
820+         textTool?.let  { Assert .assertTrue(it.outlined) }
821+ 
822+         onTopBarView().performClickCheckmark()
823+ 
824+         if  (surfaceBitmapWidth !=  null  &&  canvasPoint !=  null ) {
825+             layerModel?.currentLayer?.bitmap?.getPixels(
826+                 pixelsDrawingSurface, 0 , surfaceBitmapWidth, 0 ,
827+                 canvasPoint.y.toInt(), surfaceBitmapWidth, 1 
828+             )
829+         }
830+ 
831+         val  blackPixelAmountWithOutline =  pixelsDrawingSurface?.let  { countPixelsWithColor(it, Color .BLACK ) }
832+         if  (blackPixelAmountNoOutline !=  null  &&  blackPixelAmountWithOutline !=  null ) {
833+             assert (blackPixelAmountNoOutline >  blackPixelAmountWithOutline)
834+             assert (blackPixelAmountWithOutline >  0 )
835+         }
836+ 
837+         val  whitePixelAmountWithOutline =  pixelsDrawingSurface?.let  { countPixelsWithColor(it, Color .WHITE ) }
838+         if  (whitePixelAmountNoOutline !=  null  &&  whitePixelAmountWithOutline !=  null ) {
839+             assert (whitePixelAmountNoOutline <  whitePixelAmountWithOutline)
840+         }
841+     }
842+ 
843+     @Test
844+     fun  testTextOutlineWidth () {
845+         val  canvasPoint =  centerBox()
846+         selectFormatting(FormattingOptions .OUTLINE )
847+         textTool?.let  { Assert .assertTrue(it.outlined) }
848+         outlineWidthLayout?.let  { Assert .assertTrue(it.isVisible) }
849+         val  outlineWidthInput =  onView(withId(R .id.pocketpaint_outline_width_text))
850+         val  outlineWidthSeekbar =  onView(withId(R .id.pocketpaint_outline_width_seek_bar))
851+         outlineWidthInput.check(matches(ViewMatchers .withText(DEFAULT_TEXT_OUTLINE_WIDTH .toString())))
852+         outlineWidthSeekbar.check(matches(UiMatcher .withProgress(DEFAULT_TEXT_OUTLINE_WIDTH )))
853+ 
854+         enterTestText()
855+ 
856+         var  testOutlineWidthText =  " 1" 
857+ 
858+         outlineWidthInput.perform(
859+             ViewActions .replaceText(testOutlineWidthText),
860+             ViewActions .closeSoftKeyboard()
861+         )
862+         outlineWidthInput.check(matches(ViewMatchers .withText(testOutlineWidthText)))
863+         outlineWidthSeekbar.check(matches(UiMatcher .withProgress(testOutlineWidthText.toInt())))
864+ 
865+         onTopBarView().performClickCheckmark()
866+         val  surfaceBitmapWidth =  layerModel?.width
867+         val  pixelsDrawingSurface =  surfaceBitmapWidth?.let  { IntArray (it) }
868+         if  (surfaceBitmapWidth !=  null  &&  canvasPoint !=  null ) {
869+             layerModel?.currentLayer?.bitmap?.getPixels(
870+                 pixelsDrawingSurface, 0 , surfaceBitmapWidth, 0 ,
871+                 canvasPoint.y.toInt(), surfaceBitmapWidth, 1 
872+             )
873+         }
874+         val  blackPixelAmountThinOutline =  pixelsDrawingSurface?.let  { countPixelsWithColor(it, Color .BLACK ) }
875+         val  whitePixelAmountThinOutline =  pixelsDrawingSurface?.let  { countPixelsWithColor(it, Color .WHITE ) }
876+         onTopBarView().performUndo()
877+ 
878+         testOutlineWidthText =  " 60" 
879+ 
880+         outlineWidthInput.perform(
881+             ViewActions .replaceText(testOutlineWidthText),
882+             ViewActions .closeSoftKeyboard()
883+         )
884+         outlineWidthInput.check(matches(ViewMatchers .withText(testOutlineWidthText)))
885+         outlineWidthSeekbar.check(matches(UiMatcher .withProgress(testOutlineWidthText.toInt())))
886+ 
887+         onTopBarView().performClickCheckmark()
888+ 
889+         if  (surfaceBitmapWidth !=  null  &&  canvasPoint !=  null ) {
890+             layerModel?.currentLayer?.bitmap?.getPixels(
891+                 pixelsDrawingSurface, 0 , surfaceBitmapWidth, 0 ,
892+                 canvasPoint.y.toInt(), surfaceBitmapWidth, 1 
893+             )
894+         }
895+ 
896+         val  blackPixelAmountThickOutline =  pixelsDrawingSurface?.let  { countPixelsWithColor(it, Color .BLACK ) }
897+         if  (blackPixelAmountThinOutline !=  null  &&  blackPixelAmountThickOutline !=  null ) {
898+             assert (blackPixelAmountThinOutline >  0 )
899+             assert (blackPixelAmountThickOutline >  0 )
900+             assert (blackPixelAmountThickOutline >  blackPixelAmountThinOutline)
901+         }
902+ 
903+         val  whitePixelAmountThickOutline =  pixelsDrawingSurface?.let  { countPixelsWithColor(it, Color .WHITE ) }
904+         if  (whitePixelAmountThinOutline !=  null  &&  whitePixelAmountThickOutline !=  null ) {
905+             assert (whitePixelAmountThinOutline >  0 )
906+             assert (whitePixelAmountThickOutline >  0 )
907+             assert (whitePixelAmountThickOutline <  whitePixelAmountThinOutline)
908+         }
909+     }
910+ 
766911    private  fun  centerBox (): PointF ?  {
767912        val  screenPoint = 
768913            activityHelper?.displayWidth?.div(2.0f )
@@ -892,6 +1037,7 @@ class TextToolIntegrationTest {
8921037            FormattingOptions .UNDERLINE  ->  activity.getString(R .string.text_tool_dialog_underline_shortcut)
8931038            FormattingOptions .ITALIC  ->  activity.getString(R .string.text_tool_dialog_italic_shortcut)
8941039            FormattingOptions .BOLD  ->  activity.getString(R .string.text_tool_dialog_bold_shortcut)
1040+             FormattingOptions .OUTLINE  ->  activity.getString(R .string.text_tool_dialog_outline_shortcut)
8951041        }
8961042    }
8971043
@@ -921,7 +1067,7 @@ class TextToolIntegrationTest {
9211067    private  val  toolMemberMultilineText:  Array <String >
9221068        get() =  textTool!! .multilineText
9231069
924-     private  enum  class  FormattingOptions  { UNDERLINE , ITALIC , BOLD  }
1070+     private  enum  class  FormattingOptions  { UNDERLINE , ITALIC , BOLD ,  OUTLINE  }
9251071
9261072    companion  object  {
9271073        private  const  val  TEST_TEXT  =  " 123 www 123" 
0 commit comments