DrawTextTest.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /*
  2. * Copyright 2011 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/core/SkBitmap.h"
  8. #include "include/core/SkCanvas.h"
  9. #include "include/core/SkColor.h"
  10. #include "include/core/SkFont.h"
  11. #include "include/core/SkMatrix.h"
  12. #include "include/core/SkPaint.h"
  13. #include "include/core/SkPathEffect.h"
  14. #include "include/core/SkPoint.h"
  15. #include "include/core/SkRect.h"
  16. #include "include/core/SkRefCnt.h"
  17. #include "include/core/SkScalar.h"
  18. #include "include/core/SkSurface.h"
  19. #include "include/core/SkTypeface.h"
  20. #include "include/core/SkTypes.h"
  21. #include "include/effects/SkDashPathEffect.h"
  22. #include "tests/Test.h"
  23. #include <cmath>
  24. static const SkColor bgColor = SK_ColorWHITE;
  25. static void create(SkBitmap* bm, SkIRect bound) {
  26. bm->allocN32Pixels(bound.width(), bound.height());
  27. }
  28. /** Assumes that the ref draw was completely inside ref canvas --
  29. implies that everything outside is "bgColor".
  30. Checks that all overlap is the same and that all non-overlap on the
  31. ref is "bgColor".
  32. */
  33. static bool compare(const SkBitmap& ref, const SkIRect& iref,
  34. const SkBitmap& test, const SkIRect& itest)
  35. {
  36. const int xOff = itest.fLeft - iref.fLeft;
  37. const int yOff = itest.fTop - iref.fTop;
  38. for (int y = 0; y < test.height(); ++y) {
  39. for (int x = 0; x < test.width(); ++x) {
  40. SkColor testColor = test.getColor(x, y);
  41. int refX = x + xOff;
  42. int refY = y + yOff;
  43. SkColor refColor;
  44. if (refX >= 0 && refX < ref.width() &&
  45. refY >= 0 && refY < ref.height())
  46. {
  47. refColor = ref.getColor(refX, refY);
  48. } else {
  49. refColor = bgColor;
  50. }
  51. if (refColor != testColor) {
  52. return false;
  53. }
  54. }
  55. }
  56. return true;
  57. }
  58. /** Test that drawing glyphs with empty paths is different from drawing glyphs without paths. */
  59. DEF_TEST(DrawText_dashout, reporter) {
  60. SkIRect size = SkIRect::MakeWH(64, 64);
  61. SkBitmap drawTextBitmap;
  62. create(&drawTextBitmap, size);
  63. SkCanvas drawTextCanvas(drawTextBitmap);
  64. SkBitmap drawDashedTextBitmap;
  65. create(&drawDashedTextBitmap, size);
  66. SkCanvas drawDashedTextCanvas(drawDashedTextBitmap);
  67. SkBitmap emptyBitmap;
  68. create(&emptyBitmap, size);
  69. SkCanvas emptyCanvas(emptyBitmap);
  70. SkPoint point = SkPoint::Make(25.0f, 25.0f);
  71. SkFont font(nullptr, 20);
  72. font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
  73. font.setSubpixel(true);
  74. SkPaint paint;
  75. paint.setColor(SK_ColorGRAY);
  76. paint.setStyle(SkPaint::kStroke_Style);
  77. // Draw a stroked "A" without a dash which will draw something.
  78. drawTextCanvas.drawColor(SK_ColorWHITE);
  79. drawTextCanvas.drawString("A", point.fX, point.fY, font, paint);
  80. // Draw an "A" but with a dash which will never draw anything.
  81. paint.setStrokeWidth(2);
  82. constexpr SkScalar bigInterval = 10000;
  83. static constexpr SkScalar intervals[] = { 1, bigInterval };
  84. paint.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 2));
  85. drawDashedTextCanvas.drawColor(SK_ColorWHITE);
  86. drawDashedTextCanvas.drawString("A", point.fX, point.fY, font, paint);
  87. // Draw nothing.
  88. emptyCanvas.drawColor(SK_ColorWHITE);
  89. REPORTER_ASSERT(reporter, !compare(drawTextBitmap, size, emptyBitmap, size));
  90. REPORTER_ASSERT(reporter, compare(drawDashedTextBitmap, size, emptyBitmap, size));
  91. }
  92. // Test drawing text at some unusual coordinates.
  93. // We measure success by not crashing or asserting.
  94. DEF_TEST(DrawText_weirdCoordinates, r) {
  95. auto surface = SkSurface::MakeRasterN32Premul(10,10);
  96. auto canvas = surface->getCanvas();
  97. SkScalar oddballs[] = { 0.0f, (float)INFINITY, (float)NAN, 34359738368.0f };
  98. for (auto x : oddballs) {
  99. canvas->drawString("a", +x, 0.0f, SkFont(), SkPaint());
  100. canvas->drawString("a", -x, 0.0f, SkFont(), SkPaint());
  101. }
  102. for (auto y : oddballs) {
  103. canvas->drawString("a", 0.0f, +y, SkFont(), SkPaint());
  104. canvas->drawString("a", 0.0f, -y, SkFont(), SkPaint());
  105. }
  106. }
  107. // Test drawing text with some unusual matricies.
  108. // We measure success by not crashing or asserting.
  109. DEF_TEST(DrawText_weirdMatricies, r) {
  110. auto surface = SkSurface::MakeRasterN32Premul(100,100);
  111. auto canvas = surface->getCanvas();
  112. SkFont font;
  113. font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
  114. struct {
  115. SkScalar textSize;
  116. SkScalar matrix[9];
  117. } testCases[] = {
  118. // 2x2 singular
  119. {10, { 0, 0, 0, 0, 0, 0, 0, 0, 1}},
  120. {10, { 0, 0, 0, 0, 1, 0, 0, 0, 1}},
  121. {10, { 0, 0, 0, 1, 0, 0, 0, 0, 1}},
  122. {10, { 0, 0, 0, 1, 1, 0, 0, 0, 1}},
  123. {10, { 0, 1, 0, 0, 1, 0, 0, 0, 1}},
  124. {10, { 1, 0, 0, 0, 0, 0, 0, 0, 1}},
  125. {10, { 1, 0, 0, 1, 0, 0, 0, 0, 1}},
  126. {10, { 1, 1, 0, 0, 0, 0, 0, 0, 1}},
  127. {10, { 1, 1, 0, 1, 1, 0, 0, 0, 1}},
  128. // See https://bugzilla.mozilla.org/show_bug.cgi?id=1305085 .
  129. { 1, {10, 20, 0, 20, 40, 0, 0, 0, 1}},
  130. };
  131. for (const auto& testCase : testCases) {
  132. font.setSize(testCase.textSize);
  133. const SkScalar(&m)[9] = testCase.matrix;
  134. SkMatrix mat;
  135. mat.setAll(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8]);
  136. canvas->setMatrix(mat);
  137. canvas->drawString("Hamburgefons", 10, 10, font, SkPaint());
  138. }
  139. }