スポンサーリンク

Skiaでフォント利用(4)Bold,Italicで描画する

Bold,Italicの対応確認

Bold,Italicで描画する際には、フォントが対応していなければいけない。

SkTypefaceのisBold() , isItalic() で対応を調べることができる。

#include "include/core/SkCanvas.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkImage.h"

// Png保存に必要
#include "include/encode/SkPngEncoder.h"
#include "include/core/SkStream.h"

// テキスト描画
#include "include/core/SkTypeface.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontMgr.h"
#include "include/ports/SkFontMgr_directory.h" // フォントマネージャ作成
#include "include/core/SkFontMetrics.h"

/////////////////////////////////////

// フォント一覧表示
void disp_fonts(sk_sp<SkFontMgr> fmng) {
  int ffcount = fmng->countFamilies();

for (int ffi = 0; ffi < ffcount; ffi++) { sk_sp<SkFontStyleSet> typeface = fmng->createStyleSet(ffi);
for (int ftf = 0; ftf < typeface->count(); ftf++) { sk_sp<SkTypeface> face = typeface->createTypeface(ftf); SkString familyName; face->getFamilyName(&familyName); printf("%3d %3d : %-30s %s %s \n", ffi, ftf, familyName.c_str(), face->isBold() ? "Bold" : " ", // Boldに対応している場合に表示 face->isItalic() ? "Italic" : " "// Italicに対応している場合に表示 ); } } }

// テキスト描画のテスト
void TextTest() { // フォントマネージャ作成 sk_sp<SkFontMgr> fontMgr = SkFontMgr_New_Custom_Directory("C:\\Windows\\Fonts\\"); // フォントが格納されているディレクトリ指定 disp_fonts(fontMgr); }

実行例

0 0 : Agency FB Bold
0 1 : Agency FB
1 0 : Alef Bold
1 1 : Alef
2 0 : Algerian
3 0 : Amiri Bold
3 1 : Amiri Bold Italic
3 2 : Amiri Italic
3 3 : Amiri
4 0 : Amiri Quran
5 0 : Book Antiqua Bold
5 1 : Book Antiqua Bold Italic
5 2 : Book Antiqua Italic
5 3 : Book Antiqua
...

テストコード

#include "include/core/SkCanvas.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkImage.h"

// Png保存に必要
#include "include/encode/SkPngEncoder.h"
#include "include/core/SkStream.h"

// テキスト描画
#include "include/core/SkTypeface.h"
#include "include/core/SkFont.h"
#include "include/core/SkFontMgr.h"
#include "include/ports/SkFontMgr_directory.h" // フォントマネージャ作成
#include "include/core/SkFontMetrics.h"

/////////////////////////////////////


void save(const SkBitmap& bitmap, const char* filename);
 
// 文字列のバウンディングボックスを描画
void RenderBounding(SkScalar x, SkScalar y, SkString text,SkFont* font,SkCanvas* canvas, SkPaint* paint) {

    // バウンディングボックスを取得
    SkRect bounds;
    font->measureText(
        text.c_str(),
        strlen(text.c_str()),
        SkTextEncoding::kUTF8, 
        &bounds,
        paint
    );

    // バウンディングボックスをオフセットして描画位置を調整
    bounds.offset(x, y);

    // バウンディングボックスの描画
    paint->setStyle(SkPaint::kStroke_Style);
    canvas->drawRect(bounds, *paint);
    paint->setStyle(SkPaint::kFill_Style);
}

// テキスト描画のテスト
void TextTest() {
 
    // フォントマネージャ作成
    sk_sp<SkFontMgr> fontMgr = SkFontMgr_New_Custom_Directory("C:\\Windows\\Fonts\\"); // フォントが格納されているディレクトリ指定

    // フォント一覧作成
    sk_sp<SkTypeface> typeface[4] = {
        fontMgr->matchFamilyStyle("Amiri", SkFontStyle::Normal()     ),
        fontMgr->matchFamilyStyle("Amiri", SkFontStyle::Italic()     ),
        fontMgr->matchFamilyStyle("Amiri", SkFontStyle::Bold()       ),
        fontMgr->matchFamilyStyle("Amiri", SkFontStyle::BoldItalic() )
    };

    // 画像作成
    SkBitmap bmp;
    bmp.allocN32Pixels(600, 200);
    bmp.eraseColor(SK_ColorGRAY);

    // テキストの描画
    SkPaint paint;
    paint.setColor(SK_ColorBLACK); // テキストの色
    paint.setAntiAlias(false); // アンチエイリアスを有効にする

    SkCanvas* canvas = new SkCanvas(bmp);

    // フォントの設定
    SkFont font;
    font.setEdging(SkFont::Edging::kAntiAlias); // エッジングの設定
    font.setSize(50.f * 72 / 96); // テキストのサイズ。setSizeがポイントを受け取るのでピクセルから変換

    SkScalar x = 30.f; // テキストの位置(横)を設定
    SkScalar y = 0; // テキストの位置(縦)を設定

    SkFontMetrics metrics;
    for (auto face = std::begin(typeface); face != std::end(typeface); ++face) {

        font.setTypeface(*face); // フォントの設定

        font.getMetrics(&metrics);

        y -= metrics.fAscent;// テキストの位置(高さ)を設定

        SkString text;
        (*face)->getFamilyName(&text); // フォントファミリー名を取得

        RenderBounding(x, y, text, &font, canvas, &paint); // バウンディングボックスの描画
        canvas->drawString(text, x, y, font, paint);       // テキストの描画

    }
    //////////////////////////////////////////////////
    // ファイルに保存
    save(bmp, "test.png");
}

// 作成した画像を出力
void save(const SkBitmap& bitmap, const char* filename) { // optionsの設定 SkPngEncoder::Options options; options.fZLibLevel = 9; // 圧縮レベル options.fFilterFlags = SkPngEncoder::FilterFlag::kAll; // フィルタの種類 SkImageInfo info = bitmap.info(); unsigned char* pixels = (unsigned char*)bitmap.getPixels(); // 画像データの先頭アドレス size_t rowBytes = bitmap.rowBytes(); // 1行のバイト数 // bitmapをファイル保存 SkPixmap pixmap(info, pixels, rowBytes); SkFILEWStream stream(filename); SkPngEncoder::Encode(&stream, pixmap, options); }

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: