スポンサーリンク

Skiaでフォント利用(3)文字列のバウンディングボックスを取得

文字列を囲むボックスを描画する

#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() {
    
    std::vector<sk_sp<SkData>> fontDataList;

    // フォントマネージャ作成
    sk_sp<SkFontMgr> fontMgr = SkFontMgr_New_Custom_Directory("C:\\Windows\\Fonts\\"); // フォントが格納されているディレクトリ指定
    auto sk = fontMgr->matchFamily("MS PGothic");
    sk_sp<SkTypeface> typeface = sk->createTypeface(0); // フォントの取得 0 は通常。1~はボールド・イタリック等

    // 画像作成
    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がポイントを受け取るのでピクセルから変換
    font.setTypeface(typeface); // フォントの設定

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

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

    SkString text;
    typeface->getFamilyName(&text); // フォントファミリー名を取得
    text.append(u8" : 日本語");

    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: