122 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright 2020 Google LLC
 | |
|  *
 | |
|  * 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/SkFont.h"
 | |
| #include "include/core/SkPaint.h"
 | |
| #include "include/core/SkPath.h"
 | |
| #include "include/core/SkSize.h"
 | |
| #include "include/core/SkString.h"
 | |
| #include "include/utils/SkCustomTypeface.h"
 | |
| #include "tools/Resources.h"
 | |
| 
 | |
| static sk_sp<SkTypeface> make_tf() {
 | |
|     SkCustomTypefaceBuilder builder;
 | |
|     SkFont font;
 | |
|     const float upem = font.getTypefaceOrDefault()->getUnitsPerEm();
 | |
| 
 | |
|     // request a big size, to improve precision at the fontscaler level
 | |
|     font.setSize(upem);
 | |
|     font.setHinting(SkFontHinting::kNone);
 | |
| 
 | |
|     // so we can scale our paths back down to 1-point
 | |
|     const SkMatrix scale = SkMatrix::Scale(1.0f/upem, 1.0f/upem);
 | |
| 
 | |
|     {
 | |
|         SkFontMetrics metrics;
 | |
|         font.getMetrics(&metrics);
 | |
|         builder.setMetrics(metrics, 1.0f/upem);
 | |
|     }
 | |
|     builder.setFontStyle(font.getTypefaceOrDefault()->fontStyle());
 | |
| 
 | |
|     // Steal the first 128 chars from the default font
 | |
|     for (SkGlyphID index = 0; index <= 127; ++index) {
 | |
|         SkGlyphID glyph = font.unicharToGlyph(index);
 | |
| 
 | |
|         SkScalar width;
 | |
|         font.getWidths(&glyph, 1, &width);
 | |
|         SkPath path;
 | |
|         font.getPath(glyph, &path);
 | |
| 
 | |
|         // we use the charcode to be our glyph index, since we have no cmap table
 | |
|         builder.setGlyph(index, width/upem, path.makeTransform(scale));
 | |
|     }
 | |
| 
 | |
|     return builder.detach();
 | |
| }
 | |
| 
 | |
| #include "include/core/SkTextBlob.h"
 | |
| 
 | |
| static sk_sp<SkTypeface> round_trip(sk_sp<SkTypeface> tf) {
 | |
|     auto data = tf->serialize();
 | |
|     SkMemoryStream stream(data->data(), data->size());
 | |
|     return SkTypeface::MakeDeserialize(&stream);
 | |
| }
 | |
| 
 | |
| class UserFontGM : public skiagm::GM {
 | |
|     sk_sp<SkTypeface> fTF;
 | |
| 
 | |
| public:
 | |
|     UserFontGM() {}
 | |
| 
 | |
|     void onOnceBeforeDraw() override {
 | |
|         fTF = make_tf();
 | |
|         // test serialization
 | |
|         fTF = round_trip(fTF);
 | |
|     }
 | |
| 
 | |
|     static sk_sp<SkTextBlob> make_blob(sk_sp<SkTypeface> tf, float size, float* spacing) {
 | |
|         SkFont font(tf);
 | |
|         font.setSize(size);
 | |
|         font.setEdging(SkFont::Edging::kAntiAlias);
 | |
|         *spacing = font.getMetrics(nullptr);
 | |
|         return SkTextBlob::MakeFromString("Typeface", font);
 | |
|     }
 | |
| 
 | |
|     bool runAsBench() const override { return true; }
 | |
| 
 | |
|     SkString onShortName() override { return SkString("user_typeface"); }
 | |
| 
 | |
|     SkISize onISize() override { return {810, 452}; }
 | |
| 
 | |
|     void onDraw(SkCanvas* canvas) override {
 | |
|         auto waterfall = [&](sk_sp<SkTypeface> tf) {
 | |
|             SkPaint paint;
 | |
|             paint.setAntiAlias(true);
 | |
| 
 | |
|             float spacing;
 | |
|             float x = 20,
 | |
|                   y = 16;
 | |
|             for (float size = 9; size <= 100; size *= 1.25f) {
 | |
|                 auto blob = make_blob(tf, size, &spacing);
 | |
| 
 | |
|                 // shared baseline
 | |
|                 if (tf == nullptr) {
 | |
|                     paint.setColor(0xFFDDDDDD);
 | |
|                     canvas->drawRect({0, y, 810, y+1}, paint);
 | |
|                 }
 | |
| 
 | |
|                 paint.setColor(0xFFCCCCCC);
 | |
|                 paint.setStyle(SkPaint::kStroke_Style);
 | |
|                 canvas->drawRect(blob->bounds().makeOffset(x, y), paint);
 | |
| 
 | |
|                 paint.setStyle(SkPaint::kFill_Style);
 | |
|                 paint.setColor(SK_ColorBLACK);
 | |
|                 canvas->drawTextBlob(blob, x, y, paint);
 | |
| 
 | |
|                 y += SkScalarRoundToInt(spacing * 1.25f + 2);
 | |
|             }
 | |
|         };
 | |
| 
 | |
|         waterfall(nullptr);
 | |
|         canvas->translate(400, 0);
 | |
|         waterfall(fTF);
 | |
|     }
 | |
| };
 | |
| DEF_GM(return new UserFontGM;)
 |