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 38 using std::vector; 39 40 namespace android { 41 42 FT_Library library; // TODO: this should not be a global 43 44 FontCollection *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 for (size_t i = 0; i < sizeof(fns)/sizeof(fns[0]); i++) { 59 const char *fn = fns[i]; 60 SkTypeface *skFace = SkTypeface::CreateFromFile(fn); 61 MinikinFont *font = new MinikinFontSkia(skFace); 62 family->addFont(font); 63 } 64 typefaces.push_back(family); 65 66 #if 1 67 family = new FontFamily(); 68 const char *fn = "/system/fonts/DroidSansDevanagari-Regular.ttf"; 69 SkTypeface *skFace = SkTypeface::CreateFromFile(fn); 70 MinikinFont *font = new MinikinFontSkia(skFace); 71 family->addFont(font); 72 typefaces.push_back(family); 73 #endif 74 75 return new FontCollection(typefaces); 76 } 77 78 // Maybe move to MinikinSkia (esp. instead of opening GetSkTypeface publicly)? 79 80 void drawToSkia(SkCanvas *canvas, SkPaint *paint, Layout *layout, float x, float y) { 81 size_t nGlyphs = layout->nGlyphs(); 82 uint16_t *glyphs = new uint16_t[nGlyphs]; 83 SkPoint *pos = new SkPoint[nGlyphs]; 84 SkTypeface *lastFace = NULL; 85 SkTypeface *skFace = NULL; 86 size_t start = 0; 87 88 paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); 89 for (size_t i = 0; i < nGlyphs; i++) { 90 MinikinFontSkia *mfs = static_cast<MinikinFontSkia *>(layout->getFont(i)); 91 skFace = mfs->GetSkTypeface(); 92 glyphs[i] = layout->getGlyphId(i); 93 pos[i].fX = x + layout->getX(i); 94 pos[i].fY = y + layout->getY(i); 95 if (i > 0 && skFace != lastFace) { 96 paint->setTypeface(lastFace); 97 canvas->drawPosText(glyphs + start, (i - start) << 1, pos + start, *paint); 98 start = i; 99 } 100 lastFace = skFace; 101 } 102 paint->setTypeface(skFace); 103 canvas->drawPosText(glyphs + start, (nGlyphs - start) << 1, pos + start, *paint); 104 delete[] glyphs; 105 delete[] pos; 106 } 107 108 int runMinikinTest() { 109 FT_Error error = FT_Init_FreeType(&library); 110 if (error) { 111 return -1; 112 } 113 Layout::init(); 114 115 FontCollection *collection = makeFontCollection(); 116 Layout layout; 117 layout.setFontCollection(collection); 118 const char *text = "fine world \xe0\xa4\xa8\xe0\xa4\xae\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\xa4\xe0\xa5\x87"; 119 int bidiFlags = 0; 120 FontStyle fontStyle(7); 121 MinikinPaint minikinPaint; 122 minikinPaint.size = 32; 123 icu::UnicodeString icuText = icu::UnicodeString::fromUTF8(text); 124 layout.doLayout(icuText.getBuffer(), 0, icuText.length(), icuText.length(), bidiFlags, fontStyle, minikinPaint); 125 layout.dump(); 126 127 SkAutoGraphics ag; 128 129 int width = 800; 130 int height = 600; 131 SkBitmap bitmap; 132 bitmap.allocN32Pixels(width, height); 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 150 int main(int argc, const char** argv) { 151 return android::runMinikinTest(); 152 } 153