/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Netscape Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Brian Stell * Louie Zhao * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the NPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifdef DEBUG // set this to 1 to have the code draw the bounding boxes #define DEBUG_SHOW_GLYPH_BOX 0 #endif #include "gfx-config.h" #include "nsFontFreeType.h" #include "nsUnicharUtils.h" #if (!defined(MOZ_ENABLE_FREETYPE2)) nsFreeTypeFont * nsFreeTypeFont::NewFont(nsITrueTypeFontCatalogEntry *, PRUint16, const char *) { return nsnull; } #else #include "nsX11AlphaBlend.h" #include "nsAntiAliasedGlyph.h" #include "nsFontDebug.h" #include "nsIServiceManager.h" // macros to handle FreeType2 16.16 numbers #define FT_16_16_TO_REG(x) ((x)>>16) #define IMAGE_BUFFER_SIZE 2048 PRUint32 deltaMicroSeconds(PRTime aStartTime, PRTime aEndTime); void GetFallbackGlyphMetrics(FT_BBox *aBoundingBox, FT_Face aFace); PRUint8 nsFreeTypeFont::sLinearWeightTable[256]; // // class nsFreeTypeXImage definition // class nsFreeTypeXImage : public nsFreeTypeFont { public: nsFreeTypeXImage(nsITrueTypeFontCatalogEntry *aFaceID, PRUint16 aPixelSize, const char *aName); gint DrawString(nsRenderingContextGTK* aContext, nsDrawingSurfaceGTK* aSurface, nscoord aX, nscoord aY, const PRUnichar* aString, PRUint32 aLength); protected: nsFreeTypeXImage(); }; // // class nsFreeTypeXImageSBC (Single Byte Converter) definition // class nsFreeTypeXImageSBC : public nsFreeTypeXImage { public: nsFreeTypeXImageSBC(nsITrueTypeFontCatalogEntry *aFaceID, PRUint16 aPixelSize, const char *aName); #ifdef MOZ_MATHML virtual nsresult GetBoundingMetrics(const PRUnichar* aString, PRUint32 aLength, nsBoundingMetrics& aBoundingMetrics); #endif virtual gint GetWidth(const PRUnichar* aString, PRUint32 aLength); virtual gint DrawString(nsRenderingContextGTK* aContext, nsDrawingSurfaceGTK* aSurface, nscoord aX, nscoord aY, const PRUnichar* aString, PRUint32 aLength); protected: nsFreeTypeXImageSBC(); }; #ifdef ENABLE_TIME_MACROS PRUint32 deltaMicroSeconds(PRTime aStartTime, PRTime aEndTime) { PRUint32 delta; PRUint64 loadTime64; LL_SUB(loadTime64, aEndTime, aStartTime); LL_L2UI(delta, loadTime64); return delta; } #endif // // class nsFreeTypeFont data/functions // nsFreeTypeFont::nsFreeTypeFont() { NS_ERROR("should never call nsFreeTypeFont::nsFreeTypeFont"); } nsFreeTypeFont * nsFreeTypeFont::NewFont(nsITrueTypeFontCatalogEntry *aFaceID, PRUint16 aPixelSize, const char *aName) { // Make sure FreeType is available nsresult rv; nsCOMPtr ft2 = do_GetService(NS_FREETYPE2_CONTRACTID, &rv); if (NS_FAILED(rv)) { NS_ERROR("FreeType2 routines not available"); return nsnull; } // for now we only support ximage (XGetImage/alpha-blend/XPutImage) display // when we support XRender then we will need to test if it is // available and if so use it since it is faster than ximage. PRBool ximage = PR_TRUE; PRBool render = PR_FALSE; nsFreeTypeFont *ftfont; nsCAutoString familyName; aFaceID->GetFamilyName(familyName); nsTTFontFamilyEncoderInfo *ffei = nsFreeType2::GetCustomEncoderInfo(familyName.get()); if (ximage) { if (ffei) { ftfont = new nsFreeTypeXImageSBC(aFaceID, aPixelSize, aName); } else { ftfont = new nsFreeTypeXImage(aFaceID, aPixelSize, aName); } return ftfont; } else if (render) { NS_ERROR("need to construct a render type FreeType object"); return nsnull; } NS_ERROR("need to construct other type FreeType objects"); return nsnull; } FT_Face nsFreeTypeFont::getFTFace() { FT_Face face = nsnull; FTC_Manager mgr; nsresult rv; mFt2->GetFTCacheManager(&mgr); rv = mFt2->ManagerLookupSize(mgr, &mImageDesc.font, &face, nsnull); NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get face/size"); if (NS_FAILED(rv)) return nsnull; return face; } nsFreeTypeFont::nsFreeTypeFont(nsITrueTypeFontCatalogEntry *aFaceID, PRUint16 aPixelSize, const char *aName) { PRBool anti_alias = PR_TRUE; PRBool embedded_bimap = PR_FALSE; mFaceID = aFaceID; mPixelSize = aPixelSize; mImageDesc.font.face_id = (void*)mFaceID; mImageDesc.font.pix_width = aPixelSize; mImageDesc.font.pix_height = aPixelSize; mImageDesc.image_type = 0; if (aPixelSize < nsFreeType2::gAntiAliasMinimum) { mImageDesc.image_type |= ftc_image_mono; anti_alias = PR_FALSE; } if (nsFreeType2::gFreeType2Autohinted) mImageDesc.image_type |= ftc_image_flag_autohinted; if (nsFreeType2::gFreeType2Unhinted) mImageDesc.image_type |= ftc_image_flag_unhinted; PRUint32 num_embedded_bitmaps, i; PRInt32* embedded_bitmapheights; mFaceID->GetEmbeddedBitmapHeights(&num_embedded_bitmaps, &embedded_bitmapheights); // check if we have an embedded bitmap if (aPixelSize <= nsFreeType2::gEmbeddedBitmapMaximumHeight) { if (num_embedded_bitmaps) { for (i=0; iGetCCMap(&size, &mCCMap); #ifdef NS_FONT_DEBUG_LOAD_FONT nsCAutoString fileName; mFaceID->GetFileName(fileName); if (gFontDebug & NS_FONT_DEBUG_LOAD_FONT) { printf("loaded \"%s\", size=%d, filename=%s\n", mName, mSize, fileName.get()); } #endif } nsFreeTypeFont::~nsFreeTypeFont() { } #ifdef MOZ_MATHML nsresult nsFreeTypeFont::GetBoundingMetrics(const PRUnichar* aString, PRUint32 aLength, nsBoundingMetrics& aBoundingMetrics) { return doGetBoundingMetrics(aString, aLength, &aBoundingMetrics.leftBearing, &aBoundingMetrics.rightBearing, &aBoundingMetrics.ascent, &aBoundingMetrics.descent, &aBoundingMetrics.width); } #endif nsresult nsFreeTypeFont::doGetBoundingMetrics(const PRUnichar* aString, PRUint32 aLength, PRInt32* aLeftBearing, PRInt32* aRightBearing, PRInt32* aAscent, PRInt32* aDescent, PRInt32* aWidth) { nsresult rv; *aLeftBearing = 0; *aRightBearing = 0; *aAscent = 0; *aDescent = 0; *aWidth = 0; if (aLength < 1) { return NS_ERROR_FAILURE; } FT_Pos pos = 0; FT_BBox bbox; // initialize to "uninitialized" values bbox.xMin = bbox.yMin = 32000; bbox.xMax = bbox.yMax = -32000; // get the face/size from the FreeType cache FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face) return NS_ERROR_FAILURE; FTC_Image_Cache icache; mFt2->GetImageCache(&icache); if (!icache) return NS_ERROR_FAILURE; // get the text size PRUint32 i, extraSurrogateLength; for (i=0; iGetCharIndex(face, code_point, &glyph_index); //NS_ASSERTION(glyph_index,"failed to get glyph"); if (glyph_index) { rv = mFt2->ImageCacheLookup(icache, &mImageDesc, glyph_index, &glyph); NS_ASSERTION(NS_SUCCEEDED(rv),"error loading glyph"); } if ((glyph_index) && (NS_SUCCEEDED(rv))) { mFt2->GlyphGetCBox(glyph, ft_glyph_bbox_pixels, &glyph_bbox); advance = FT_16_16_TO_REG(glyph->advance.x); } else { // allocate space to draw an empty box in GetFallbackGlyphMetrics(&glyph_bbox, face); advance = glyph_bbox.xMax + 1; } bbox.xMin = PR_MIN(pos+glyph_bbox.xMin, bbox.xMin); bbox.xMax = PR_MAX(pos+glyph_bbox.xMax, bbox.xMax); bbox.yMin = PR_MIN(glyph_bbox.yMin, bbox.yMin); bbox.yMax = PR_MAX(glyph_bbox.yMax, bbox.yMax); pos += advance; } // check we got at least one size if (bbox.xMin > bbox.xMax) bbox.xMin = bbox.xMax = bbox.yMin = bbox.yMax = 0; *aLeftBearing = bbox.xMin; *aRightBearing = bbox.xMax; *aAscent = bbox.yMax; *aDescent = -bbox.yMin; *aWidth = pos; return NS_OK; } GdkFont* nsFreeTypeFont::GetGDKFont() { return nsnull; } PRBool nsFreeTypeFont::GetGDKFontIs10646() { return PR_TRUE; } PRBool nsFreeTypeFont::IsFreeTypeFont() { return PR_TRUE; } gint nsFreeTypeFont::GetWidth(const PRUnichar* aString, PRUint32 aLength) { FT_UInt glyph_index; FT_Glyph glyph; FT_Pos origin_x = 0; // get the face/size from the FreeType cache FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face) return 0; FTC_Image_Cache icache; mFt2->GetImageCache(&icache); if (!icache) return 0; PRUint32 i, extraSurrogateLength; for (i=0; iGetCharIndex((FT_Face)face, code_point, &glyph_index); nsresult rv; rv = mFt2->ImageCacheLookup(icache, &mImageDesc, glyph_index, &glyph); NS_ASSERTION(NS_SUCCEEDED(rv),"error loading glyph"); if (NS_FAILED(rv)) { origin_x += face->size->metrics.x_ppem/2 + 2; continue; } origin_x += FT_16_16_TO_REG(glyph->advance.x); } return origin_x; } gint nsFreeTypeFont::DrawString(nsRenderingContextGTK* aContext, nsDrawingSurfaceGTK* aSurface, nscoord aX, nscoord aY, const PRUnichar* aString, PRUint32 aLength) { NS_ERROR("should never call nsFreeTypeFont::DrawString"); return 0; } PRUint32 nsFreeTypeFont::Convert(const PRUnichar* aSrc, PRUint32 aSrcLen, PRUnichar* aDest, PRUint32 aDestLen) { NS_ERROR("should not be calling nsFreeTypeFont::Convert"); return 0; } int nsFreeTypeFont::ascent() { FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face) return 0; return FT_DESIGN_UNITS_TO_PIXELS(face->ascender, face->size->metrics.y_scale); } int nsFreeTypeFont::descent() { FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face) return 0; return FT_DESIGN_UNITS_TO_PIXELS(-face->descender, face->size->metrics.y_scale); } int nsFreeTypeFont::max_ascent() { FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face) return 0; TT_OS2 * tt_os2; mFt2->GetSfntTable(face, ft_sfnt_os2, (void**)&tt_os2); NS_ASSERTION(tt_os2, "unable to get OS2 table"); if (tt_os2) return FT_DESIGN_UNITS_TO_PIXELS(tt_os2->sTypoAscender, face->size->metrics.y_scale); else return FT_DESIGN_UNITS_TO_PIXELS(face->bbox.yMax, face->size->metrics.y_scale); } int nsFreeTypeFont::max_descent() { FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face) return 0; TT_OS2 *tt_os2; mFt2->GetSfntTable(face, ft_sfnt_os2, (void**)&tt_os2); NS_ASSERTION(tt_os2, "unable to get OS2 table"); if (tt_os2) return FT_DESIGN_UNITS_TO_PIXELS(-tt_os2->sTypoDescender, face->size->metrics.y_scale); else return FT_DESIGN_UNITS_TO_PIXELS(-face->bbox.yMin, face->size->metrics.y_scale); } int nsFreeTypeFont::max_width() { FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face) return 0; return FT_DESIGN_UNITS_TO_PIXELS(face->max_advance_width, face->size->metrics.x_scale); } PRBool nsFreeTypeFont::getXHeight(unsigned long &val) { FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face || !val) return PR_FALSE; val = FT_DESIGN_UNITS_TO_PIXELS(face->height, face->size->metrics.y_scale); return PR_TRUE; } PRBool nsFreeTypeFont::underlinePosition(long &val) { FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face) return PR_FALSE; val = FT_DESIGN_UNITS_TO_PIXELS(-face->underline_position, face->size->metrics.y_scale); return PR_TRUE; } PRBool nsFreeTypeFont::underline_thickness(unsigned long &val) { FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face) return PR_FALSE; val = FT_DESIGN_UNITS_TO_PIXELS(face->underline_thickness, face->size->metrics.y_scale); return PR_TRUE; } PRBool nsFreeTypeFont::superscript_y(long &val) { FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face) return PR_FALSE; TT_OS2 *tt_os2; mFt2->GetSfntTable(face, ft_sfnt_os2, (void**)&tt_os2); NS_ASSERTION(tt_os2, "unable to get OS2 table"); if (!tt_os2) return PR_FALSE; val = FT_DESIGN_UNITS_TO_PIXELS(tt_os2->ySuperscriptYOffset, face->size->metrics.y_scale); return PR_TRUE; } PRBool nsFreeTypeFont::subscript_y(long &val) { FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face) return PR_FALSE; TT_OS2 *tt_os2; mFt2->GetSfntTable(face, ft_sfnt_os2, (void**)&tt_os2); NS_ASSERTION(tt_os2, "unable to get OS2 table"); if (!tt_os2) return PR_FALSE; val = FT_DESIGN_UNITS_TO_PIXELS(tt_os2->ySubscriptYOffset, face->size->metrics.y_scale); // some fonts have the sign wrong. it should be always positive. val = (val < 0) ? -val : val; return PR_TRUE; } // // class nsFreeTypeRender // // this needs to be written class nsFreeTypeRender : nsFreeTypeFont { private: nsFreeTypeRender(); }; // // class nsFreeTypeXImage data/functions // nsFreeTypeXImage::nsFreeTypeXImage() { NS_ERROR("should never call nsFreeTypeXImage::nsFreeTypeXImage"); } nsFreeTypeXImage::nsFreeTypeXImage(nsITrueTypeFontCatalogEntry *aFaceID, PRUint16 aPixelSize, const char *aName) : nsFreeTypeFont(aFaceID, aPixelSize, aName) { //NS_ERROR("should never call nsFreeTypeXImage::nsFreeTypeXImage"); } gint nsFreeTypeXImage::DrawString(nsRenderingContextGTK* aContext, nsDrawingSurfaceGTK* aSurface, nscoord aX, nscoord aY, const PRUnichar* aString, PRUint32 aLength) { #if DEBUG_SHOW_GLYPH_BOX PRUint32 x, y; // grey shows image size // red shows character cells // green box shows text ink #endif if (aLength < 1) { return 0; } // get the face/size from the FreeType cache FT_Face face = getFTFace(); NS_ASSERTION(face, "failed to get face/size"); if (!face) return 0; nsresult rslt; PRInt32 leftBearing, rightBearing, ascent, descent, width; rslt = doGetBoundingMetrics(aString, aLength, &leftBearing, &rightBearing, &ascent, &descent, &width); if (NS_FAILED(rslt)) return 0; // make sure we bring down enough background for blending rightBearing = PR_MAX(rightBearing, width+1); // offset in the ximage to the x origin PRInt32 x_origin = PR_MAX(0, -leftBearing); // offset in the ximage to the x origin PRInt32 y_origin = ascent; PRInt32 x_pos = x_origin; int image_width = x_origin + rightBearing; int image_height = y_origin + PR_MAX(descent, 0); if ((image_width<=0) || (image_height<=0)) { // if we do not have any pixels then no point in trying to draw // eg: the space char has 0 height NS_ASSERTION(width>=0, "Negative width"); return width; } Display *dpy = GDK_DISPLAY(); Drawable win = GDK_WINDOW_XWINDOW(aSurface->GetDrawable()); GC gc = GDK_GC_XGC(aContext->GetGC()); XGCValues values; if (!XGetGCValues(dpy, gc, GCForeground, &values)) { NS_ERROR("failed to get foreground pixel"); return 0; } nscolor color = nsX11AlphaBlend::PixelToNSColor(values.foreground); #if DEBUG_SHOW_GLYPH_BOX // show X/Y origin XDrawLine(dpy, win, DefaultGC(dpy, 0), aX-2, aY, aX+2, aY); XDrawLine(dpy, win, DefaultGC(dpy, 0), aX, aY-2, aX, aY+2); // show width XDrawLine(dpy, win, DefaultGC(dpy, 0), aX-x_origin, aY-y_origin-2, aX+rightBearing, aY-y_origin-2); #endif // // Get the background // XImage *sub_image = nsX11AlphaBlend::GetBackground(dpy, DefaultScreen(dpy), win, aX-x_origin, aY-y_origin, image_width, image_height); if (sub_image==nsnull) { #ifdef DEBUG int screen = DefaultScreen(dpy); // complain if the requested area is not completely off screen int win_width = DisplayWidth(dpy, screen); int win_height = DisplayHeight(dpy, screen); if (((int)(aX-leftBearing+image_width) > 0) // not hidden to left && ((int)(aX-leftBearing) < win_width) // not hidden to right && ((int)(aY-ascent+image_height) > 0)// not hidden to top && ((int)(aY-ascent) < win_height)) // not hidden to bottom { NS_ASSERTION(sub_image, "failed to get the image"); } #endif return 0; } #if DEBUG_SHOW_GLYPH_BOX DEBUG_AADRAWBOX(sub_image,0,0,image_width,image_height,0,0,0,255/4); nscolor black NS_RGB(0,255,0); blendPixel blendPixelFunc = nsX11AlphaBlend::GetBlendPixel(); // x origin for (x=0; x<(unsigned int)image_height; x++) if (x%4==0) (*blendPixelFunc)(sub_image, x_origin, x, black, 255/2); // y origin for (y=0; y<(unsigned int)image_width; y++) if (y%4==0) (*blendPixelFunc)(sub_image, y, ascent-1, black, 255/2); #endif FTC_Image_Cache icache; mFt2->GetImageCache(&icache); if (!icache) return 0; // // Get aa glyphs and blend with background // blendGlyph blendGlyph = nsX11AlphaBlend::GetBlendGlyph(); PRUint32 i, extraSurrogateLength; for (i=0; iGetCharIndex(face, code_point, &glyph_index); if (glyph_index) { rv = mFt2->ImageCacheLookup(icache, &mImageDesc, glyph_index, &glyph); } if ((glyph_index) && (NS_SUCCEEDED(rv))) { mFt2->GlyphGetCBox(glyph, ft_glyph_bbox_pixels, &glyph_bbox); } else { // draw an empty box for the missing glyphs GetFallbackGlyphMetrics(&glyph_bbox, face); int x, y, w = glyph_bbox.xMax, h = glyph_bbox.yMax; for (x=1; x=glyph_bbox.yMax,"glyph too tall"); NS_ASSERTION(x_pos>=-aaglyph.GetLBearing(),"glyph extends too far to left"); #if DEBUG_SHOW_GLYPH_BOX // draw box around part of glyph that extends to the left // of the main area (negative LBearing) if (aaglyph.GetLBearing() < 0) { DEBUG_AADRAWBOX(sub_image, x_pos + aaglyph.GetLBearing(), ascent-glyph_bbox.yMax, -aaglyph.GetLBearing(), glyph_bbox.yMax, 255,0,0, 255/4); } // draw box around main glyph area DEBUG_AADRAWBOX(sub_image, x_pos, ascent-glyph_bbox.yMax, aaglyph.GetAdvance(), glyph_bbox.yMax, 0,255,0, 255/4); // draw box around part of glyph that extends to the right // of the main area (negative LBearing) if (aaglyph.GetRBearing() > (int)aaglyph.GetAdvance()) { DEBUG_AADRAWBOX(sub_image, x_pos + aaglyph.GetAdvance(), ascent-glyph_bbox.yMax, aaglyph.GetRBearing()-aaglyph.GetAdvance(), glyph_bbox.yMax, 0,0,255, 255/4); } #endif (*blendGlyph)(sub_image, &aaglyph, sLinearWeightTable, color, x_pos + aaglyph.GetLBearing(), ascent-glyph_bbox.yMax); x_pos += aaglyph.GetAdvance(); } // // Send it to the display // XPutImage(dpy, win, gc, sub_image, 0, 0, aX-x_origin , aY-ascent, image_width, image_height); XDestroyImage(sub_image); return width; } /////////////////////////////////////////////////////////////////////// // // class nsFreeTypeXImage data/functions // /////////////////////////////////////////////////////////////////////// nsFreeTypeXImageSBC::nsFreeTypeXImageSBC() { NS_ERROR("should never call nsFreeTypeXImageSBC::nsFreeTypeXImageSBC"); } nsFreeTypeXImageSBC::nsFreeTypeXImageSBC(nsITrueTypeFontCatalogEntry *aFaceID, PRUint16 aPixelSize, const char *aName) : nsFreeTypeXImage(aFaceID, aPixelSize, aName) { } #ifdef MOZ_MATHML nsresult nsFreeTypeXImageSBC::GetBoundingMetrics(const PRUnichar* aString, PRUint32 aLength, nsBoundingMetrics& aBoundingMetrics) { nsresult res; char buf[512]; PRInt32 bufLen = sizeof(buf); PRInt32 stringLen = aLength; nsCAutoString familyName; mFaceID->GetFamilyName(familyName); nsTTFontFamilyEncoderInfo *ffei = nsFreeType2::GetCustomEncoderInfo(familyName.get()); NS_ASSERTION(ffei,"failed to find font encoder info"); if (!ffei) return NS_ERROR_FAILURE; res = ffei->mEncodingInfo->mConverter->Convert(aString, &stringLen, buf, &bufLen); NS_ASSERTION((aLength&&bufLen)||(!aLength&&!bufLen), "converter failed"); // // Widen to 16 bit // PRUnichar unibuf[512]; int i; for (i=0; iGetFamilyName(familyName); nsTTFontFamilyEncoderInfo *ffei = nsFreeType2::GetCustomEncoderInfo(familyName.get()); NS_ASSERTION(ffei,"failed to find font encoder info"); if (!ffei) return 0; ffei->mEncodingInfo->mConverter->Convert(aString, &stringLen, buf, &bufLen); NS_ASSERTION((aLength&&bufLen)||(!aLength&&!bufLen), "converter failed"); // // Widen to 16 bit // PRUnichar unibuf[512]; int i; for (i=0; iGetFamilyName(familyName); nsTTFontFamilyEncoderInfo *ffei = nsFreeType2::GetCustomEncoderInfo(familyName.get()); NS_ASSERTION(ffei,"failed to find font encoder info"); if (!ffei) return 0; ffei->mEncodingInfo->mConverter->Convert(aString, &stringLen, buf, &bufLen); NS_ASSERTION((aLength&&bufLen)||(!aLength&&!bufLen), "converter failed"); // // Widen to 16 bit // PRUnichar unibuf[512]; int i; for (i=0; ixMin = 0; aBoundingBox->yMin = 0; aBoundingBox->xMax = PR_MAX(aFace->size->metrics.x_ppem/2 - 1, 0); aBoundingBox->yMax = PR_MAX(aFace->size->metrics.y_ppem/2, 1); } void WeightTableInitCorrection(PRUint8* aTable, PRUint8 aMinValue, double aGain) { // setup the wieghting table for (int i=0; i<256; i++) { int val = i + (int)rint((double)(i-aMinValue)*aGain); val = PR_MAX(0, val); val = PR_MIN(val, 255); aTable[i] = (PRUint8)val; } } #endif