@@ -27,7 +27,9 @@ import android.graphics.Paint
27
27
import android.graphics.PointF
28
28
import android.graphics.Typeface
29
29
import android.widget.EditText
30
+ import android.widget.RelativeLayout
30
31
import androidx.core.content.res.ResourcesCompat
32
+ import androidx.core.view.isVisible
31
33
import androidx.recyclerview.widget.RecyclerView
32
34
import androidx.test.espresso.Espresso
33
35
import androidx.test.espresso.Espresso.onView
@@ -61,6 +63,7 @@ import org.catrobat.paintroid.tools.FontType
61
63
import org.catrobat.paintroid.tools.ToolReference
62
64
import org.catrobat.paintroid.tools.ToolType
63
65
import org.catrobat.paintroid.tools.implementation.BOX_OFFSET
66
+ import org.catrobat.paintroid.tools.implementation.DEFAULT_TEXT_OUTLINE_WIDTH
64
67
import org.catrobat.paintroid.tools.implementation.MARGIN_TOP
65
68
import org.catrobat.paintroid.tools.implementation.TEXT_SIZE_MAGNIFICATION_FACTOR
66
69
import org.catrobat.paintroid.tools.implementation.TextTool
@@ -90,6 +93,8 @@ class TextToolIntegrationTest {
90
93
private var underlinedToggleButton: MaterialButton ? = null
91
94
private var italicToggleButton: MaterialButton ? = null
92
95
private var boldToggleButton: MaterialButton ? = null
96
+ private var outlineToggleButton: MaterialButton ? = null
97
+ private var outlineWidthLayout: RelativeLayout ? = null
93
98
private var textSize: EditText ? = null
94
99
private var layerModel: LayerContracts .Model ? = null
95
100
private lateinit var activity: MainActivity
@@ -116,6 +121,8 @@ class TextToolIntegrationTest {
116
121
activity.findViewById(R .id.pocketpaint_text_tool_dialog_toggle_underlined)
117
122
italicToggleButton = activity.findViewById(R .id.pocketpaint_text_tool_dialog_toggle_italic)
118
123
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)
119
126
textSize = activity.findViewById(R .id.pocketpaint_font_size_text)
120
127
textTool?.resetBoxPosition()
121
128
}
@@ -125,6 +132,7 @@ class TextToolIntegrationTest {
125
132
selectFormatting(FormattingOptions .ITALIC )
126
133
selectFormatting(FormattingOptions .BOLD )
127
134
selectFormatting(FormattingOptions .UNDERLINE )
135
+ selectFormatting(FormattingOptions .OUTLINE )
128
136
enterTestText()
129
137
onView(withId(R .id.pocketpaint_text_tool_dialog_input_text)).perform(click())
130
138
onView(withId(R .id.pocketpaint_text_tool_dialog_input_text)).perform(
@@ -135,12 +143,14 @@ class TextToolIntegrationTest {
135
143
italicToggleButton?.let { Assert .assertTrue(it.isChecked) }
136
144
boldToggleButton?.let { Assert .assertTrue(it.isChecked) }
137
145
underlinedToggleButton?.let { Assert .assertTrue(it.isChecked) }
146
+ outlineToggleButton?.let { Assert .assertTrue(it.isChecked) }
138
147
Assert .assertEquals(TEST_TEXT_ADVANCED , textEditText?.text?.toString())
139
148
onView(withId(R .id.pocketpaint_text_tool_dialog_input_text)).check(matches(isDisplayed()))
140
149
onView(withId(R .id.pocketpaint_text_tool_dialog_list_font)).check(matches(isDisplayed()))
141
150
onView(withId(R .id.pocketpaint_text_tool_dialog_toggle_underlined)).check(matches(isDisplayed()))
142
151
onView(withId(R .id.pocketpaint_text_tool_dialog_toggle_italic)).check(matches(isDisplayed()))
143
152
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()))
144
154
onView(withId(R .id.pocketpaint_font_size_text)).check(matches(isDisplayed()))
145
155
}
146
156
@@ -149,13 +159,15 @@ class TextToolIntegrationTest {
149
159
selectFormatting(FormattingOptions .ITALIC )
150
160
selectFormatting(FormattingOptions .BOLD )
151
161
selectFormatting(FormattingOptions .UNDERLINE )
162
+ selectFormatting(FormattingOptions .OUTLINE )
152
163
enterTestText()
153
164
onDrawingSurfaceView()
154
165
.perform(UiInteractions .touchAt(DrawingSurfaceLocationProvider .MIDDLE ))
155
166
156
167
italicToggleButton?.let { Assert .assertTrue(it.isChecked) }
157
168
boldToggleButton?.let { Assert .assertTrue(it.isChecked) }
158
169
underlinedToggleButton?.let { Assert .assertTrue(it.isChecked) }
170
+ outlineToggleButton?.let { Assert .assertTrue(it.isChecked) }
159
171
Assert .assertEquals(TEST_TEXT , textEditText?.text?.toString())
160
172
onView(withId(R .id.pocketpaint_text_tool_dialog_input_text))
161
173
.check(matches(not (isDisplayed())))
@@ -167,6 +179,8 @@ class TextToolIntegrationTest {
167
179
.check(matches(not (isDisplayed())))
168
180
onView(withId(R .id.pocketpaint_text_tool_dialog_toggle_bold))
169
181
.check(matches(not (isDisplayed())))
182
+ onView(withId(R .id.pocketpaint_text_tool_dialog_toggle_outline))
183
+ .check(matches(not (isDisplayed())))
170
184
onView(withId(R .id.pocketpaint_font_size_text))
171
185
.check(matches(not (isDisplayed())))
172
186
}
@@ -247,6 +261,8 @@ class TextToolIntegrationTest {
247
261
textTool?.let { Assert .assertFalse(it.underlined) }
248
262
textTool?.let { Assert .assertFalse(it.italic) }
249
263
textTool?.let { Assert .assertFalse(it.bold) }
264
+ textTool?.let { Assert .assertFalse(it.outlined) }
265
+ outlineWidthLayout?.let { Assert .assertFalse(it.isVisible) }
250
266
}
251
267
252
268
@Test
@@ -292,6 +308,20 @@ class TextToolIntegrationTest {
292
308
Assert .assertFalse(toolMemberBold)
293
309
boldToggleButton?.let { Assert .assertFalse(it.isChecked) }
294
310
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
+ )
295
325
}
296
326
297
327
@Test
@@ -301,6 +331,7 @@ class TextToolIntegrationTest {
301
331
selectFormatting(FormattingOptions .UNDERLINE )
302
332
selectFormatting(FormattingOptions .ITALIC )
303
333
selectFormatting(FormattingOptions .BOLD )
334
+ selectFormatting(FormattingOptions .OUTLINE )
304
335
onToolBarView().performCloseToolOptionsView()
305
336
306
337
val oldBoxWidth = toolMemberBoxWidth
@@ -318,6 +349,7 @@ class TextToolIntegrationTest {
318
349
underlinedToggleButton?.let { Assert .assertTrue(it.isChecked) }
319
350
italicToggleButton?.let { Assert .assertTrue(it.isChecked) }
320
351
boldToggleButton?.let { Assert .assertTrue(it.isChecked) }
352
+ outlineToggleButton?.let { Assert .assertTrue(it.isChecked) }
321
353
Assert .assertTrue(oldBoxWidth == toolMemberBoxWidth && oldBoxHeight == toolMemberBoxHeight)
322
354
}
323
355
@@ -328,6 +360,7 @@ class TextToolIntegrationTest {
328
360
selectFormatting(FormattingOptions .UNDERLINE )
329
361
selectFormatting(FormattingOptions .ITALIC )
330
362
selectFormatting(FormattingOptions .BOLD )
363
+ selectFormatting(FormattingOptions .OUTLINE )
331
364
332
365
val toolMemberBoxPosition = toolMemberBoxPosition
333
366
val expectedPosition = toolMemberBoxPosition?.y?.let { PointF (toolMemberBoxPosition.x, it) }
@@ -344,6 +377,7 @@ class TextToolIntegrationTest {
344
377
underlinedToggleButton?.let { Assert .assertTrue(it.isChecked) }
345
378
italicToggleButton?.let { Assert .assertTrue(it.isChecked) }
346
379
boldToggleButton?.let { Assert .assertTrue(it.isChecked) }
380
+ outlineToggleButton?.let { Assert .assertTrue(it.isChecked) }
347
381
Assert .assertEquals(expectedPosition, toolMemberBoxPosition)
348
382
Assert .assertEquals(oldBoxWidth.toDouble(), toolMemberBoxWidth.toDouble(), EQUALS_DELTA )
349
383
Assert .assertEquals(oldBoxHeight.toDouble(), toolMemberBoxHeight.toDouble(), EQUALS_DELTA )
@@ -750,6 +784,7 @@ class TextToolIntegrationTest {
750
784
selectFormatting(FormattingOptions .ITALIC )
751
785
selectFormatting(FormattingOptions .BOLD )
752
786
selectFormatting(FormattingOptions .UNDERLINE )
787
+ selectFormatting(FormattingOptions .OUTLINE )
753
788
}
754
789
val boxWidth = toolMemberBoxWidth
755
790
val boxHeight = toolMemberBoxHeight
@@ -759,10 +794,120 @@ class TextToolIntegrationTest {
759
794
selectFormatting(FormattingOptions .ITALIC )
760
795
selectFormatting(FormattingOptions .BOLD )
761
796
selectFormatting(FormattingOptions .UNDERLINE )
797
+ selectFormatting(FormattingOptions .OUTLINE )
762
798
Assert .assertTrue(boxWidth < toolMemberBoxWidth && boxHeight < toolMemberBoxHeight)
763
799
}
764
800
}
765
801
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
+
766
911
private fun centerBox (): PointF ? {
767
912
val screenPoint =
768
913
activityHelper?.displayWidth?.div(2.0f )
@@ -892,6 +1037,7 @@ class TextToolIntegrationTest {
892
1037
FormattingOptions .UNDERLINE -> activity.getString(R .string.text_tool_dialog_underline_shortcut)
893
1038
FormattingOptions .ITALIC -> activity.getString(R .string.text_tool_dialog_italic_shortcut)
894
1039
FormattingOptions .BOLD -> activity.getString(R .string.text_tool_dialog_bold_shortcut)
1040
+ FormattingOptions .OUTLINE -> activity.getString(R .string.text_tool_dialog_outline_shortcut)
895
1041
}
896
1042
}
897
1043
@@ -921,7 +1067,7 @@ class TextToolIntegrationTest {
921
1067
private val toolMemberMultilineText: Array <String >
922
1068
get() = textTool!! .multilineText
923
1069
924
- private enum class FormattingOptions { UNDERLINE , ITALIC , BOLD }
1070
+ private enum class FormattingOptions { UNDERLINE , ITALIC , BOLD , OUTLINE }
925
1071
926
1072
companion object {
927
1073
private const val TEST_TEXT = " 123 www 123"
0 commit comments