Ejemplo n.º 1
0
        void R_GetGlyphInfo(FT_GlyphSlot glyph, out int left, out int right, out int width, out int top, out int bottom, out int height, out int pitch)
        {
            left  = _FLOOR(glyph.metrics.horiBearingX);
            right = _CEIL(glyph.metrics.horiBearingX + glyph.metrics.width);
            width = _TRUNC(right - left);

            top    = _CEIL(glyph.metrics.horiBearingY);
            bottom = _FLOOR(glyph.metrics.horiBearingY - glyph.metrics.height);
            height = _TRUNC(top - bottom);
            pitch  = qtrue ? (width + 3) & -4 : (width + 7) >> 3;
        }
Ejemplo n.º 2
0
        FT_Bitmap R_RenderGlyph(FT_GlyphSlot glyph, GlyphInfo glyphOut)
        {
            FT_Bitmap bit2;

            R_GetGlyphInfo(glyph, out var left, out var right, out var width, out var top, out var bottom, out var height, out var pitch);

            if (glyph.format == ft_glyph_format_outline)
            {
                size = pitch * height;

                bit2 = Mem_Alloc(sizeof(FT_Bitmap));

                bit2.width      = width;
                bit2.rows       = height;
                bit2.pitch      = pitch;
                bit2.pixel_mode = ft_pixel_mode_grays;
                //bit2.pixel_mode = ft_pixel_mode_mono;
                bit2.buffer    = Mem_Alloc(pitch * height);
                bit2.num_grays = 256;

                memset(bit2.buffer, 0, size);

                FT_Outline_Translate(&glyph.outline, -left, -bottom);

                FT_Outline_Get_Bitmap(ftLibrary, &glyph.outline, bit2);

                glyphOut.height = height;
                glyphOut.pitch  = pitch;
                glyphOut.top    = (glyph.metrics.horiBearingY >> 6) + 1;
                glyphOut.bottom = bottom;

                return(bit2);
            }
            else
            {
                common.Printf("Non-outline fonts are not supported\n");
            }
            return(null);
        }
//    *
//	Run image manipulation
//	\return Pointer to image buffer which has been set in the constructor.
//	
	public override TextureBuffer process()
	{
		FT_Library ftlib = new FT_Library();
		FT_Face face = new FT_Face();
		FT_GlyphSlot slot = new FT_GlyphSlot();
	
		FT_Error error = FT_Init_FreeType(ftlib);
		if (error == 0)
		{
			error = FT_New_Face(ftlib, getFontFileByName().c_str(), 0, face);
			if (error == FT_Err_Unknown_File_Format)
				Utils.log("FreeType ERROR: FT_Err_Unknown_File_Format");
			else if (error != null)
				Utils.log("FreeType ERROR: FT_New_Face - " + StringConverter.toString(error));
			else
			{
				FT_Set_Pixel_Sizes(face, 0, mFontSize);
	
				int px = (int)mX;
				int py = (int)mY;
				slot = face.glyph;
	
				for (int n = 0; n < mText.length(); n++)
				{
					error = FT_Load_Char(face, mText[n], FT_LOAD_RENDER);
					if (error != null)
						continue;
	
					for (int i = 0; i < (int)slot.bitmap.width; i++)
					{
						for (int j = 0; j < (int)slot.bitmap.rows; j++)
						{
							if (slot.bitmap.buffer[j * slot.bitmap.width + i] > 127)
								mBuffer.setPixel(px + i, py + j, mColour);
						}
					}
	
					px += slot.advance.x >> 6;
					py += slot.advance.y >> 6;
				}
				FT_Done_Face(face);
				Utils.log("Modify texture with text processing : " + mText);
			}
			FT_Done_FreeType(ftlib);
		}
		else
			Utils.log("FreeType ERROR: FT_Init_FreeType");
		return mBuffer;
	}
//    *
//	 * Build a MultiShape from chars (one Shape per character)
//	 * \exception Ogre::InternalErrorException Freetype error
//	 * \todo Need to split shapes of multi region chars. For example the letter \c O
//	 * has two shapes, but they are connected to one shape.
//
        public MultiShape realizeShapes()
        {
            MultiShape retVal = new MultiShape();

            FT_Library   ftlib = new FT_Library();
            FT_Face      face  = new FT_Face();
            FT_GlyphSlot slot  = new FT_GlyphSlot();

            FT_Error error = FT_Init_FreeType(ftlib);

            if (error == 0)
            {
                error = FT_New_Face(ftlib, getFontFileByName().c_str(), 0, face);
                if (error == FT_Err_Unknown_File_Format)
                {
                    //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __LINE__ macro:
                    //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __FILE__ macro:
                    throw ExceptionFactory.create(Mogre.ExceptionCodeType <Mogre.Exception.ExceptionCodes.ERR_INTERNAL_ERROR>(), "FreeType ERROR: FT_Err_Unknown_File_Format", "Procedural::TextShape::realizeShapes()", __FILE__, __LINE__);
                    ;
                }
                else if (error != null)
                {
                    //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __LINE__ macro:
                    //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __FILE__ macro:
                    throw ExceptionFactory.create(Mogre.ExceptionCodeType <Mogre.Exception.ExceptionCodes.ERR_INTERNAL_ERROR>(), "FreeType ERROR: FT_New_Face - " + StringConverter.toString(error), "Procedural::TextShape::realizeShapes()", __FILE__, __LINE__);
                    ;
                }
                else
                {
                    FT_Set_Pixel_Sizes(face, 0, mFontSize);

                    int px = 0;
                    int py = 0;
                    slot = face.glyph;

                    for (int n = 0; n < mText.length(); n++)
                    {
                        error = FT_Load_Char(face, mText[n], FT_LOAD_NO_BITMAP);
                        if (error != null)
                        {
                            continue;
                        }

                        Shape s = new Shape();

                        int         nContours = face.glyph.outline.n_contours;
                        int         startPos  = 0;
                        string      tags      = face.glyph.outline.tags;
                        FT_Vector[] vec       = face.glyph.outline.points;

                        for (int k = 0; k < nContours; k++)
                        {
                            if (k > 0)
                            {
                                startPos = face.glyph.outline.contours[k - 1] + 1;
                            }
                            int endPos = face.glyph.outline.contours[k] + 1;

                            Vector2 lastPoint = Vector2.ZERO;
                            for (int j = startPos; j < endPos; j++)
                            {
                                if (FT_CURVE_TAG(tags[j]) == FT_CURVE_TAG_ON)
                                {
                                    lastPoint = Vector2((float)vec[j].x, (float)vec[j].y);
                                    s.addPoint(lastPoint / 64.0f);
                                }
                                else
                                {
                                    if (FT_CURVE_TAG(tags[j]) == FT_CURVE_TAG_CUBIC)
                                    {
                                        int prevPoint = j - 1;
                                        if (j == 0)
                                        {
                                            prevPoint = endPos - 1;
                                        }
                                        int nextIndex = j + 1;
                                        if (nextIndex >= endPos)
                                        {
                                            nextIndex = startPos;
                                        }
                                        Vector2[] nextPoint = new Vector2[nextIndex]((float)vec.x, (float)vec[nextIndex].y);
                                        if ((FT_CURVE_TAG(tags[prevPoint]) != FT_CURVE_TAG_ON) && (FT_CURVE_TAG(tags[prevPoint]) == FT_CURVE_TAG_CUBIC))
                                        {
                                            BezierCurve2 bc = new BezierCurve2();
                                            bc.addPoint(Vector2((float)vec[prevPoint].x, (float)vec[prevPoint].y) / 64.0f);
                                            bc.addPoint(Vector2((float)vec[j].x, (float)vec[j].y) / 64.0f);
                                            bc.addPoint(Vector2((float)vec[nextIndex].x, (float)vec[nextIndex].y) / 64.0f);
                                            s.appendShape(bc.realizeShape());
                                        }
                                    }
                                    else
                                    {
                                        Vector2[] conicPoint = new Vector2[j]((float)vec.x, (float)vec[j].y);
                                        if (j == startPos)
                                        {
                                            if ((FT_CURVE_TAG(tags[endPos - 1]) != FT_CURVE_TAG_ON) && (FT_CURVE_TAG(tags[endPos - 1]) != FT_CURVE_TAG_CUBIC))
                                            {
                                                Vector2[] lastConnic = new Vector2[endPos - 1]((float)vec.x, (float)vec[endPos - 1].y);
                                                lastPoint = (conicPoint + lastConnic) / 2;
                                            }
                                        }

                                        int nextIndex = j + 1;
                                        if (nextIndex >= endPos)
                                        {
                                            nextIndex = startPos;
                                        }

                                        Vector2[] nextPoint = new Vector2[nextIndex]((float)vec.x, (float)vec[nextIndex].y);

                                        bool nextIsConnic = (FT_CURVE_TAG(tags[nextIndex]) != FT_CURVE_TAG_ON) && (FT_CURVE_TAG(tags[nextIndex]) != FT_CURVE_TAG_CUBIC);
                                        if (nextIsConnic)
                                        {
                                            nextPoint = (conicPoint + nextPoint) / 2;
                                        }

                                        int          pc = s.getPointCount();
                                        BezierCurve2 bc = new BezierCurve2();
                                        if (pc == 0)
                                        {
                                            bc.addPoint(Vector2.ZERO);
                                        }
                                        else
                                        {
                                            bc.addPoint(s.getPoint(pc - 1));
                                        }
                                        bc.addPoint(lastPoint / 64.0f);
                                        bc.addPoint(conicPoint / 64.0f);
                                        bc.addPoint(nextPoint / 64.0f);
                                        if (pc == 0)
                                        {
                                            s.appendShape(bc.realizeShape());
                                        }
                                        else
                                        {
                                            List <Vector2> subShape = bc.realizeShape().getPoints();
                                            for (List <Vector2> .Enumerator iter = subShape.GetEnumerator(); iter.MoveNext(); iter++)
                                            {
                                                if (iter != subShape.GetEnumerator())
                                                {
                                                    s.addPoint(iter.Current);
                                                }
                                            }
                                        }

                                        if (nextIsConnic)
                                        {
//
//ORIGINAL LINE: lastPoint = nextPoint;
                                            lastPoint = (nextPoint);
                                        }
                                    }
                                }
                            }
                        }

                        s.close();
                        s.translate((float)px, (float)py);
                        retVal.addShape(s);

                        px += slot.advance.x >> 6;
                        py += slot.advance.y >> 6;
                    }
                    FT_Done_Face(face);
                }
                FT_Done_FreeType(ftlib);
            }
            else
            {
                //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __LINE__ macro:
                //C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __FILE__ macro:
                throw ExceptionFactory.create(Mogre.ExceptionCodeType <Mogre.Exception.ExceptionCodes.ERR_INTERNAL_ERROR>(), "FreeType ERROR: FT_Init_FreeTyp", "Procedural::TextShape::realizeShapes()", __FILE__, __LINE__);
                ;
            }

            return(retVal);
        }
//    *
//	 * Build a MultiShape from chars (one Shape per character)
//	 * \exception Ogre::InternalErrorException Freetype error
//	 * \todo Need to split shapes of multi region chars. For example the letter \c O
//	 * has two shapes, but they are connected to one shape.
//	 
	public MultiShape realizeShapes()
	{
		MultiShape retVal = new MultiShape();
	
		FT_Library ftlib = new FT_Library();
		FT_Face face = new FT_Face();
		FT_GlyphSlot slot = new FT_GlyphSlot();
	
		FT_Error error = FT_Init_FreeType(ftlib);
		if (error == 0)
		{
			error = FT_New_Face(ftlib, getFontFileByName().c_str(), 0, face);
			if (error == FT_Err_Unknown_File_Format)
			{
	//C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __LINE__ macro:
	//C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __FILE__ macro:
				throw ExceptionFactory.create(Mogre.ExceptionCodeType<Mogre.Exception.ExceptionCodes.ERR_INTERNAL_ERROR>(), "FreeType ERROR: FT_Err_Unknown_File_Format", "Procedural::TextShape::realizeShapes()", __FILE__, __LINE__);
				;
			}
			else if (error != null)
			{
	//C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __LINE__ macro:
	//C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __FILE__ macro:
				throw ExceptionFactory.create(Mogre.ExceptionCodeType<Mogre.Exception.ExceptionCodes.ERR_INTERNAL_ERROR>(), "FreeType ERROR: FT_New_Face - " + StringConverter.toString(error), "Procedural::TextShape::realizeShapes()", __FILE__, __LINE__);
				;
			}
			else
			{
				FT_Set_Pixel_Sizes(face, 0, mFontSize);
	
				int px = 0;
				int py = 0;
				slot = face.glyph;
	
				for (int n = 0; n < mText.length(); n++)
				{
					error = FT_Load_Char(face, mText[n], FT_LOAD_NO_BITMAP);
					if (error != null)
						continue;
	
					Shape s = new Shape();
	
					int nContours = face.glyph.outline.n_contours;
					int startPos = 0;
					string tags = face.glyph.outline.tags;
					FT_Vector[] vec = face.glyph.outline.points;
	
					for (int k = 0; k < nContours; k++)
					{
						if (k > 0)
							startPos = face.glyph.outline.contours[k-1]+1;
						int endPos = face.glyph.outline.contours[k]+1;
	
						Vector2 lastPoint = Vector2.ZERO;
						for (int j = startPos; j < endPos; j++)
						{
							if (FT_CURVE_TAG(tags[j]) == FT_CURVE_TAG_ON)
							{
								lastPoint = Vector2((float)vec[j].x, (float)vec[j].y);
								s.addPoint(lastPoint / 64.0f);
							}
							else
							{
								if (FT_CURVE_TAG(tags[j]) == FT_CURVE_TAG_CUBIC)
								{
									int prevPoint = j - 1;
									if (j == 0)
										prevPoint = endPos - 1;
									int nextIndex = j + 1;
									if (nextIndex >= endPos)
										nextIndex = startPos;
									Vector2[] nextPoint = new Vector2[nextIndex]((float)vec.x, (float)vec[nextIndex].y);
									if ((FT_CURVE_TAG(tags[prevPoint]) != FT_CURVE_TAG_ON) && (FT_CURVE_TAG(tags[prevPoint]) == FT_CURVE_TAG_CUBIC))
									{
										BezierCurve2 bc = new BezierCurve2();
										bc.addPoint(Vector2((float)vec[prevPoint].x, (float)vec[prevPoint].y) / 64.0f);
										bc.addPoint(Vector2((float)vec[j].x, (float)vec[j].y) / 64.0f);
										bc.addPoint(Vector2((float)vec[nextIndex].x, (float)vec[nextIndex].y) / 64.0f);
										s.appendShape(bc.realizeShape());
									}
								}
								else
								{
									Vector2[] conicPoint = new Vector2[j]((float)vec.x, (float)vec[j].y);
									if (j == startPos)
									{
										if ((FT_CURVE_TAG(tags[endPos-1]) != FT_CURVE_TAG_ON) && (FT_CURVE_TAG(tags[endPos-1]) != FT_CURVE_TAG_CUBIC))
										{
											Vector2[] lastConnic = new Vector2[endPos - 1]((float)vec.x, (float)vec[endPos - 1].y);
											lastPoint = (conicPoint + lastConnic) / 2;
										}
									}
	
									int nextIndex = j + 1;
									if (nextIndex >= endPos)
										nextIndex = startPos;
	
									Vector2[] nextPoint = new Vector2[nextIndex]((float)vec.x, (float)vec[nextIndex].y);
	
									bool nextIsConnic = (FT_CURVE_TAG(tags[nextIndex]) != FT_CURVE_TAG_ON) && (FT_CURVE_TAG(tags[nextIndex]) != FT_CURVE_TAG_CUBIC);
									if (nextIsConnic)
										nextPoint = (conicPoint + nextPoint) / 2;
	
									int pc = s.getPointCount();
									BezierCurve2 bc = new BezierCurve2();
									if (pc == 0)
										bc.addPoint(Vector2.ZERO);
									else
										bc.addPoint(s.getPoint(pc - 1));
									bc.addPoint(lastPoint / 64.0f);
									bc.addPoint(conicPoint / 64.0f);
									bc.addPoint(nextPoint / 64.0f);
									if (pc == 0)
										s.appendShape(bc.realizeShape());
									else
									{
										List<Vector2> subShape = bc.realizeShape().getPoints();
										for (List<Vector2>.Enumerator iter = subShape.GetEnumerator(); iter.MoveNext(); iter++)
										{
											if (iter != subShape.GetEnumerator())
												s.addPoint(iter.Current);
										}
									}
	
									if (nextIsConnic)
//
//ORIGINAL LINE: lastPoint = nextPoint;
										lastPoint=(nextPoint);
								}
							}
						}
					}
	
					s.close();
					s.translate((float)px, (float)py);
					retVal.addShape(s);
	
					px += slot.advance.x >> 6;
					py += slot.advance.y >> 6;
				}
				FT_Done_Face(face);
			}
			FT_Done_FreeType(ftlib);
		}
		else
		{
	//C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __LINE__ macro:
	//C++ TO C# CONVERTER TODO TASK: There is no direct equivalent in C# to the C++ __FILE__ macro:
			throw ExceptionFactory.create(Mogre.ExceptionCodeType<Mogre.Exception.ExceptionCodes.ERR_INTERNAL_ERROR>(), "FreeType ERROR: FT_Init_FreeTyp", "Procedural::TextShape::realizeShapes()", __FILE__, __LINE__);
			;
		}
	
		return retVal;
	}