Home | History | Annotate | Download | only in gm
      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 
      8 #include "gm.h"
      9 #include "SkCanvas.h"
     10 #include "SkPath.h"
     11 #include "SkGradientShader.h"
     12 #include "SkTypeface.h"
     13 
     14 static SkShader* make_heatGradient(const SkPoint pts[2]) {
     15     const SkColor colors[] = {
     16         SK_ColorBLACK, SK_ColorBLUE, SK_ColorCYAN, SK_ColorGREEN,
     17         SK_ColorYELLOW, SK_ColorRED, SK_ColorWHITE
     18     };
     19     const SkColor bw[] = { SK_ColorBLACK, SK_ColorWHITE };
     20 
     21     return SkGradientShader::CreateLinear(pts, bw, NULL,
     22                                           SK_ARRAY_COUNT(bw),
     23                                           SkShader::kClamp_TileMode);
     24 }
     25 
     26 static bool setFont(SkPaint* paint, const char name[]) {
     27     SkTypeface* tf = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
     28     if (tf) {
     29         paint->setTypeface(tf)->unref();
     30         return true;
     31     }
     32     return false;
     33 }
     34 
     35 #ifdef SK_BUILD_FOR_MAC
     36 #import <ApplicationServices/ApplicationServices.h>
     37 #define BITMAP_INFO_RGB     (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host)
     38 
     39 static CGContextRef makeCG(const SkBitmap& bm) {
     40     if (SkBitmap::kARGB_8888_Config != bm.config() ||
     41         NULL == bm.getPixels()) {
     42         return NULL;
     43     }
     44     CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
     45     CGContextRef cg = CGBitmapContextCreate(bm.getPixels(), bm.width(), bm.height(),
     46                                             8, bm.rowBytes(), space, BITMAP_INFO_RGB);
     47     CFRelease(space);
     48 
     49     CGContextSetAllowsFontSubpixelQuantization(cg, false);
     50     CGContextSetShouldSubpixelQuantizeFonts(cg, false);
     51 
     52     return cg;
     53 }
     54 
     55 extern CTFontRef SkTypeface_GetCTFontRef(const SkTypeface* face);
     56 
     57 static CGFontRef typefaceToCGFont(const SkTypeface* face) {
     58     if (NULL == face) {
     59         return 0;
     60     }
     61 
     62     CTFontRef ct = SkTypeface_GetCTFontRef(face);
     63     return CTFontCopyGraphicsFont(ct, NULL);
     64 }
     65 
     66 static void cgSetPaintForText(CGContextRef cg, const SkPaint& paint) {
     67     SkColor c = paint.getColor();
     68     CGFloat rgba[] = {
     69         SkColorGetB(c) / 255.0,
     70         SkColorGetG(c) / 255.0,
     71         SkColorGetR(c) / 255.0,
     72         SkColorGetA(c) / 255.0,
     73     };
     74     CGContextSetRGBFillColor(cg, rgba[0], rgba[1], rgba[2], rgba[3]);
     75 
     76     CGContextSetTextDrawingMode(cg, kCGTextFill);
     77     CGContextSetFont(cg, typefaceToCGFont(paint.getTypeface()));
     78     CGContextSetFontSize(cg, SkScalarToFloat(paint.getTextSize()));
     79 
     80     CGContextSetAllowsFontSubpixelPositioning(cg, paint.isSubpixelText());
     81     CGContextSetShouldSubpixelPositionFonts(cg, paint.isSubpixelText());
     82 
     83     CGContextSetShouldAntialias(cg, paint.isAntiAlias());
     84     CGContextSetShouldSmoothFonts(cg, paint.isLCDRenderText());
     85 }
     86 
     87 static void cgDrawText(CGContextRef cg, const void* text, size_t len,
     88                        float x, float y, const SkPaint& paint) {
     89     if (cg) {
     90         cgSetPaintForText(cg, paint);
     91 
     92         uint16_t glyphs[200];
     93         int count = paint.textToGlyphs(text, len, glyphs);
     94 
     95         CGContextShowGlyphsAtPoint(cg, x, y, glyphs, count);
     96     }
     97 }
     98 #endif
     99 
    100 namespace skiagm {
    101 
    102 /**
    103    Test a set of clipping problems discovered while writing blitAntiRect,
    104    and test all the code paths through the clipping blitters.
    105    Each region should show as a blue center surrounded by a 2px green
    106    border, with no red.
    107 */
    108 
    109 #define HEIGHT 480
    110 
    111 class GammaTextGM : public GM {
    112 public:
    113     GammaTextGM() {
    114 
    115     }
    116 
    117 protected:
    118     virtual SkString onShortName() {
    119         return SkString("gammatext");
    120     }
    121 
    122     virtual SkISize onISize() {
    123         return make_isize(1024, HEIGHT);
    124     }
    125 
    126     static void drawGrad(SkCanvas* canvas) {
    127         SkPoint pts[] = { { 0, 0 }, { 0, HEIGHT } };
    128 #if 0
    129         const SkColor colors[] = { SK_ColorBLACK, SK_ColorWHITE };
    130         SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, 2, SkShader::kClamp_TileMode);
    131 #else
    132         SkShader* s = make_heatGradient(pts);
    133 #endif
    134 
    135         canvas->clear(SK_ColorRED);
    136         SkPaint paint;
    137         paint.setShader(s)->unref();
    138         SkRect r = { 0, 0, 1024, HEIGHT };
    139         canvas->drawRect(r, paint);
    140     }
    141 
    142     virtual void onDraw(SkCanvas* canvas) {
    143 #ifdef SK_BUILD_FOR_MAC
    144         CGContextRef cg = makeCG(canvas->getDevice()->accessBitmap(false));
    145 #endif
    146 
    147         drawGrad(canvas);
    148 
    149         const SkColor fg[] = {
    150             0xFFFFFFFF,
    151             0xFFFFFF00, 0xFFFF00FF, 0xFF00FFFF,
    152             0xFFFF0000, 0xFF00FF00, 0xFF0000FF,
    153             0xFF000000,
    154         };
    155 
    156         const char* text = "Hamburgefons";
    157         size_t len = strlen(text);
    158 
    159         SkPaint paint;
    160         setFont(&paint, "Times");
    161         paint.setTextSize(SkIntToScalar(16));
    162         paint.setAntiAlias(true);
    163         paint.setLCDRenderText(true);
    164 
    165         SkScalar x = 10;
    166         for (size_t i = 0; i < SK_ARRAY_COUNT(fg); ++i) {
    167             paint.setColor(fg[i]);
    168 
    169             SkScalar y = 40;
    170             SkScalar stopy = HEIGHT;
    171             while (y < stopy) {
    172 #if 1
    173                 canvas->drawText(text, len, x, y, paint);
    174 #else
    175                 cgDrawText(cg, text, len, x, HEIGHT - y, paint);
    176 #endif
    177                 y += paint.getTextSize() * 2;
    178             }
    179             x += SkIntToScalar(1024) / SK_ARRAY_COUNT(fg);
    180         }
    181     }
    182 
    183 private:
    184     typedef GM INHERITED;
    185 };
    186 
    187 //////////////////////////////////////////////////////////////////////////////
    188 
    189 static GM* MyFactory(void*) { return new GammaTextGM; }
    190 static GMRegistry reg(MyFactory);
    191 
    192 }
    193