From 4901eb7dd6c31c957d64a7197a4a91864210710d Mon Sep 17 00:00:00 2001 From: "pavlov@pavlov.net" Date: Tue, 28 Aug 2007 13:44:12 -0700 Subject: [PATCH] bug 378457. use nsAutoBuffers instead of mallocs for unsicribe item data. r=vlad, sr=bsmedberg. original patch from David Humphrey --- gfx/thebes/src/gfxWindowsFonts.cpp | 76 ++++++++++++++---------------- xpcom/ds/nsAutoBuffer.h | 10 ++++ 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/gfx/thebes/src/gfxWindowsFonts.cpp b/gfx/thebes/src/gfxWindowsFonts.cpp index dac48fcd0aef..10e494ef7222 100644 --- a/gfx/thebes/src/gfxWindowsFonts.cpp +++ b/gfx/thebes/src/gfxWindowsFonts.cpp @@ -58,6 +58,7 @@ #include +#include "nsAutoBuffer.h" #include "nsUnicodeRange.h" #include "nsUnicharUtils.h" @@ -650,15 +651,15 @@ SetupTextRunFromGlyphs(gfxTextRun *aRun, WCHAR *aGlyphs, HDC aDC, return PR_FALSE; SIZE size; - nsAutoTArray partialWidthArray; - if (!partialWidthArray.AppendElements(length)) + nsAutoBuffer partialWidthArray; + if (!partialWidthArray.EnsureElemCapacity(length)) return PR_FALSE; BOOL success = GetTextExtentExPointI(aDC, (WORD*) aGlyphs, length, INT_MAX, NULL, - partialWidthArray.Elements(), + partialWidthArray.get(), &size); if (!success) return PR_FALSE; @@ -700,14 +701,14 @@ gfxWindowsFontGroup::InitTextRunGDI(gfxContext *aContext, gfxTextRun *aRun, nsRefPtr font = GetFontAt(0); DCFromContext dc(aContext); if (SetupDCFont(dc, font)) { - nsAutoTArray glyphArray; - if (!glyphArray.AppendElements(aLength)) + nsAutoBuffer glyphArray; + if (!glyphArray.EnsureElemCapacity(aLength)) return; - DWORD ret = GetGlyphIndicesA(dc, aString, aLength, (WORD*) glyphArray.Elements(), + DWORD ret = GetGlyphIndicesA(dc, aString, aLength, (WORD*) glyphArray.get(), GGI_MARK_NONEXISTING_GLYPHS); if (ret != GDI_ERROR && - SetupTextRunFromGlyphs(aRun, glyphArray.Elements(), dc, font)) + SetupTextRunFromGlyphs(aRun, glyphArray.get(), dc, font)) return; } @@ -724,14 +725,14 @@ gfxWindowsFontGroup::InitTextRunGDI(gfxContext *aContext, gfxTextRun *aRun, nsRefPtr font = GetFontAt(0); DCFromContext dc(aContext); if (SetupDCFont(dc, font)) { - nsAutoTArray glyphArray; - if (!glyphArray.AppendElements(aLength)) + nsAutoBuffer glyphArray; + if (!glyphArray.EnsureElemCapacity(aLength)) return; - DWORD ret = GetGlyphIndicesW(dc, aString, aLength, (WORD*) glyphArray.Elements(), + DWORD ret = GetGlyphIndicesW(dc, aString, aLength, (WORD*) glyphArray.get(), GGI_MARK_NONEXISTING_GLYPHS); if (ret != GDI_ERROR && - SetupTextRunFromGlyphs(aRun, glyphArray.Elements(), dc, font)) + SetupTextRunFromGlyphs(aRun, glyphArray.get(), dc, font)) return; } @@ -871,10 +872,6 @@ static const char *sCJKLangGroup[] = { #define STATIC_STRING_LENGTH 100 -/** - * XXX We could use a bunch of nsAutoTArrays to avoid memory allocation - * for non-huge strings. - */ class UniscribeItem { public: @@ -886,22 +883,15 @@ public: mItemString(aString), mItemLength(aLength), mAlternativeString(nsnull), mScriptItem(aItem), mScript(aItem->a.eScript), mGroup(aGroup), - mGlyphs(nsnull), mClusters(nsnull), mAttr(nsnull), mNumGlyphs(0), mMaxGlyphs((int)(1.5 * aLength) + 16), - mOffsets(nsnull), mAdvances(nsnull), mFontSelected(PR_FALSE) { - mGlyphs = (WORD *)malloc(mMaxGlyphs * sizeof(WORD)); - mClusters = (WORD *)malloc((mItemLength + 1) * sizeof(WORD)); - mAttr = (SCRIPT_VISATTR *)malloc(mMaxGlyphs * sizeof(SCRIPT_VISATTR)); + mGlyphs.EnsureElemCapacity(mMaxGlyphs); + mClusters.EnsureElemCapacity(mItemLength + 1); + mAttr.EnsureElemCapacity(mMaxGlyphs); } ~UniscribeItem() { - free(mGlyphs); - free(mClusters); - free(mAttr); - free(mOffsets); - free(mAdvances); free(mAlternativeString); } @@ -936,13 +926,13 @@ public: rv = ScriptShape(shapeDC, mCurrentFont->ScriptCache(), str, mRangeLength, mMaxGlyphs, &sa, - mGlyphs, mClusters, - mAttr, &mNumGlyphs); + mGlyphs.get(), mClusters.get(), + mAttr.get(), &mNumGlyphs); if (rv == E_OUTOFMEMORY) { + mGlyphs.AddElemCapacity(mMaxGlyphs); + mAttr.AddElemCapacity(mMaxGlyphs); mMaxGlyphs *= 2; - mGlyphs = (WORD *)realloc(mGlyphs, mMaxGlyphs * sizeof(WORD)); - mAttr = (SCRIPT_VISATTR *)realloc(mAttr, mMaxGlyphs * sizeof(SCRIPT_VISATTR)); continue; } @@ -959,7 +949,7 @@ public: } #ifdef DEBUG_pavlov if (rv == USP_E_SCRIPT_NOT_IN_FONT) { - ScriptGetCMap(mDC, mCurrentFont->ScriptCache(), str, mRangeString, 0, mGlyphs); + ScriptGetCMap(mDC, mCurrentFont->ScriptCache(), str, mRangeString, 0, mGlyphs.get()); PRUnichar foo[LF_FACESIZE+1]; GetTextFaceW(mDC, LF_FACESIZE, foo); printf("bah\n"); @@ -999,16 +989,16 @@ public: HRESULT Place() { HRESULT rv; - mOffsets = (GOFFSET *)malloc(mNumGlyphs * sizeof(GOFFSET)); - mAdvances = (int *)malloc(mNumGlyphs * sizeof(int)); + mOffsets.EnsureElemCapacity(mNumGlyphs); + mAdvances.EnsureElemCapacity(mNumGlyphs); HDC placeDC = nsnull; while (PR_TRUE) { rv = ScriptPlace(placeDC, mCurrentFont->ScriptCache(), - mGlyphs, mNumGlyphs, - mAttr, &mScriptItem->a, - mAdvances, mOffsets, NULL); + mGlyphs.get(), mNumGlyphs, + mAttr.get(), &mScriptItem->a, + mAdvances.get(), mOffsets.get(), NULL); if (rv == E_PENDING) { SelectFont(); @@ -1465,16 +1455,20 @@ private: gfxWindowsFontGroup *mGroup; - WORD *mGlyphs; - WORD *mClusters; - SCRIPT_VISATTR *mAttr; +#define AVERAGE_ITEM_LENGTH 40 + + nsAutoBuffer mGlyphs; + nsAutoBuffer mClusters; + nsAutoBuffer mAttr; + + nsAutoBuffer mOffsets; + nsAutoBuffer mAdvances; + +#undef AVERAGE_ITEM_LENGTH int mMaxGlyphs; int mNumGlyphs; - GOFFSET *mOffsets; - int *mAdvances; - nsRefPtr mCurrentFont; PRPackedBool mFontSelected; diff --git a/xpcom/ds/nsAutoBuffer.h b/xpcom/ds/nsAutoBuffer.h index 8401136934e7..05cb4b38b477 100644 --- a/xpcom/ds/nsAutoBuffer.h +++ b/xpcom/ds/nsAutoBuffer.h @@ -117,6 +117,16 @@ public: T* get() const { return mBufferPtr; } PRInt32 GetElemCapacity() const { return mCurElemCapacity; } + T& operator[](PRUint32 i) + { + return mBufferPtr[i]; + } + + const T& operator[](PRUint32 i) const + { + return mBufferPtr[i]; + } + protected: T *mBufferPtr;