example_skia.cpp revision ecc2d34ac23a497988f21e5f415b53c007b9d8c5
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17// This is a test program that uses Minikin to layout and draw some text. 18// At the moment, it just draws a string into /data/local/tmp/foo.pgm. 19 20#include <stdio.h> 21#include <vector> 22#include <fstream> 23 24#include <unicode/unistr.h> 25#include <unicode/utf16.h> 26 27#include <minikin/MinikinFontFreeType.h> 28#include <minikin/Layout.h> 29 30#include <SkCanvas.h> 31#include <SkGraphics.h> 32#include <SkImageEncoder.h> 33#include <SkTypeface.h> 34#include <SkPaint.h> 35 36#include "MinikinSkia.h" 37 38using std::vector; 39 40namespace android { 41 42FT_Library library; // TODO: this should not be a global 43 44FontCollection *makeFontCollection() { 45 vector<FontFamily *>typefaces; 46 const char *fns[] = { 47 "/system/fonts/Roboto-Regular.ttf", 48 "/system/fonts/Roboto-Italic.ttf", 49 "/system/fonts/Roboto-BoldItalic.ttf", 50 "/system/fonts/Roboto-Light.ttf", 51 "/system/fonts/Roboto-Thin.ttf", 52 "/system/fonts/Roboto-Bold.ttf", 53 "/system/fonts/Roboto-ThinItalic.ttf", 54 "/system/fonts/Roboto-LightItalic.ttf" 55 }; 56 57 FontFamily *family = new FontFamily(); 58 FT_Face face; 59 FT_Error error; 60 for (size_t i = 0; i < sizeof(fns)/sizeof(fns[0]); i++) { 61 const char *fn = fns[i]; 62 SkTypeface *skFace = SkTypeface::CreateFromFile(fn); 63 MinikinFont *font = new MinikinFontSkia(skFace); 64 family->addFont(font); 65 } 66 typefaces.push_back(family); 67 68#if 1 69 family = new FontFamily(); 70 const char *fn = "/system/fonts/DroidSansDevanagari-Regular.ttf"; 71 SkTypeface *skFace = SkTypeface::CreateFromFile(fn); 72 MinikinFont *font = new MinikinFontSkia(skFace); 73 family->addFont(font); 74 typefaces.push_back(family); 75#endif 76 77 return new FontCollection(typefaces); 78} 79 80// Maybe move to MinikinSkia (esp. instead of opening GetSkTypeface publicly)? 81 82void drawToSkia(SkCanvas *canvas, SkPaint *paint, Layout *layout, float x, float y) { 83 size_t nGlyphs = layout->nGlyphs(); 84 uint16_t *glyphs = new uint16_t[nGlyphs]; 85 SkPoint *pos = new SkPoint[nGlyphs]; 86 SkTypeface *lastFace = NULL; 87 SkTypeface *skFace = NULL; 88 size_t start = 0; 89 90 paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); 91 for (size_t i = 0; i < nGlyphs; i++) { 92 MinikinFontSkia *mfs = static_cast<MinikinFontSkia *>(layout->getFont(i)); 93 skFace = mfs->GetSkTypeface(); 94 glyphs[i] = layout->getGlyphId(i); 95 pos[i].fX = SkFloatToScalar(x + layout->getX(i)); 96 pos[i].fY = SkFloatToScalar(y + layout->getY(i)); 97 if (i > 0 && skFace != lastFace) { 98 paint->setTypeface(lastFace); 99 canvas->drawPosText(glyphs + start, (i - start) << 1, pos + start, *paint); 100 start = i; 101 } 102 lastFace = skFace; 103 } 104 paint->setTypeface(skFace); 105 canvas->drawPosText(glyphs + start, (nGlyphs - start) << 1, pos + start, *paint); 106 delete[] glyphs; 107 delete[] pos; 108} 109 110int runMinikinTest() { 111 FT_Error error = FT_Init_FreeType(&library); 112 if (error) { 113 return -1; 114 } 115 Layout::init(); 116 117 FontCollection *collection = makeFontCollection(); 118 Layout layout; 119 layout.setFontCollection(collection); 120 layout.setProperties("font-size: 32; font-weight: 700;"); 121 const char *text = "fine world \xe0\xa4\xa8\xe0\xa4\xae\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\xa4\xe0\xa5\x87"; 122 icu::UnicodeString icuText = icu::UnicodeString::fromUTF8(text); 123 layout.doLayout(icuText.getBuffer(), icuText.length()); 124 layout.dump(); 125 126 SkAutoGraphics ag; 127 128 SkScalar width = 800; 129 SkScalar height = 600; 130 SkBitmap bitmap; 131 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); 132 bitmap.allocPixels(); 133 SkCanvas canvas(bitmap); 134 SkPaint paint; 135 paint.setARGB(255, 0, 0, 128); 136 paint.setStyle(SkPaint::kStroke_Style); 137 paint.setStrokeWidth(2); 138 paint.setTextSize(100); 139 paint.setAntiAlias(true); 140 canvas.drawLine(10, 300, 10 + layout.getAdvance(), 300, paint); 141 paint.setStyle(SkPaint::kFill_Style); 142 drawToSkia(&canvas, &paint, &layout, 10, 300); 143 144 SkImageEncoder::EncodeFile("/data/local/tmp/foo.png", bitmap, SkImageEncoder::kPNG_Type, 100); 145 return 0; 146} 147 148} 149 150int main(int argc, const char** argv) { 151 return android::runMinikinTest(); 152} 153