Bug 1089397 - Port the code that uses gfxContextPathAutoSaveRestore to Moz2D. r=mattwoodrow

This commit is contained in:
Jonathan Watt 2014-10-28 14:40:51 +00:00
parent 579842c323
commit 95c7a6f6e7
2 changed files with 11 additions and 81 deletions

View File

@ -710,67 +710,6 @@ private:
gfxContext *mContext;
};
/**
* Sentry helper class for functions with multiple return points that need to
* back up the current path of a context and have it automatically restored
* before they return. This class assumes that the transformation matrix will
* be the same when Save and Restore are called. The calling function must
* ensure that this is the case or the path will be copied incorrectly.
*/
class gfxContextPathAutoSaveRestore
{
typedef mozilla::gfx::Path Path;
public:
gfxContextPathAutoSaveRestore() : mContext(nullptr) {}
explicit gfxContextPathAutoSaveRestore(gfxContext *aContext, bool aSave = true) : mContext(aContext)
{
if (aSave)
Save();
}
~gfxContextPathAutoSaveRestore()
{
Restore();
}
void SetContext(gfxContext *aContext, bool aSave = true)
{
mContext = aContext;
if (aSave)
Save();
}
/**
* If a path is already saved, does nothing. Else copies the current path
* so that it may be restored.
*/
void Save()
{
if (!mPath && mContext) {
mPath = mContext->GetPath();
}
}
/**
* If no path is saved, does nothing. Else replaces the context's path with
* a copy of the saved one, and clears the saved path.
*/
void Restore()
{
if (mPath) {
mContext->SetPath(mPath);
mPath = nullptr;
}
}
private:
gfxContext *mContext;
mozilla::RefPtr<Path> mPath;
};
/**
* Sentry helper class for functions with multiple return points that need to
* back up the current matrix of a context and have it automatically restored

View File

@ -7,6 +7,8 @@
#include "gfxGlyphExtents.h"
#include "gfxPlatformFontList.h"
#include "gfxUserFontSet.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/PathHelpers.h"
#include "nsGkAtoms.h"
#include "nsILanguageAtomService.h"
#include "nsServiceManagerUtils.h"
@ -24,6 +26,7 @@
#include "cairo.h"
using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::unicode;
static const char16_t kEllipsisChar[] = { 0x2026, 0x0 };
@ -454,30 +457,18 @@ gfxTextRun::DrawPartialLigature(gfxFont *aFont, uint32_t aStart, uint32_t aEnd,
}
{
// Need to preserve the path, otherwise this can break canvas text-on-path;
// in general it seems like a good thing, as naive callers probably won't
// expect gfxTextRun::Draw to implicitly destroy the current path.
gfxContextPathAutoSaveRestore savePath(aParams.context);
// use division here to ensure that when the rect is aligned on multiples
// of mAppUnitsPerDevUnit, we clip to true device unit boundaries.
// Also, make sure we snap the rectangle to device pixels.
Rect clipRect = aParams.isVerticalRun ?
Rect(clipExtents.X(), start / mAppUnitsPerDevUnit,
clipExtents.Width(), (end - start) / mAppUnitsPerDevUnit) :
Rect(start / mAppUnitsPerDevUnit, clipExtents.Y(),
(end - start) / mAppUnitsPerDevUnit, clipExtents.Height());
MaybeSnapToDevicePixels(clipRect, *aParams.dt, true);
aParams.context->Save();
aParams.context->NewPath();
if (aParams.isVerticalRun) {
aParams.context->Rectangle(gfxRect(clipExtents.X(),
start / mAppUnitsPerDevUnit,
clipExtents.Width(),
(end - start) / mAppUnitsPerDevUnit),
true);
} else {
aParams.context->Rectangle(gfxRect(start / mAppUnitsPerDevUnit,
clipExtents.Y(),
(end - start) / mAppUnitsPerDevUnit,
clipExtents.Height()),
true);
}
aParams.context->Clip();
aParams.context->Clip(clipRect);
}
gfxPoint pt;