181 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			181 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright 2019 Google Inc.
 | |
|  *
 | |
|  * Use of this source code is governed by a BSD-style license that can be
 | |
|  * found in the LICENSE file.
 | |
|  */
 | |
| 
 | |
| #include "gm/gm.h"
 | |
| #include "include/core/SkCanvas.h"
 | |
| #include "include/core/SkColor.h"
 | |
| #include "include/core/SkFont.h"
 | |
| #include "include/core/SkFontStyle.h"
 | |
| #include "include/core/SkFontTypes.h"
 | |
| #include "include/core/SkPaint.h"
 | |
| #include "include/core/SkScalar.h"
 | |
| #include "include/core/SkTypeface.h"
 | |
| #include "include/core/SkTypes.h"
 | |
| 
 | |
| #include <string.h>
 | |
| #include <initializer_list>
 | |
| 
 | |
| #ifdef SK_BUILD_FOR_MAC
 | |
| 
 | |
| #include "include/core/SkSurface.h"
 | |
| 
 | |
| #import <ApplicationServices/ApplicationServices.h>
 | |
| 
 | |
| static void std_cg_setup(CGContextRef ctx) {
 | |
|     CGContextSetAllowsFontSubpixelQuantization(ctx, false);
 | |
|     CGContextSetShouldSubpixelQuantizeFonts(ctx, false);
 | |
| 
 | |
|     // Because CG always draws from the horizontal baseline,
 | |
|     // if there is a non-integral translation from the horizontal origin to the vertical origin,
 | |
|     // then CG cannot draw the glyph in the correct location without subpixel positioning.
 | |
|     CGContextSetAllowsFontSubpixelPositioning(ctx, true);
 | |
|     CGContextSetShouldSubpixelPositionFonts(ctx, true);
 | |
| 
 | |
|     CGContextSetAllowsFontSmoothing(ctx, true);
 | |
|     CGContextSetShouldAntialias(ctx, true);
 | |
| 
 | |
|     CGContextSetTextDrawingMode(ctx, kCGTextFill);
 | |
| 
 | |
|     // Draw black on white to create mask. (Special path exists to speed this up in CG.)
 | |
|     CGContextSetGrayFillColor(ctx, 0.0f, 1.0f);
 | |
| }
 | |
| 
 | |
| static CGContextRef make_cg_ctx(const SkPixmap& pm) {
 | |
|     CGBitmapInfo info;
 | |
|     CGColorSpaceRef cs;
 | |
| 
 | |
|     switch (pm.colorType()) {
 | |
|         case kRGBA_8888_SkColorType:
 | |
|             info = kCGBitmapByteOrder32Host | (CGBitmapInfo)kCGImageAlphaNoneSkipFirst;
 | |
|             cs = CGColorSpaceCreateDeviceRGB();
 | |
|             break;
 | |
|         case kGray_8_SkColorType:
 | |
|             info = kCGImageAlphaNone;
 | |
|             cs = CGColorSpaceCreateDeviceGray();
 | |
|             break;
 | |
|         case kAlpha_8_SkColorType:
 | |
|             info = kCGImageAlphaOnly;
 | |
|             cs = nullptr;
 | |
|             break;
 | |
|         default:
 | |
|             return nullptr;
 | |
|     }
 | |
|     auto ctx = CGBitmapContextCreate(pm.writable_addr(), pm.width(), pm.height(), 8, pm.rowBytes(),
 | |
|                                      cs, info);
 | |
|     std_cg_setup(ctx);
 | |
|     return ctx;
 | |
| }
 | |
| 
 | |
| static void test_mac_fonts(SkCanvas* canvas, SkScalar size, SkScalar xpos) {
 | |
|     int w = 32;
 | |
|     int h = 32;
 | |
| 
 | |
|     canvas->scale(10, 10);
 | |
|     SkScalar y = 1;
 | |
| 
 | |
|     for (SkColorType ct : {kRGBA_8888_SkColorType, kGray_8_SkColorType, kAlpha_8_SkColorType}) {
 | |
|         SkImageInfo ii = SkImageInfo::Make(w, h, ct, kPremul_SkAlphaType);
 | |
|         auto surf = SkSurface::MakeRaster(ii);
 | |
|         SkPixmap pm;
 | |
|         surf->peekPixels(&pm);
 | |
|         CGContextRef ctx = make_cg_ctx(pm);
 | |
|         CGContextSelectFont(ctx, "Times", size, kCGEncodingMacRoman);
 | |
| 
 | |
|         SkScalar x = 1;
 | |
|         for (bool smooth : {false, true}) {
 | |
|             surf->getCanvas()->clear(ct == kAlpha_8_SkColorType ? 0 : 0xFFFFFFFF);
 | |
|             CGContextSetShouldSmoothFonts(ctx, smooth);
 | |
|             CGContextShowTextAtPoint(ctx, 2 + xpos, 2, "A", 1);
 | |
| 
 | |
|             surf->draw(canvas, x, y);
 | |
|             x += pm.width();
 | |
|         }
 | |
|         y += pm.height();
 | |
|     }
 | |
| }
 | |
| 
 | |
| class MacAAFontsGM : public skiagm::GM {
 | |
|     SkScalar fSize = 16;
 | |
|     SkScalar fXPos = 0;
 | |
| 
 | |
| public:
 | |
|     MacAAFontsGM() {}
 | |
|     ~MacAAFontsGM() override {}
 | |
| 
 | |
| protected:
 | |
|     DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
 | |
|         test_mac_fonts(canvas, fSize, fXPos);
 | |
| 
 | |
|         return DrawResult::kOk;
 | |
|     }
 | |
| 
 | |
|     SkISize onISize() override { return { 1024, 768 }; }
 | |
| 
 | |
|     SkString onShortName() override { return SkString("macaatest"); }
 | |
| 
 | |
|     bool onChar(SkUnichar uni) override {
 | |
|         switch (uni) {
 | |
|             case 'i': fSize += 1; return true;
 | |
|             case 'k': fSize -= 1; return true;
 | |
|             case 'j': fXPos -= 1.0f/16; return true;
 | |
|             case 'l': fXPos += 1.0f/16; return true;
 | |
|             default: break;
 | |
|         }
 | |
|         return false;
 | |
|     }
 | |
| };
 | |
| DEF_GM(return new MacAAFontsGM;)
 | |
| 
 | |
| #endif
 | |
| 
 | |
| DEF_SIMPLE_GM(macaa_colors, canvas, 800, 500) {
 | |
|     const SkColor GRAY = 0xFF808080;
 | |
|     const SkColor colors[] = {
 | |
|         SK_ColorBLACK, SK_ColorWHITE,
 | |
|         SK_ColorBLACK, GRAY,
 | |
|         SK_ColorWHITE, SK_ColorBLACK,
 | |
|         SK_ColorWHITE, GRAY,
 | |
|     };
 | |
|     const SkScalar sizes[] = {10, 12, 15, 18, 24};
 | |
| 
 | |
|     const SkScalar width = 200;
 | |
|     const SkScalar height = 500;
 | |
|     const char str[] = "Hamburgefons";
 | |
|     const size_t len = strlen(str);
 | |
| 
 | |
|     SkFont font;
 | |
|     font.setTypeface(SkTypeface::MakeFromName("Times", SkFontStyle()));
 | |
| 
 | |
|     for (size_t i = 0; i < SK_ARRAY_COUNT(colors); i += 2) {
 | |
|         canvas->save();
 | |
| 
 | |
|         SkPaint paint;
 | |
|         paint.setColor(colors[i+1]);
 | |
|         canvas->drawRect({0, 0, width, height}, paint);
 | |
|         paint.setColor(colors[i]);
 | |
| 
 | |
|         SkScalar y = 10;
 | |
|         SkScalar x = 10;
 | |
|         for (SkScalar ps : sizes) {
 | |
|             font.setSize(ps);
 | |
|             for (bool lcd : {false, true}) {
 | |
|                 font.setEdging(lcd ? SkFont::Edging::kSubpixelAntiAlias
 | |
|                                    : SkFont::Edging::kAntiAlias);
 | |
|                 for (auto h : {SkFontHinting::kNone, SkFontHinting::kNormal}) {
 | |
|                     font.setHinting(h);
 | |
| 
 | |
|                     y += font.getSpacing() + 2;
 | |
|                     canvas->drawSimpleText(str, len, SkTextEncoding::kUTF8, x, y, font, paint);
 | |
|                 }
 | |
|             }
 | |
|             y += 8;
 | |
|         }
 | |
|         canvas->restore();
 | |
|         canvas->translate(width, 0);
 | |
|     }
 | |
| }
 |