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; }
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; }