のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

Raspberry Piで、Freetypeの出力をOpenVGで表示

static void MyRenderNative(NATIVE_FONT_INFO *nfi, NATIVE_OPENVG_INFO *nopvgi,
		NATIVE_VIEWER_INFO *nvi) {
	uint top_space = 1;
	uint bottom_space = 1;
	uint left_space = 1;
	uint right_space = 1;
	uint oneChar_width = 0;
	uint oneChar_height = 0;

	uint max_row = 0;
	uint max_col = 0;
	uint row = 0;
	uint col = 0;
	int tmpx = 0;
	int tmpy = 0;

	float clearColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };

	enum ERROR_CODE {
		RTN_OK = 0
	};

	VGfloat scale_x = 1.0f;
	VGfloat scale_y = 1.0f;

	if (isInitialized(nfi) != MY_TRUE) {
		return;
	}

	uintToVgColor(nopvgi->fontBg, clearColor, sizeof(clearColor));

	/* Clear Color */
	Start(nopvgi->screenWidth, nopvgi->screenHeight, clearColor);
	vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
	assert(vgGetError() == VG_NO_ERROR);

	/* 描画設定 */
	setRenderingQuality(nopvgi->renderingQuality);

//	vgSeti(VG_MATRIX_MODE, VG_MATRIX_GLYPH_USER_TO_SURFACE);
	vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE);
	assert(vgGetError() == VG_NO_ERROR);

	// Scale
	vgLoadIdentity();
	vgScale(scale_x, scale_y);
	assert(vgGetError() == VG_NO_ERROR);

	// VgImage
	VGImageFormat fmt = VG_lL_8; //VG_lRGBA_8888;
	VGbitfield quality = VG_IMAGE_QUALITY_BETTER;
	VGImage img = vgCreateImage(fmt, nopvgi->screenWidth, nopvgi->screenHeight,
			quality);
	assert(vgGetError() == VG_NO_ERROR);

	// Char Size
	FT_Error error = 0;
	assert(nfi->face != 0);
	error = FT_Set_Pixel_Sizes(nfi->face, nfi->width, nfi->height);
	if (error) {
		printf("Error:FT_Set_Pixel_Sizes error=0x%08X w=%d, h=%d\n", error,
				nfi->width, nfi->height);

	}

	oneChar_width = left_space + right_space + nfi->width;
	oneChar_height = top_space + bottom_space + nfi->height;

	// 表示できる最大の文字数
	max_row = nopvgi->screenHeight / oneChar_height; // 行の数(Y)
	max_col = nopvgi->screenWidth / oneChar_width;  // 列の数(X)

	if (max_row > nvi->numY) {
		max_row = nvi->numY;
	}
	if (max_col > nvi->numX) {
		max_col = nvi->numX;
	}

	printf("MaxRow=%4d, MaxCol=%4d sum=%d\n", max_row, max_col,
			max_row * max_col);
	/* フォント関係 */
	FT_Int32 load_flags = FT_LOAD_DEFAULT;
	FT_ULong charcode = nfi->code;
	FT_UInt glyph_index = 0;
	FT_GlyphSlot slot = nfi->face->glyph;
	for (row = 0; row < max_row; row++) {
		for (col = 0; col < max_col; col++) {
			// 左下が原点なのでY軸を反転
			tmpy = nopvgi->orgY + (nopvgi->screenHeight - 1)
					- (row + 1) * oneChar_height;
			tmpx = nopvgi->orgX + col * oneChar_width;

			glyph_index = FT_Get_Char_Index(nfi->face, charcode);
			error = FT_Load_Glyph(nfi->face, glyph_index, load_flags);
			if (error) {
				printf("Error:FT_Load_Glyph Code=0x%08X\n", (uint) charcode);
				goto NEXT;
			}

			FT_Render_Mode render_mode = FT_RENDER_MODE_NORMAL;
			error = FT_Render_Glyph(nfi->face->glyph, render_mode);
			if (error) {
				printf("Error:FT_Render_Glyph Code=0x%08X\n", (uint) charcode);
				goto NEXT;
			}

			VGErrorCode vgError = VG_NO_ERROR;
			uchar *data = slot->bitmap.buffer
					+ slot->bitmap.pitch * (slot->bitmap.rows - 1);
			VGint w = slot->bitmap.width;
			VGint h = slot->bitmap.rows;
			VGint pitch = -slot->bitmap.pitch;
			VGint x = tmpx + slot->bitmap_left;
			VGint y = tmpy - slot->bitmap_top;
			if ((w == 0) || (h == 0)) {
				goto NEXT;
			}
			vgImageSubData(img, data, pitch, fmt, x, y, w, h);
			if ((vgError = vgGetError()) != VG_NO_ERROR) {
				printf("Error:VgError=0x%08X code=0x%08lX"
						"tmpx=%d tmpy=%d x=%d y=%d w=%d h=%d\n", vgError,
						charcode, tmpx, tmpy, x, y, w, h);
				goto NEXT;
			}
//			assert(vgGetError() == VG_NO_ERROR);

			vgDrawImage(img);
			assert(vgGetError() == VG_NO_ERROR);

			NEXT:
			//End();
			charcode++;
		}
	}

	vgFinish();
	End();

	if (img != VG_INVALID_HANDLE ) {
		vgDestroyImage(img);
		assert(vgGetError() == VG_NO_ERROR);
	}
}