Back to index

lightning-sunbird  0.9+nobinonly
nsAntiAliasedGlyph.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */
00003 /* ***** BEGIN LICENSE BLOCK *****
00004  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00005  *
00006  * The contents of this file are subject to the Mozilla Public License Version
00007  * 1.1 (the "License"); you may not use this file except in compliance with
00008  * the License. You may obtain a copy of the License at
00009  * http://www.mozilla.org/MPL/
00010  *
00011  * Software distributed under the License is distributed on an "AS IS" basis,
00012  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00013  * for the specific language governing rights and limitations under the
00014  * License.
00015  *
00016  * The Original Code is mozilla.org code.
00017  *
00018  * The Initial Developer of the Original Code is
00019  * Netscape Communications Corporation.
00020  * Portions created by the Initial Developer are Copyright (C) 1998
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *   Brian Stell <bstell@netscape.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "gfx-config.h"
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043 #include <string.h>
00044 #include <X11/Xlib.h>
00045 #include "nsCRT.h"
00046 
00047 #include "nsAntiAliasedGlyph.h"
00048 
00049 nsAntiAliasedGlyph::nsAntiAliasedGlyph(PRUint32 aMaxWidth, PRUint32 aMaxHeight,
00050                          PRUint32 aBorder)
00051 {
00052   mMaxWidth = aMaxWidth;
00053   mMaxHeight = aMaxHeight;
00054   mBorder = aBorder;
00055   mBufferWidth  = mBorder + mMaxWidth  + mBorder;
00056   mBufferHeight = mBorder + mMaxHeight + mBorder;
00057 
00058   mAscent    = 0;
00059   mDescent   = 0;
00060   mLBearing  = 0;
00061   mRBearing  = 0;
00062   mWidth     = 0;
00063   mHeight    = 0;
00064   mAdvance   = 0;
00065   mOwnBuffer = PR_FALSE;
00066   mBuffer    = nsnull;
00067   mBufferLen = 0;
00068 }
00069 
00070 nsAntiAliasedGlyph::~nsAntiAliasedGlyph()
00071 {
00072   if (mOwnBuffer)
00073     nsMemory::Free(mBuffer);
00074 }
00075 
00076 PRBool
00077 nsAntiAliasedGlyph::Init()
00078 {
00079   return Init(nsnull, 0);
00080 }
00081 
00082 PRBool
00083 nsAntiAliasedGlyph::Init(PRUint8 *aBuffer, PRUint32 aBufferLen)
00084 {
00085   mBufferLen = mBufferWidth * mBufferHeight;
00086   if (aBufferLen >= mBufferLen) {
00087     mBuffer = aBuffer;
00088     mOwnBuffer = PR_FALSE;
00089   }
00090   else {
00091     mBuffer = (PRUint8 *)nsMemory::Alloc(mBufferLen);
00092     if (!mBuffer) {
00093       mBufferLen = 0;
00094       return PR_FALSE;
00095     }
00096     mOwnBuffer = PR_TRUE;
00097   }
00098   memset(mBuffer, 0, mBufferLen);
00099   return PR_TRUE;
00100 }
00101 
00102 #ifdef MOZ_ENABLE_FREETYPE2
00103 PRBool
00104 nsAntiAliasedGlyph::WrapFreeType(FT_BBox *aBbox, FT_BitmapGlyph aSlot,
00105                                  PRUint8 *aBuffer, PRUint32 aBufferLen)
00106 {
00107   mAscent       = aBbox->yMax;
00108   mDescent      = aBbox->yMin;
00109   mLBearing     = aBbox->xMin;
00110   mRBearing     = aBbox->xMax;
00111   mAdvance      = aSlot->root.advance.x>>16;
00112   mWidth        = aSlot->bitmap.width;
00113   mHeight       = aSlot->bitmap.rows;
00114 
00115 
00116   if (aSlot->bitmap.pixel_mode == ft_pixel_mode_grays) {
00117     mBufferWidth  = aSlot->bitmap.pitch;
00118     mBufferHeight = aSlot->bitmap.rows;
00119     mBufferLen = mBufferWidth * mBufferHeight;
00120     mBuffer = aSlot->bitmap.buffer;
00121     mOwnBuffer = PR_FALSE;
00122     return PR_TRUE;
00123   }
00124   else {
00125     // expand the data from 1 bit to 8 bit
00126     mBufferWidth  = aSlot->bitmap.width;
00127     mBufferHeight = aSlot->bitmap.rows;
00128     if (!Init(aBuffer, aBufferLen))
00129       return PR_FALSE;
00130     int pitch = aSlot->bitmap.pitch;
00131     for (int row=0; row<aSlot->bitmap.rows; row++) {
00132       for (int j=0; j<aSlot->bitmap.width; j++) {
00133         int byte = aSlot->bitmap.buffer[(j>>3) + (row*pitch)];
00134         if (!((byte<<(j&0x7)) & 0x80))
00135           continue;
00136         mBuffer[j+(row*mBufferWidth)] = 255;
00137       }
00138     }
00139   }
00140   return PR_TRUE;
00141 }
00142 #endif
00143 
00144 PRBool
00145 nsAntiAliasedGlyph::SetImage(XCharStruct *aCharStruct, XImage *aXImage)
00146 {
00147   NS_ASSERTION(mBuffer, "null buffer (was Init called?)");
00148   if (!mBuffer)
00149     return PR_FALSE;
00150   PRUint32 src_width = GLYPH_RIGHT_EDGE(aCharStruct)
00151                        - GLYPH_LEFT_EDGE(aCharStruct);
00152   PRUint32 src_height = aXImage->height;
00153   if ((src_width > mMaxWidth) || (src_height > mMaxHeight)) {
00154     NS_ASSERTION(src_width<=mMaxWidth,"unexpected width");
00155     NS_ASSERTION(src_height<=mMaxHeight,"unexpected height");
00156     return PR_FALSE;
00157   }
00158 
00159   mAscent   = aCharStruct->ascent;
00160   mDescent  = aCharStruct->descent;
00161   mLBearing = aCharStruct->lbearing;
00162   mRBearing = aCharStruct->rbearing;
00163   mWidth    = src_width;
00164   mHeight   = src_height;
00165   mAdvance  = aCharStruct->width;
00166 
00167   NS_ASSERTION(aXImage->format==ZPixmap,"unexpected image format");
00168   if (aXImage->format != ZPixmap)
00169     return PR_FALSE;
00170 
00171   int bits_per_pixel = aXImage->bits_per_pixel;
00172   memset((char*)mBuffer, 0, mBufferLen);
00173 
00174   PRUint32 x, y;
00175   PRUint32 src_index = 0;
00176   PRUint32 dst_index =  mBorder + (mBorder*mBufferWidth);
00177   PRInt32 delta_dst_row = -src_width + mBufferWidth;
00178   PRUint8 *pSrcLineStart = (PRUint8 *)aXImage->data;
00179   if (bits_per_pixel == 16) {
00180     for (y=0; y<src_height; y++) {
00181       PRUint16 *src = (PRUint16*)pSrcLineStart;
00182       for (x=0; x<src_width; x++,src++,dst_index++) {
00183         if (*src & 0x1)
00184           mBuffer[dst_index] = 0xFF;
00185       }
00186       // move to the next row
00187       dst_index += delta_dst_row;
00188       pSrcLineStart += aXImage->bytes_per_line;
00189     }
00190     return PR_TRUE;
00191   }
00192   else if (bits_per_pixel == 24) {
00193     PRUint8 *src = (PRUint8*)aXImage->data;
00194     for (y=0; y<src_height; y++) {
00195       for (x=0; x<src_width; x++,src_index+=3,dst_index++) {
00196         if (src[src_index] & 0x1)
00197           mBuffer[dst_index] = 0xFF;
00198       }
00199       // move to the next row
00200       dst_index += delta_dst_row;
00201       src_index += -3*src_width + aXImage->bytes_per_line;
00202     }
00203     return PR_TRUE;
00204   }
00205   else if (bits_per_pixel == 32) {
00206     for (y=0; y<src_height; y++) {
00207       PRUint32 *src = (PRUint32*)pSrcLineStart;
00208       for (x=0; x<src_width; x++,src++,dst_index++) {
00209         if (*src & 0x100)
00210           mBuffer[dst_index] = 0xFF;
00211       }
00212       // move to the next row
00213       dst_index += delta_dst_row;
00214       pSrcLineStart += aXImage->bytes_per_line;
00215     }
00216     return PR_TRUE;
00217   }
00218   else {
00219     NS_ASSERTION(0, "do not support current bits_per_pixel");
00220     return PR_FALSE;
00221   }
00222 }
00223 
00224 PRBool
00225 nsAntiAliasedGlyph::SetSize(GlyphMetrics *aGlyphMetrics)
00226 {
00227   mAscent   = aGlyphMetrics->ascent;
00228   mDescent  = aGlyphMetrics->descent;
00229   mLBearing = aGlyphMetrics->lbearing;
00230   mRBearing = aGlyphMetrics->rbearing;
00231   mWidth    = aGlyphMetrics->width;
00232   mHeight   = aGlyphMetrics->height;
00233   mAdvance  = aGlyphMetrics->advance;
00234   return PR_TRUE;
00235 }