Back to index

lightning-sunbird  0.9+nobinonly
nsRenderingContextPh.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #ifndef nsRenderingContextPh_h___
00038 #define nsRenderingContextPh_h___
00039 
00040 #include "nsRenderingContextImpl.h"
00041 #include "nsUnitConversion.h"
00042 #include "nsFont.h"
00043 #include "nsIFontMetrics.h"
00044 #include "nsPoint.h"
00045 #include "nsString.h"
00046 #include "nsCRT.h"
00047 #include "nsTransform2D.h"
00048 #include "nsIViewManager.h"
00049 #include "nsIWidget.h"
00050 #include "nsRect.h"
00051 #include "nsImagePh.h"
00052 #include "nsIDeviceContext.h"
00053 #include "nsVoidArray.h"
00054 #include "nsGfxCIID.h"
00055 
00056 #include "nsDrawingSurfacePh.h"
00057 #include "nsRegionPh.h"
00058 
00059 // Macro for converting from nscolor to PtColor_t
00060 // Photon RGB values are stored as 00 RR GG BB
00061 // nscolor RGB values are 00 BB GG RR
00062 #define NS_TO_PH_RGB(ns) (ns & 0xff) << 16 | (ns & 0xff00) | ((ns >> 16) & 0xff)
00063 #define PH_TO_NS_RGB(ns) (ns & 0xff) << 16 | (ns & 0xff00) | ((ns >> 16) & 0xff)
00064 
00065 class nsRenderingContextPh : public nsRenderingContextImpl
00066 {
00067 public:
00068    nsRenderingContextPh();
00069    virtual ~nsRenderingContextPh();
00070    
00071    NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
00072           
00073    NS_DECL_ISUPPORTS
00074           
00075    NS_IMETHOD Init(nsIDeviceContext* aContext, nsIWidget *aWindow);
00076 
00077         inline
00078    NS_IMETHODIMP Init(nsIDeviceContext* aContext, nsIDrawingSurface* aSurface)
00079               {
00080               mContext = aContext;
00081               NS_IF_ADDREF(mContext);
00082 
00083               mSurface = (nsDrawingSurfacePh *) aSurface;
00084               NS_ADDREF(mSurface);
00085               mOffscreenSurface = mSurface;
00086 
00087               mGC = mSurface->GetGC();
00088               mOwner = PR_FALSE;
00089               mSurfaceDC = ((nsDrawingSurfacePh*)mSurface)->GetDC();
00090 
00091               return CommonInit();
00092               }
00093    
00094    inline NS_IMETHODIMP Reset(void) { return NS_OK; }
00095    
00096         inline
00097    NS_IMETHODIMP GetDeviceContext(nsIDeviceContext *&aContext)
00098               { NS_IF_ADDREF( mContext );
00099                      aContext = mContext;
00100                      return NS_OK;
00101               }
00102    
00103         inline
00104    NS_IMETHODIMP LockDrawingSurface(PRInt32 aX, PRInt32 aY, PRUint32 aWidth, PRUint32 aHeight,
00105                                                          void **aBits, PRInt32 *aStride, PRInt32 *aWidthBytes,
00106                                                          PRUint32 aFlags)
00107               {
00108               PushState();
00109               return mSurface->Lock( aX, aY, aWidth, aHeight, aBits, aStride, aWidthBytes, aFlags );
00110               }
00111 
00112         inline
00113    NS_IMETHODIMP UnlockDrawingSurface(void)
00114               {      PopState();
00115                      mSurface->Unlock();
00116                      return NS_OK;
00117               }
00118    
00119         inline
00120    NS_IMETHODIMP SelectOffScreenDrawingSurface(nsIDrawingSurface* aSurface)
00121               { mSurface = ( nsnull==aSurface ) ? mOffscreenSurface : (nsDrawingSurfacePh *) aSurface;
00122                      mSurfaceDC = mSurface->Select( );
00123                      return NS_OK;
00124               }
00125 
00126         inline
00127    NS_IMETHODIMP GetDrawingSurface(nsIDrawingSurface* *aSurface) { *aSurface = mSurface; return NS_OK; }
00128 
00129         inline
00130    NS_IMETHODIMP GetHints(PRUint32& aResult)
00131               { /* this flag indicates that the system prefers 8bit chars over wide chars */
00132                      /* It may or may not be faster under photon... */
00133                      aResult = NS_RENDERING_HINT_FAST_8BIT_TEXT;
00134                      return NS_OK;
00135               }
00136    
00137    NS_IMETHOD PushState(void);
00138    NS_IMETHOD PopState(void);
00139    
00140         inline
00141    NS_IMETHODIMP IsVisibleRect( const nsRect& aRect, PRBool &aVisible )
00142               { aVisible = PR_TRUE;
00143                      return NS_OK;
00144               }
00145    
00146    NS_IMETHOD SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
00147    NS_IMETHOD GetClipRect(nsRect &aRect, PRBool &aClipState);
00148    NS_IMETHOD SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);
00149 
00150         inline
00151    NS_IMETHODIMP CopyClipRegion(nsIRegion &aRegion)
00152               { if( !mClipRegion ) return NS_ERROR_FAILURE;
00153                      aRegion.SetTo(*NS_STATIC_CAST(nsIRegion*, mClipRegion));
00154                      return NS_OK;
00155               }
00156 
00157    NS_IMETHOD GetClipRegion(nsIRegion **aRegion);
00158    
00159    inline
00160         NS_IMETHODIMP SetLineStyle(nsLineStyle aLineStyle)
00161    { mCurrentLineStyle = aLineStyle;
00162         return NS_OK;
00163         }
00164 
00165         inline
00166    NS_IMETHODIMP GetLineStyle(nsLineStyle &aLineStyle)
00167               { aLineStyle = mCurrentLineStyle;
00168                      return NS_OK;
00169               }
00170    
00171    inline
00172         NS_IMETHODIMP SetColor(nscolor aColor) { mCurrentColor = NS_TO_PH_RGB( aColor ); return NS_OK; }
00173         inline
00174    NS_IMETHODIMP GetColor(nscolor &aColor) const { aColor = PH_TO_NS_RGB( mCurrentColor ); return NS_OK; }
00175    
00176         inline
00177         NS_IMETHODIMP SetFont(const nsFont& aFont, nsIAtom* aLangGroup)
00178               { nsIFontMetrics* newMetrics;
00179                      nsresult rv = mContext->GetMetricsFor( aFont, aLangGroup, newMetrics );
00180                      if( NS_SUCCEEDED( rv ) ) {
00181                        rv = SetFont( newMetrics );
00182                        NS_RELEASE( newMetrics );
00183                             }
00184                      return rv;
00185               }
00186 
00187    NS_IMETHOD SetFont(nsIFontMetrics *aFontMetrics);
00188    
00189         inline       
00190    NS_IMETHODIMP GetFontMetrics(nsIFontMetrics *&aFontMetrics)
00191               { NS_IF_ADDREF(mFontMetrics);
00192                      aFontMetrics = mFontMetrics;
00193                      return NS_OK;
00194               }
00195    
00196         inline
00197    NS_IMETHODIMP Translate(nscoord aX, nscoord aY) { mTranMatrix->AddTranslation((float)aX,(float)aY); return NS_OK; }
00198 
00199         inline
00200    NS_IMETHODIMP Scale(float aSx, float aSy) { mTranMatrix->AddScale(aSx, aSy); return NS_OK; }
00201 
00202         inline
00203    NS_IMETHODIMP GetCurrentTransform(nsTransform2D *&aTransform) { aTransform = mTranMatrix; return NS_OK; }
00204 
00205    
00206    NS_IMETHOD CreateDrawingSurface(const nsRect &aBounds, PRUint32 aSurfFlags, nsIDrawingSurface* &aSurface);
00207 
00208         inline
00209    NS_IMETHODIMP DestroyDrawingSurface(nsIDrawingSurface* aDS)
00210               { nsDrawingSurfacePh *surf = (nsDrawingSurfacePh *) aDS;
00211                      NS_IF_RELEASE(surf);
00212                      return NS_OK;
00213               }
00214    
00215    NS_IMETHOD DrawLine(nscoord aX0, nscoord aY0, nscoord aX1, nscoord aY1);
00216 
00217         inline
00218    NS_IMETHODIMP DrawPolyline(const nsPoint aPoints[], PRInt32 aNumPoints) { return DrawPolygon( aPoints, aNumPoints ); }
00219    
00220         inline
00221    NS_IMETHODIMP DrawRect(const nsRect& aRect) { return DrawRect( aRect.x, aRect.y, aRect.width, aRect.height ); }
00222 
00223    NS_IMETHOD DrawRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
00224    
00225         inline
00226    NS_IMETHODIMP FillRect(const nsRect& aRect) { return FillRect( aRect.x, aRect.y, aRect.width, aRect.height ); }
00227 
00228    NS_IMETHOD FillRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
00229    
00230         inline
00231    NS_IMETHODIMP InvertRect(const nsRect& aRect) {  return InvertRect( aRect.x, aRect.y, aRect.width, aRect.height ); }
00232 
00233    NS_IMETHOD InvertRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
00234    
00235    NS_IMETHOD DrawPolygon(const nsPoint aPoints[], PRInt32 aNumPoints);
00236    NS_IMETHOD FillPolygon(const nsPoint aPoints[], PRInt32 aNumPoints);
00237    
00238         inline
00239    NS_IMETHODIMP DrawEllipse(const nsRect& aRect) { return DrawEllipse( aRect.x, aRect.y, aRect.width, aRect.height ); }
00240 
00241    NS_IMETHOD DrawEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
00242 
00243         inline
00244    NS_IMETHODIMP FillEllipse(const nsRect& aRect) { return FillEllipse( aRect.x, aRect.y, aRect.width, aRect.height ); }
00245 
00246    NS_IMETHOD FillEllipse(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
00247    
00248         inline
00249    NS_IMETHODIMP DrawArc(const nsRect& aRect, float aStartAngle, float aEndAngle) { return DrawArc(aRect.x,aRect.y,aRect.width,aRect.height,aStartAngle,aEndAngle); }
00250 
00251    NS_IMETHOD DrawArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
00252                                      float aStartAngle, float aEndAngle);
00253 
00254         inline
00255    NS_IMETHODIMP FillArc(const nsRect& aRect, float aStartAngle, float aEndAngle) { return FillArc(aRect.x,aRect.y,aRect.width,aRect.height,aStartAngle,aEndAngle); }
00256 
00257    NS_IMETHOD FillArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
00258                                      float aStartAngle, float aEndAngle);
00259 
00260         inline
00261    NS_IMETHODIMP GetWidth(char aC, nscoord& aWidth)
00262               { // Check for the very common case of trying to get the width of a single space
00263                      if(aC == ' ')
00264                        return mFontMetrics->GetSpaceWidth(aWidth);
00265                      return GetWidth( &aC, 1, aWidth );
00266               }
00267 
00268         inline
00269    NS_IMETHODIMP GetWidth(PRUnichar aC, nscoord& aWidth, PRInt32 *aFontID)
00270               { /* turn it into a string */
00271               PRUnichar buf[2];
00272               buf[0] = aC;
00273               buf[1] = nsnull;
00274               return GetWidth( buf, 1, aWidth, aFontID );
00275               }
00276 
00277         inline
00278    NS_IMETHODIMP GetWidth(const nsString& aString, nscoord& aWidth, PRInt32 *aFontID) { return GetWidth( aString.get(), aString.Length(), aWidth, aFontID ); }
00279 
00280         inline
00281    NS_IMETHODIMP GetWidth(const char* aString, nscoord& aWidth) { return GetWidth( aString, strlen( aString ), aWidth ); }
00282 
00283    NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth);
00284    NS_IMETHOD GetWidth(const PRUnichar* aString, PRUint32 aLength,
00285                                       nscoord& aWidth, PRInt32 *aFontID);
00286    
00287    NS_IMETHOD DrawString(const char *aString, PRUint32 aLength,
00288                                            nscoord aX, nscoord aY,
00289                                            const nscoord* aSpacing);
00290 
00291         inline
00292    NS_IMETHODIMP DrawString(const PRUnichar *aString, PRUint32 aLength,
00293                                            nscoord aX, nscoord aY,
00294                                            PRInt32 aFontID,
00295                                            const nscoord* aSpacing)
00296               {
00297               NS_ConvertUCS2toUTF8 theUnicodeString( aString, aLength );
00298               const char *p = theUnicodeString.get( );
00299               return DrawString( p, strlen( p ), aX, aY, aSpacing );
00300               }
00301 
00302         inline
00303    NS_IMETHODIMP DrawString(const nsString& aString, nscoord aX, nscoord aY, PRInt32 aFontID, const nscoord* aSpacing)
00304               {
00305               NS_ConvertUCS2toUTF8 theUnicodeString( aString.get(), aString.Length() );
00306               const char *p = theUnicodeString.get();
00307               return DrawString( p, strlen( p ), aX, aY, aSpacing );
00308               }
00309 
00310         inline
00311    NS_IMETHODIMP GetTextDimensions(const char* aString, PRUint32 aLength, nsTextDimensions& aDimensions)
00312               {
00313               mFontMetrics->GetMaxAscent(aDimensions.ascent);
00314               mFontMetrics->GetMaxDescent(aDimensions.descent);
00315               return GetWidth(aString, aLength, aDimensions.width);
00316               }
00317 
00318    NS_IMETHOD GetTextDimensions(const PRUnichar *aString, PRUint32 aLength,
00319                                                         nsTextDimensions& aDimensions, PRInt32 *aFontID);
00320 
00321         inline
00322    NS_IMETHODIMP DrawImage(nsIImage *aImage, nscoord aX, nscoord aY)
00323               {
00324        // we have to do this here because we are doing a transform below
00325        return DrawImage( aImage, aX, aY,
00326                          NSToCoordRound(mP2T * aImage->GetWidth()),
00327                          NSToCoordRound(mP2T * aImage->GetHeight())
00328                        );
00329               }
00330 
00331         inline
00332    NS_IMETHODIMP DrawImage(nsIImage *aImage, nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight)
00333               {
00334               nscoord x, y, w, h;
00335               x = aX;
00336               y = aY;
00337               w = aWidth;
00338               h = aHeight;
00339               mTranMatrix->TransformCoord(&x, &y, &w, &h);
00340               return (aImage->Draw(*this, mSurface, x, y, w, h));
00341               }
00342 
00343         inline
00344    NS_IMETHODIMP DrawImage(nsIImage *aImage, const nsRect& aRect) { return DrawImage( aImage, aRect.x, aRect.y, aRect.width, aRect.height ); }
00345 
00346    NS_IMETHOD DrawImage(nsIImage *aImage, const nsRect& aSRect, const nsRect& aDRect);
00347    
00348    NS_IMETHOD CopyOffScreenBits(nsIDrawingSurface* aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY,
00349                                                         const nsRect &aDestBounds, PRUint32 aCopyFlags);
00350 
00351         inline
00352    NS_IMETHODIMP RetrieveCurrentNativeGraphicData(void **ngd)
00353               {
00354               if( ngd != nsnull ) *ngd = nsnull;
00355               return NS_OK;
00356               }
00357 
00358 #ifdef MOZ_MATHML
00359 
00362   NS_IMETHOD GetBoundingMetrics(const char*        aString,
00363                                 PRUint32           aLength,
00364                                 nsBoundingMetrics& aBoundingMetrics);
00365 
00369   NS_IMETHOD GetBoundingMetrics(const PRUnichar*   aString,
00370                                 PRUint32           aLength,
00371                                 nsBoundingMetrics& aBoundingMetrics,
00372                                 PRInt32*           aFontID = nsnull);
00373 
00374 #endif /* MOZ_MATHML */
00375 
00376    
00377    
00378 private:
00379        inline NS_IMETHODIMP CommonInit()
00380               {
00381               if( mContext && mTranMatrix ) {
00382                 mP2T = mContext->DevUnitsToAppUnits();
00383                 float app2dev;
00384                 app2dev = mContext->AppUnitsToDevUnits();
00385                 mTranMatrix->AddScale(app2dev, app2dev);
00386                 }
00387               return NS_OK;
00388               }
00389 
00390        void ApplyClipping( PhGC_t * );
00391        void CreateClipRegion( );
00392   inline void UpdateGC( )
00393               {
00394               PgSetGCCx( mSurfaceDC, mGC ); /* new */
00395               if( mRegionID ) mSurfaceDC->gin.rid = mRegionID;
00396               ApplyClipping( mGC );
00397               }
00398 
00399    // ConditionRect is used to fix coordinate overflow problems for
00400    // rectangles after they are transformed to screen coordinates
00401    inline void ConditionRect(nscoord &x, nscoord &y, nscoord &w, nscoord &h) {
00402           if ( y < -32766 )
00403                  y = -32766;
00404           if ( y + h > 32766 )
00405                  h  = 32766 - y;
00406           if ( x < -32766 )
00407                  x = -32766;
00408           if ( x + w > 32766 ) 
00409                  w  = 32766 - x;
00410    }
00411 
00412    PhGC_t             *mGC;
00413         PhDrawContext_t            *mSurfaceDC; /* the DC of the mSurface - keep this in sync with mSurface */
00414         PhRid_t                                         mRegionID;
00415    nscolor            mCurrentColor;
00416    nsLineStyle        mCurrentLineStyle;
00417    nsIFontMetrics     *mFontMetrics;
00418    nsDrawingSurfacePh *mOffscreenSurface;
00419    nsDrawingSurfacePh *mSurface;
00420    nsIDeviceContext   *mContext;
00421    float              mP2T;
00422    nsCOMPtr<nsIRegion>mClipRegion;
00423    char               *mPhotonFontName;
00424         PRBool                                                 mOwner;
00425    
00426    //state management
00427    nsVoidArray       *mStateCache;
00428 };
00429 
00430 #endif /* nsRenderingContextPh_h___ */