| /* |
| * Copyright (C) 2013 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| // This is a test program that uses Minikin to layout and draw some text. |
| // At the moment, it just draws a string into /data/local/tmp/foo.pgm. |
| |
| #include <stdio.h> |
| #include <vector> |
| #include <fstream> |
| |
| #include <unicode/unistr.h> |
| #include <unicode/utf16.h> |
| |
| #include <minikin/MinikinFontFreeType.h> |
| #include <minikin/Layout.h> |
| |
| #include <SkCanvas.h> |
| #include <SkGraphics.h> |
| #include <SkImageEncoder.h> |
| #include <SkTypeface.h> |
| #include <SkPaint.h> |
| |
| #include "MinikinSkia.h" |
| |
| using std::vector; |
| |
| namespace android { |
| |
| FT_Library library; // TODO: this should not be a global |
| |
| FontCollection *makeFontCollection() { |
| vector<FontFamily *>typefaces; |
| const char *fns[] = { |
| "/system/fonts/Roboto-Regular.ttf", |
| "/system/fonts/Roboto-Italic.ttf", |
| "/system/fonts/Roboto-BoldItalic.ttf", |
| "/system/fonts/Roboto-Light.ttf", |
| "/system/fonts/Roboto-Thin.ttf", |
| "/system/fonts/Roboto-Bold.ttf", |
| "/system/fonts/Roboto-ThinItalic.ttf", |
| "/system/fonts/Roboto-LightItalic.ttf" |
| }; |
| |
| FontFamily *family = new FontFamily(); |
| FT_Face face; |
| FT_Error error; |
| for (size_t i = 0; i < sizeof(fns)/sizeof(fns[0]); i++) { |
| const char *fn = fns[i]; |
| SkTypeface *skFace = SkTypeface::CreateFromFile(fn); |
| MinikinFont *font = new MinikinFontSkia(skFace); |
| family->addFont(font); |
| } |
| typefaces.push_back(family); |
| |
| #if 1 |
| family = new FontFamily(); |
| const char *fn = "/system/fonts/DroidSansDevanagari-Regular.ttf"; |
| SkTypeface *skFace = SkTypeface::CreateFromFile(fn); |
| MinikinFont *font = new MinikinFontSkia(skFace); |
| family->addFont(font); |
| typefaces.push_back(family); |
| #endif |
| |
| return new FontCollection(typefaces); |
| } |
| |
| // Maybe move to MinikinSkia (esp. instead of opening GetSkTypeface publicly)? |
| |
| void drawToSkia(SkCanvas *canvas, SkPaint *paint, Layout *layout, float x, float y) { |
| size_t nGlyphs = layout->nGlyphs(); |
| uint16_t *glyphs = new uint16_t[nGlyphs]; |
| SkPoint *pos = new SkPoint[nGlyphs]; |
| SkTypeface *lastFace = NULL; |
| SkTypeface *skFace = NULL; |
| size_t start = 0; |
| |
| paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| for (size_t i = 0; i < nGlyphs; i++) { |
| MinikinFontSkia *mfs = static_cast<MinikinFontSkia *>(layout->getFont(i)); |
| skFace = mfs->GetSkTypeface(); |
| glyphs[i] = layout->getGlyphId(i); |
| pos[i].fX = x + layout->getX(i); |
| pos[i].fY = y + layout->getY(i); |
| if (i > 0 && skFace != lastFace) { |
| paint->setTypeface(lastFace); |
| canvas->drawPosText(glyphs + start, (i - start) << 1, pos + start, *paint); |
| start = i; |
| } |
| lastFace = skFace; |
| } |
| paint->setTypeface(skFace); |
| canvas->drawPosText(glyphs + start, (nGlyphs - start) << 1, pos + start, *paint); |
| delete[] glyphs; |
| delete[] pos; |
| } |
| |
| int runMinikinTest() { |
| FT_Error error = FT_Init_FreeType(&library); |
| if (error) { |
| return -1; |
| } |
| Layout::init(); |
| |
| FontCollection *collection = makeFontCollection(); |
| Layout layout; |
| layout.setFontCollection(collection); |
| const char *text = "fine world \xe0\xa4\xa8\xe0\xa4\xae\xe0\xa4\xb8\xe0\xa5\x8d\xe0\xa4\xa4\xe0\xa5\x87"; |
| const char *style = "font-size: 32; font-weight: 700;"; |
| int bidiFlags = 0; |
| FontStyle fontStyle(7); |
| MinikinPaint minikinPaint; |
| minikinPaint.size = 32; |
| icu::UnicodeString icuText = icu::UnicodeString::fromUTF8(text); |
| layout.doLayout(icuText.getBuffer(), 0, icuText.length(), icuText.length(), bidiFlags, fontStyle, minikinPaint); |
| layout.dump(); |
| |
| SkAutoGraphics ag; |
| |
| int width = 800; |
| int height = 600; |
| SkBitmap bitmap; |
| bitmap.allocN32Pixels(width, height); |
| SkCanvas canvas(bitmap); |
| SkPaint paint; |
| paint.setARGB(255, 0, 0, 128); |
| paint.setStyle(SkPaint::kStroke_Style); |
| paint.setStrokeWidth(2); |
| paint.setTextSize(100); |
| paint.setAntiAlias(true); |
| canvas.drawLine(10, 300, 10 + layout.getAdvance(), 300, paint); |
| paint.setStyle(SkPaint::kFill_Style); |
| drawToSkia(&canvas, &paint, &layout, 10, 300); |
| |
| SkImageEncoder::EncodeFile("/data/local/tmp/foo.png", bitmap, SkImageEncoder::kPNG_Type, 100); |
| return 0; |
| } |
| |
| } |
| |
| int main(int argc, const char** argv) { |
| return android::runMinikinTest(); |
| } |