mixedtextblobs.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Copyright 2013 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 "gm/gm.h"
  8. #include "include/core/SkCanvas.h"
  9. #include "include/core/SkColor.h"
  10. #include "include/core/SkFont.h"
  11. #include "include/core/SkFontTypes.h"
  12. #include "include/core/SkPaint.h"
  13. #include "include/core/SkRect.h"
  14. #include "include/core/SkRefCnt.h"
  15. #include "include/core/SkScalar.h"
  16. #include "include/core/SkSize.h"
  17. #include "include/core/SkString.h"
  18. #include "include/core/SkTextBlob.h"
  19. #include "include/core/SkTypeface.h"
  20. #include "tools/Resources.h"
  21. #include "tools/ToolUtils.h"
  22. #include <string.h>
  23. namespace skiagm {
  24. static void draw_blob(SkCanvas* canvas, const SkTextBlob* blob, const SkPaint& skPaint,
  25. const SkRect& clipRect) {
  26. SkPaint clipHairline;
  27. clipHairline.setColor(SK_ColorWHITE);
  28. clipHairline.setStyle(SkPaint::kStroke_Style);
  29. SkPaint paint(skPaint);
  30. canvas->save();
  31. canvas->drawRect(clipRect, clipHairline);
  32. paint.setAlphaf(0.125f);
  33. canvas->drawTextBlob(blob, 0, 0, paint);
  34. canvas->clipRect(clipRect);
  35. paint.setAlphaf(1.0f);
  36. canvas->drawTextBlob(blob, 0, 0, paint);
  37. canvas->restore();
  38. }
  39. class MixedTextBlobsGM : public GM {
  40. public:
  41. MixedTextBlobsGM() { }
  42. protected:
  43. void onOnceBeforeDraw() override {
  44. fEmojiTypeface = ToolUtils::planet_typeface();
  45. fEmojiText = "♁♃";
  46. fReallyBigATypeface = MakeResourceAsTypeface("fonts/ReallyBigA.ttf");
  47. SkTextBlobBuilder builder;
  48. // make textblob
  49. // Text so large we draw as paths
  50. SkFont font(ToolUtils::create_portable_typeface(), 385);
  51. font.setEdging(SkFont::Edging::kAlias);
  52. const char* text = "O";
  53. SkRect bounds;
  54. font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
  55. SkScalar yOffset = bounds.height();
  56. ToolUtils::add_to_text_blob(&builder, text, font, 10, yOffset);
  57. SkScalar corruptedAx = bounds.width();
  58. SkScalar corruptedAy = yOffset;
  59. const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf;
  60. const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf;
  61. SkScalar xOffset = boundsHalfWidth;
  62. yOffset = boundsHalfHeight;
  63. // LCD
  64. font.setSize(32);
  65. font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
  66. font.setSubpixel(true);
  67. text = "LCD!!!!!";
  68. font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
  69. ToolUtils::add_to_text_blob(&builder,
  70. text,
  71. font,
  72. xOffset - bounds.width() * 0.25f,
  73. yOffset - bounds.height() * 0.5f);
  74. // color emoji font with large glyph
  75. if (fEmojiTypeface) {
  76. font.setEdging(SkFont::Edging::kAlias);
  77. font.setSubpixel(false);
  78. font.setTypeface(fEmojiTypeface);
  79. font.measureText(fEmojiText, strlen(fEmojiText), SkTextEncoding::kUTF8, &bounds);
  80. ToolUtils::add_to_text_blob(&builder, fEmojiText, font, xOffset, yOffset);
  81. }
  82. // outline font with large glyph
  83. font.setSize(12);
  84. text = "aA";
  85. font.setTypeface(fReallyBigATypeface);
  86. ToolUtils::add_to_text_blob(&builder, text, font, corruptedAx, corruptedAy);
  87. fBlob = builder.make();
  88. }
  89. SkString onShortName() override {
  90. return SkString("mixedtextblobs");
  91. }
  92. SkISize onISize() override {
  93. return SkISize::Make(kWidth, kHeight);
  94. }
  95. void onDraw(SkCanvas* canvas) override {
  96. canvas->drawColor(SK_ColorGRAY);
  97. SkPaint paint;
  98. // setup work needed to draw text with different clips
  99. paint.setColor(SK_ColorBLACK);
  100. canvas->translate(10, 40);
  101. // compute the bounds of the text and setup some clips
  102. SkRect bounds = fBlob->bounds();
  103. const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf;
  104. const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf;
  105. const SkScalar boundsQuarterWidth = boundsHalfWidth * SK_ScalarHalf;
  106. const SkScalar boundsQuarterHeight = boundsHalfHeight * SK_ScalarHalf;
  107. SkRect upperLeftClip = SkRect::MakeXYWH(bounds.left(), bounds.top(),
  108. boundsHalfWidth, boundsHalfHeight);
  109. SkRect lowerRightClip = SkRect::MakeXYWH(bounds.centerX(), bounds.centerY(),
  110. boundsHalfWidth, boundsHalfHeight);
  111. SkRect interiorClip = bounds;
  112. interiorClip.inset(boundsQuarterWidth, boundsQuarterHeight);
  113. const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, interiorClip};
  114. size_t count = sizeof(clipRects) / sizeof(SkRect);
  115. for (size_t x = 0; x < count; ++x) {
  116. draw_blob(canvas, fBlob.get(), paint, clipRects[x]);
  117. if (x == (count >> 1) - 1) {
  118. canvas->translate(SkScalarFloorToScalar(bounds.width() + SkIntToScalar(25)),
  119. -(x * SkScalarFloorToScalar(bounds.height() +
  120. SkIntToScalar(25))));
  121. } else {
  122. canvas->translate(0, SkScalarFloorToScalar(bounds.height() + SkIntToScalar(25)));
  123. }
  124. }
  125. }
  126. private:
  127. sk_sp<SkTypeface> fEmojiTypeface;
  128. sk_sp<SkTypeface> fReallyBigATypeface;
  129. const char* fEmojiText;
  130. sk_sp<SkTextBlob> fBlob;
  131. static constexpr int kWidth = 1250;
  132. static constexpr int kHeight = 700;
  133. typedef GM INHERITED;
  134. };
  135. //////////////////////////////////////////////////////////////////////////////
  136. DEF_GM(return new MixedTextBlobsGM;)
  137. }