Beispiel #1
0
    Color Color::Modulate(const Color& c) const
    {
        uint8 R = static_cast<uint8>(GetRed()   * c.GetRed()   / 255);
        uint8 G = static_cast<uint8>(GetGreen() * c.GetGreen() / 255);
        uint8 B = static_cast<uint8>(GetBlue()  * c.GetBlue()  / 255);
        uint8 A = static_cast<uint8>(GetAlpha() * c.GetAlpha() / 255);

        return Color(R, G, B, A);
    }
Beispiel #2
0
    Color Color::operator +(const Color& c) const
    {
        int R = GetRed()   + c.GetRed();
        int G = GetGreen() + c.GetGreen();
        int B = GetBlue()  + c.GetBlue();
        int A = GetAlpha() + c.GetAlpha();

        Color Ret;
        Ret.SetInt(R, G, B, A);

        return Ret;
    }
xui_method_explain(xui_family_create_win, get_bits, void*			)( const xui_family& family, u16 wc )
{
	add_font(family);

	gdiinfo* info = m_gdiinfo_map[family.to_string()];

	//draw char
	SolidBrush brush(Color::White);
	info->gdig->SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
	info->gdig->Clear(Color(0));
	info->gdig->DrawString(
		(LPWSTR)(&wc), 
		1, 
		info->gdif, 
		PointF(0.0f,0.0f), 
		StringFormat::GenericTypographic(), 
		&brush);

	//char size
	RectF rect;
	info->gdig->MeasureString(
		(LPWSTR)(&wc), 
		1, 
		info->gdif, 
		PointF(0.0f, 0.0f), 
		StringFormat::GenericTypographic(), 
		&rect);

	info->size.w = (s32)ceilf(rect.Width ); 
	info->size.h = (s32)ceilf(rect.Height);

	if (info->size.w == 0)
		info->size.w =  family.size / 2;

	//copy buffer
	s32 w = info->size.w;
	s32 h = info->size.h;

	Color color;
	for (s32 y = 0; y < h; ++y)
	{
		for (s32 x = 0; x < w; ++x)
		{
			info->gdib->GetPixel(x, y, &color);
			info->bits[y*w+x] = color.GetAlpha();
		}
	}

	return info->bits;
}
Beispiel #4
0
    //=================================================
    // Helper Functions
    //=================================================
    Color OffsetColor(Color clr, short sOffset)
    {
        BYTE bRed = 0;
        BYTE bGreen = 0;
        BYTE bBlue = 0;
        short sOffsetR = sOffset;
        short sOffsetG = sOffset;
        short sOffsetB = sOffset;

        if((sOffset < -255) || (sOffset > 255))
            return clr;

        // Get RGB components of specified color
        bRed = clr.GetR();
        bGreen = clr.GetG();
        bBlue = clr.GetB();

        // Calculate max. allowed real offset
        if(sOffset > 0)
        {
            if((bRed + sOffset) > 255)
                sOffsetR = (255 - bRed);
            if((bGreen + sOffset) > 255)
                sOffsetG = (255 - bGreen);
            if((bBlue + sOffset) > 255)
                sOffsetB = (255 - bBlue);

            sOffset = min(min(sOffsetR, sOffsetG), sOffsetB);
        }
        else
        {
            if((bRed + sOffset) < 0)
                sOffsetR = -bRed;
            if((bGreen + sOffset) < 0)
                sOffsetG = -bGreen;
            if((bBlue + sOffset) < 0)
                sOffsetB = -bBlue;

            sOffset = max(max(sOffsetR, sOffsetG), sOffsetB);
        }

        return Color(clr.GetAlpha(), (BYTE)(bRed + sOffset),
            (BYTE)(bGreen + sOffset), (BYTE)(bBlue + sOffset));
    }
Beispiel #5
0
int FontSheet::GetCharMaxX(Bitmap& charBitmap)
{
	int width  = charBitmap.GetWidth();
	int height = charBitmap.GetHeight();

	for(int x = width-1; x >= 0; --x)
	{
		for(int y = 0; y < height; ++y)
		{
			Color color;
			charBitmap.GetPixel(x, y, &color);
			if(color.GetAlpha() > 0)
			{
				 return x;
			}
		}
	}

	return width-1;
}
/**
 * \brief Test to see if we clicked on the image.
 * \param pos Position to test
 * \returns True if clicked on
 */
bool CImageDrawable::HitTest(Gdiplus::Point pos)
{
    Matrix mat;
    mat.Translate((float)mCenter.X, (float)mCenter.Y);
    mat.Rotate((float)(mPlacedR * RtoD));
    mat.Translate((float)-mPlacedPosition.X, (float)-mPlacedPosition.Y);

    Point points[] = { pos };
    mat.TransformPoints(points, 1);

    double wid = mImage->GetWidth();
    double hit = mImage->GetHeight();

    double testX = points[0].X;
    double testY = points[0].Y;

    // Test to see if x, y are in the image
    if (testX < 0 || testY < 0 || testX >= wid || testY >= hit)
    {
        // We are outside the image
        return false;
    }

    // Test to see if x, y are in the drawn part of the image
    auto format = mImage->GetPixelFormat();
    if (format == PixelFormat32bppARGB || format == PixelFormat32bppPARGB)
    {
        // This image has an alpha map, which implements the 
        // transparency. If so, we should check to see if we
        // clicked on a pixel where alpha is not zero, meaning
        // the pixel shows on the screen.
        Color color;
        mImage->GetPixel((int)testX, (int)testY, &color);
        return color.GetAlpha() != 0;
    }
    else {
        return true;
    }
}
Beispiel #7
0
//---------------------------------------------------------------------------
int GetCharMaxX(Gdiplus::Bitmap& charBitmap)
{
    using namespace Gdiplus;

	int width  = charBitmap.GetWidth();
	int height = charBitmap.GetHeight();

	for(int x = width-1; x >= 0; --x)
	{
		for(int y = 0; y < height; ++y)
		{
			Color color;
			charBitmap.GetPixel(x, y, &color);
			if(color.GetAlpha() > 0)
			{
				 return x;
			}
		}
	}

	return width-1;
}
IrisColor* IrisBitmap::GetPixel(int x, int y){
	Color color;
	this->bitmap->GetPixel(x, y, &color);
	return new IrisColor(color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha());
}
Beispiel #9
0
bool D3D11::FGdiFont::Reload()
{
	assert(FRenderContext::Get()->InRenderThread());

	const char* head = "FGdiFont::Reload";
	bool dirtChars = false;
	bool dirtConfig = false;
	std::set<WCHAR> inputChars;
	{
		lock_guard<mutex> lck(Mutex);
		inputChars.insert(PendingCharacters.begin(), PendingCharacters.end());

		if (PendingConfig != nullptr)
		{
			Property.Config = *PendingConfig;
			SAFE_DELETE(PendingConfig);
			dirtConfig = true;
		}
	}

	inputChars.insert(Property.Characters.begin(), Property.Characters.end());
	dirtChars = Property.Characters != inputChars;
	if (!dirtConfig && !dirtChars)
	{
		return true;
	}

	auto& config = Property.Config;

	auto& td = Property.TextureDescription;
	td.TextureWidth = STexWidth;

	Property.CharacterDescriptions.clear();
	Property.Characters.clear();

	std::vector<WCHAR> vecChars(inputChars.begin(), inputChars.end());

	Property.FontTexture = (new FTexture2D);

	auto hint = config.bAntiAliased ? TextRenderingHintAntiAliasGridFit : TextRenderingHintSingleBitPerPixelGridFit;
	hint = TextRenderingHintClearTypeGridFit;

	LOGFONTW lf;
	wcscpy_s(lf.lfFaceName, config.FontName.c_str());
	lf.lfHeight = (int32)-config.Height;
	lf.lfWidth = 0;
	lf.lfWeight = config.Weight;
	lf.lfItalic = config.bItalic;
	lf.lfUnderline = config.bUnderline;
	lf.lfStrikeOut = 0;
	lf.lfCharSet = config.CharSet;
	lf.lfOutPrecision = config.OutPrecision;
	lf.lfClipPrecision = config.ClipPrecision;
	lf.lfQuality = config.Quality;
	lf.lfPitchAndFamily = config.PitchAndFamily;

	ULONG_PTR token = NULL;
	GdiplusStartupInput startupInput(NULL, TRUE, TRUE);
	GdiplusStartupOutput startupOutput;
	Gdiplus::Status ret;
	if (Gdiplus::Ok != (ret = GdiplusStartup(&token, &startupInput, &startupOutput)))
	{
		LVERR(head, "GdiplusStartup failed: %d", ret);
		return false;
	}

	HDC hFont = ::GetDC(NULL);
	Gdiplus::Font font(hFont, &lf);
	if (Gdiplus::Ok != (ret = font.GetLastStatus()))
	{
		LVERR(head, "Gdiplus::Font::GetLastStatus failed: %d", ret);
		RETURN_FALSE;
	}

	int32 size = (int32)(config.Height) * vecChars.size();
	Bitmap bmp(size, size, PixelFormat32bppARGB);
	if (Gdiplus::Ok != (ret = bmp.GetLastStatus()))
	{
		LVERR(head, "Bitmap::GetLastStatus failed: %d", ret);
		RETURN_FALSE;
	}

	Graphics graphics(&bmp);
	if (Gdiplus::Ok != (ret = graphics.GetLastStatus()))
	{
		LVERR(head, "Graphics::GetLastStatus failed: %d", ret);
		RETURN_FALSE;
	}

	if (Gdiplus::Ok != (ret = graphics.SetTextRenderingHint(hint)))
	{
		LVERR(head, "Graphics::SetTextRenderingHint failed: %d", ret);
		RETURN_FALSE;
	}

	Property.CharHeight = font.GetHeight(&graphics);

	RectF rect;
	if (Gdiplus::Ok != (ret = graphics.MeasureString(vecChars.data(), vecChars.size(), &font, PointF(0, 0), &rect)))
	{
		LVERR(head, "Graphics::MeasureString failed: %d", ret);
		RETURN_FALSE;
	}

	int32 numRows = (int32)(rect.Width / td.TextureWidth) + 1;
	td.TextureHeight = (int32)(numRows * Property.CharHeight) + 1;

	int32 tsz = (int32)config.Height * 2;
	Bitmap bmp2(tsz, tsz, PixelFormat32bppARGB);
	if (Gdiplus::Ok != (ret = bmp2.GetLastStatus()))
	{
		LVERR(head, "Bitmap::GetLastStatus failed: %d", ret);
		RETURN_FALSE;
	}

	Graphics graphics2(&bmp2);
	if (Gdiplus::Ok != (ret = graphics2.GetLastStatus()))
	{
		LVERR(head, "Graphics::GetLastStatus failed: %d", ret);
		RETURN_FALSE;
	}

	if (Gdiplus::Ok != (ret = graphics2.SetTextRenderingHint(hint)))
	{
		LVERR(head, "Graphics::SetTextRenderingHint failed: %d", ret);
		RETURN_FALSE;
	}

	Bitmap bmp3(td.TextureWidth, td.TextureHeight, PixelFormat32bppARGB);
	if (Gdiplus::Ok != (ret = bmp3.GetLastStatus()))
	{
		LVERR(head, "Bitmap::GetLastStatus failed: %d", ret);
		RETURN_FALSE;
	}

	Graphics graphics3(&bmp3);
	if (Gdiplus::Ok != (ret = graphics3.GetLastStatus()))
	{
		LVERR(head, "Graphics::GetLastStatus failed: %d", ret);
		RETURN_FALSE;
	}

	if (Gdiplus::Ok != (ret = graphics3.Clear(Color(0, 255, 255, 255))))
	{
		LVERR(head, "Graphics::Clear failed: %d", ret);
		RETURN_FALSE;
	}

	if (Gdiplus::Ok != (ret = graphics3.SetCompositingMode(CompositingModeSourceCopy)))
	{
		LVERR(head, "Graphics::SetCompositingMode failed: %d", ret);
		RETURN_FALSE;
	}

	SolidBrush brush(Color(255, 255, 255, 255));
	if (Gdiplus::Ok != (ret = brush.GetLastStatus()))
	{
		LVERR(head, "SolidBrush::GetLastStatus failed: %d", ret);
		RETURN_FALSE;
	}

	int32 currX = 0;
	int32 currY = 0;
	for (auto it = inputChars.begin(); it != inputChars.end(); ++it)
	{
		WCHAR wc = *it;

		// 跳过不绘制的字符
		if (wc == ' ')
		{
			Property.Characters.insert(wc);
			Property.CharacterDescriptions.insert(FCharacterDescription(wc));
			continue;
		}

		if (Gdiplus::Ok != (ret = graphics2.Clear(Color(0, 255, 255, 255))))
		{
			LVERR(head, "graphics2::Clear failed: %d", ret);
			RETURN_FALSE;
		}

		if (Gdiplus::Ok != (ret = graphics2.DrawString(&wc, 1, &font, PointF(0, 0), &brush)))
		{
			LVERR(head, "graphics2::DrawString failed: %d", ret);
			RETURN_FALSE;
		}

		int32 minX = 0;
		for (int32 x = 0; x < tsz; ++x)
		{
			for (int32 y = 0; y < tsz; ++y)
			{
				Color col;
				if (Gdiplus::Ok != (ret = bmp2.GetPixel(x, y, &col)))
				{
					LVERR(head, "Bitmap::GetPixel failed: %d", ret);
					RETURN_FALSE;
				}

				if (col.GetAlpha() > 0)
				{
					minX = x;
					x = tsz;
					break;
				}
			}
		}

		int32 maxX = tsz - 1;
		for (int32 x = tsz - 1; x >= 0; --x)
		{
			for (int32 y = 0; y < tsz; ++y)
			{
				Color col;
				if (Gdiplus::Ok != (ret = bmp2.GetPixel(x, y, &col)))
				{
					LVERR(head, "Bitmap::GetPixel failed: %d", ret);
					RETURN_FALSE;
				}

				if (col.GetAlpha() > 0)
				{
					maxX = x;
					x = -1;
					break;
				}
			}
		}

		int32 charWidth = maxX - minX + 1;
		if (currX + charWidth >= td.TextureWidth)
		{
			currX = 0;
			currY += (int32)(Property.CharHeight) + 1;
		}

		Property.Characters.insert(wc);
		Property.CharacterDescriptions.insert(FCharacterDescription(wc, currX, currY, charWidth, (int32)Property.CharHeight));

		int32 height = (int32)(Property.CharHeight) + 1;
		if (Gdiplus::Ok != (ret = graphics3.DrawImage(&bmp2, currX, currY, minX, 0, charWidth, height, UnitPixel)))
		{
			LVERR(head, "Graphics::DrawImage failed: %d", ret);
			RETURN_FALSE;
		}

		currX += charWidth + 1;
	}

	const WCHAR space = ' ';
	if (Gdiplus::Ok != (ret = graphics2.MeasureString(&space, 1, &font, PointF(0, 0), &rect)))
	{
		LVERR(head, "Graphics::MeasureString failed: %d", ret);
		RETURN_FALSE;
	}

	// 如果字符串里有空格
	td.SpaceWidth = rect.Width;
	Property.CharacterDescriptions.insert(FCharacterDescription(space, 0, 0, rect.Width, (int32)Property.CharHeight));

	BitmapData bmpData;
	if (Gdiplus::Ok != (ret = bmp3.LockBits(&Rect(0, 0, td.TextureWidth, 
		td.TextureHeight), ImageLockModeRead, PixelFormat32bppARGB, &bmpData)))
	{
		LVERR(head, "Bitmap::LockBits failed: %d", ret);
		RETURN_FALSE;
	}

	Property.FontTexture->Construct(td.TextureWidth, td.TextureHeight,
		DXGI_FORMAT_B8G8R8A8_UNORM, false, false, true, false, bmpData.Scan0, td.TextureWidth * 4);

	bmp3.UnlockBits(&bmpData);

	::ReleaseDC(NULL, hFont);
	return true;
}
Beispiel #10
0
/*
** Read the meter-specific options from the ini-file.
**
*/
void TintedImage::ReadOptions(ConfigParser& parser, const WCHAR* section, const WCHAR* imagePath)
{
	// Store the current values so we know if the image needs to be tinted or transformed
	Rect oldCrop = m_Crop;
	CROPMODE oldCropMode = m_CropMode;
	bool oldGreyScale = m_GreyScale;
	ColorMatrix oldColorMatrix = *m_ColorMatrix;
	RotateFlipType oldFlip = m_Flip;
	REAL oldRotate = m_Rotate;
	std::wstring oldPath = m_Path;

	m_Path = parser.ReadString(section, m_OptionArray[OptionIndexImagePath], imagePath);
	PathUtil::AppendBacklashIfMissing(m_Path);

	m_HasPathChanged = (oldPath != m_Path);

	if (!m_DisableTransform)
	{
		m_Crop.X = m_Crop.Y = m_Crop.Width = m_Crop.Height = -1;
		m_CropMode = CROPMODE_TL;

		const std::wstring& crop = parser.ReadString(section, m_OptionArray[OptionIndexImageCrop], L"");
		if (!crop.empty())
		{
			if (wcschr(crop.c_str(), L','))
			{
				WCHAR* parseSz = _wcsdup(crop.c_str());
				WCHAR* token;

				token = wcstok(parseSz, L",");
				if (token)
				{
					m_Crop.X = parser.ParseInt(token, 0);

					token = wcstok(nullptr, L",");
					if (token)
					{
						m_Crop.Y = parser.ParseInt(token, 0);

						token = wcstok(nullptr, L",");
						if (token)
						{
							m_Crop.Width = parser.ParseInt(token, 0);

							token = wcstok(nullptr, L",");
							if (token)
							{
								m_Crop.Height = parser.ParseInt(token, 0);

								token = wcstok(nullptr, L",");
								if (token)
								{
									m_CropMode = (CROPMODE)parser.ParseInt(token, 0);
								}
							}
						}
					}
				}
				free(parseSz);
			}

			if (m_CropMode < CROPMODE_TL || m_CropMode > CROPMODE_C)
			{
				m_CropMode = CROPMODE_TL;
				LogErrorF(m_Skin, L"%s=%s (origin) is not valid in [%s]",  m_OptionArray[OptionIndexImageCrop], crop, section);
			}
		}
	}

	m_NeedsCrop = (oldCrop.X != m_Crop.X || oldCrop.Y != m_Crop.Y || oldCrop.Width != m_Crop.Width || oldCrop.Height != m_Crop.Height || oldCropMode != m_CropMode);

	m_GreyScale = parser.ReadBool(section, m_OptionArray[OptionIndexGreyscale], false);

	Color tint = parser.ReadColor(section, m_OptionArray[OptionIndexImageTint], Color::White);
	int alpha = parser.ReadInt(section, m_OptionArray[OptionIndexImageAlpha], tint.GetAlpha());  // for backwards compatibility
	alpha = min(255, alpha);
	alpha = max(0, alpha);

	*m_ColorMatrix = c_IdentityMatrix;

	// Read in the Color Matrix
	// It has to be read in like this because it crashes when reading over 17 floats
	// at one time. The parser does it fine, but after putting the returned values
	// into the Color Matrix the next time the parser is used it crashes.
	std::vector<Gdiplus::REAL> matrix1 = parser.ReadFloats(section, m_OptionArray[OptionIndexColorMatrix1]);
	if (matrix1.size() == 5)
	{
		for (int i = 0; i < 4; ++i)  // The fifth column must be 0.
		{
			m_ColorMatrix->m[0][i] = matrix1[i];
		}
	}
	else
	{
		m_ColorMatrix->m[0][0] = (REAL)tint.GetRed() / 255.0f;
	}

	std::vector<Gdiplus::REAL> matrix2 = parser.ReadFloats(section, m_OptionArray[OptionIndexColorMatrix2]);
	if (matrix2.size() == 5)
	{
		for (int i = 0; i < 4; ++i)  // The fifth column must be 0.
		{
			m_ColorMatrix->m[1][i] = matrix2[i];
		}
	}
	else
	{
		m_ColorMatrix->m[1][1] = (REAL)tint.GetGreen() / 255.0f;
	}

	std::vector<Gdiplus::REAL> matrix3 = parser.ReadFloats(section, m_OptionArray[OptionIndexColorMatrix3]);
	if (matrix3.size() == 5)
	{
		for (int i = 0; i < 4; ++i)  // The fifth column must be 0.
		{
			m_ColorMatrix->m[2][i] = matrix3[i];
		}
	}
	else
	{
		m_ColorMatrix->m[2][2] = (REAL)tint.GetBlue() / 255.0f;
	}

	std::vector<Gdiplus::REAL> matrix4 = parser.ReadFloats(section, m_OptionArray[OptionIndexColorMatrix4]);
	if (matrix4.size() == 5)
	{
		for (int i = 0; i < 4; ++i)  // The fifth column must be 0.
		{
			m_ColorMatrix->m[3][i] = matrix4[i];
		}
	}
	else
	{
		m_ColorMatrix->m[3][3] = (REAL)alpha / 255.0f;
	}

	std::vector<Gdiplus::REAL> matrix5 = parser.ReadFloats(section, m_OptionArray[OptionIndexColorMatrix5]);
	if (matrix5.size() == 5)
	{
		for (int i = 0; i < 4; ++i)  // The fifth column must be 1.
		{
			m_ColorMatrix->m[4][i] = matrix5[i];
		}
	}

	m_NeedsTinting = (oldGreyScale != m_GreyScale || !CompareColorMatrix(&oldColorMatrix, m_ColorMatrix));

	m_UseExifOrientation = parser.ReadBool(section, m_OptionArray[OptionIndexUseExifOrientation], false);

	const WCHAR* flip = parser.ReadString(section, m_OptionArray[OptionIndexImageFlip], L"NONE").c_str();
	if (_wcsicmp(flip, L"NONE") == 0)
	{
		m_Flip = RotateNoneFlipNone;
	}
	else if (_wcsicmp(flip, L"HORIZONTAL") == 0)
	{
		m_Flip = RotateNoneFlipX;
	}
	else if (_wcsicmp(flip, L"VERTICAL") == 0)
	{
		m_Flip = RotateNoneFlipY;
	}
	else if (_wcsicmp(flip, L"BOTH") == 0)
	{
		m_Flip = RotateNoneFlipXY;
	}
	else
	{
		LogErrorF(m_Skin, L"%s=%s (origin) is not valid in [%s]",  m_OptionArray[OptionIndexImageFlip], flip, section);
	}

	if (!m_DisableTransform)
	{
		m_Rotate = (REAL)parser.ReadFloat(section, m_OptionArray[OptionIndexImageRotate], 0.0);
	}

	m_NeedsTransform = (oldFlip != m_Flip || oldRotate != m_Rotate);
}
inline void ToGDIColor(const Color& source, Gdiplus::Color& target) {
    target = Gdiplus::Color(source.GetAlpha(), source.GetRed(), source.GetGreen(), source.GetBlue());
}