Bug 1083557 - Port the code that uses nsRenderingContext::FillPolygon() to Moz2D. r=mattwoodrow

This commit is contained in:
Jonathan Watt 2014-10-17 15:06:34 +01:00
parent ed52c8589c
commit e20775a0d6
7 changed files with 114 additions and 73 deletions

View File

@ -281,24 +281,6 @@ nsRenderingContext::FillRect(nscoord aX, nscoord aY,
FillRect(nsRect(aX, aY, aWidth, aHeight));
}
void
nsRenderingContext::FillPolygon(const nsPoint twPoints[], int32_t aNumPoints)
{
if (aNumPoints == 0)
return;
nsAutoArrayPtr<gfxPoint> pxPoints(new gfxPoint[aNumPoints]);
for (int i = 0; i < aNumPoints; i++) {
pxPoints[i].x = FROM_TWIPS(twPoints[i].x);
pxPoints[i].y = FROM_TWIPS(twPoints[i].y);
}
mThebes->NewPath();
mThebes->Polygon(pxPoints, aNumPoints);
mThebes->Fill();
}
//
// text
//

View File

@ -42,6 +42,11 @@ public:
DrawTarget *GetDrawTarget() { return mThebes->GetDrawTarget(); }
nsDeviceContext *DeviceContext() { return mDeviceContext; }
int32_t AppUnitsPerDevPixel() const {
// we know this is an int (it's stored as a double for convenience)
return int32_t(mP2A);
}
// Graphics state
void IntersectClip(const nsRect& aRect);
@ -56,7 +61,6 @@ public:
void FillRect(const nsRect& aRect);
void FillRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
void FillPolygon(const nsPoint aPoints[], int32_t aNumPoints);
// Text

View File

@ -3474,9 +3474,7 @@ RoundFloatToPixel(float aValue,
return RoundIntToPixel(NSToCoordRound(aValue), aTwipsPerPixel, aRoundDown);
}
static void
SetPoly(const nsRect& aRect,
nsPoint* poly)
static void SetPoly(const Rect& aRect, Point* poly)
{
poly[0].x = aRect.x;
poly[0].y = aRect.y;
@ -3486,13 +3484,12 @@ SetPoly(const nsRect& aRect,
poly[2].y = aRect.y + aRect.height;
poly[3].x = aRect.x;
poly[3].y = aRect.y + aRect.height;
poly[4].x = aRect.x;
poly[4].y = aRect.y;
}
static void
DrawSolidBorderSegment(nsRenderingContext& aContext,
nsRect aRect,
nscolor aColor,
nscoord aTwipsPerPixel,
uint8_t aStartBevelSide = 0,
nscoord aStartBevelOffset = 0,
@ -3518,42 +3515,54 @@ DrawSolidBorderSegment(nsRenderingContext& aContext,
}
else {
// polygon with beveling
nsPoint poly[5];
SetPoly(aRect, poly);
int32_t appUnitsPerDevPixel = aContext.AppUnitsPerDevPixel();
Point poly[4];
SetPoly(NSRectToRect(aRect, appUnitsPerDevPixel), poly);
Float startBevelOffset =
NSAppUnitsToFloatPixels(aStartBevelOffset, appUnitsPerDevPixel);
switch(aStartBevelSide) {
case NS_SIDE_TOP:
poly[0].x += aStartBevelOffset;
poly[4].x = poly[0].x;
poly[0].x += startBevelOffset;
break;
case NS_SIDE_BOTTOM:
poly[3].x += aStartBevelOffset;
poly[3].x += startBevelOffset;
break;
case NS_SIDE_RIGHT:
poly[1].y += aStartBevelOffset;
poly[1].y += startBevelOffset;
break;
case NS_SIDE_LEFT:
poly[0].y += aStartBevelOffset;
poly[4].y = poly[0].y;
poly[0].y += startBevelOffset;
}
Float endBevelOffset =
NSAppUnitsToFloatPixels(aEndBevelOffset, appUnitsPerDevPixel);
switch(aEndBevelSide) {
case NS_SIDE_TOP:
poly[1].x -= aEndBevelOffset;
poly[1].x -= endBevelOffset;
break;
case NS_SIDE_BOTTOM:
poly[2].x -= aEndBevelOffset;
poly[2].x -= endBevelOffset;
break;
case NS_SIDE_RIGHT:
poly[2].y -= aEndBevelOffset;
poly[2].y -= endBevelOffset;
break;
case NS_SIDE_LEFT:
poly[3].y -= aEndBevelOffset;
poly[3].y -= endBevelOffset;
}
aContext.FillPolygon(poly, 5);
DrawTarget* drawTarget = aContext.GetDrawTarget();
RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder();
builder->MoveTo(poly[0]);
builder->LineTo(poly[1]);
builder->LineTo(poly[2]);
builder->LineTo(poly[3]);
builder->Close();
RefPtr<Path> path = builder->Finish();
drawTarget->Fill(path, ColorPattern(ToDeviceColor(aColor)),
DrawOptions(1.f, CompositionOp::OP_OVER,
AntialiasMode::NONE));
}
}
static void
@ -3630,21 +3639,21 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
if (horizontal) {
GetDashInfo(aBorder.width, dashLength, twipsPerPixel, numDashSpaces, startDashLength, endDashLength);
nsRect rect(aBorder.x, aBorder.y, startDashLength, aBorder.height);
DrawSolidBorderSegment(aContext, rect, twipsPerPixel);
DrawSolidBorderSegment(aContext, rect, aBorderColor, twipsPerPixel);
for (int32_t spaceX = 0; spaceX < numDashSpaces; spaceX++) {
rect.x += rect.width + dashLength;
rect.width = (spaceX == (numDashSpaces - 1)) ? endDashLength : dashLength;
DrawSolidBorderSegment(aContext, rect, twipsPerPixel);
DrawSolidBorderSegment(aContext, rect, aBorderColor, twipsPerPixel);
}
}
else {
GetDashInfo(aBorder.height, dashLength, twipsPerPixel, numDashSpaces, startDashLength, endDashLength);
nsRect rect(aBorder.x, aBorder.y, aBorder.width, startDashLength);
DrawSolidBorderSegment(aContext, rect, twipsPerPixel);
DrawSolidBorderSegment(aContext, rect, aBorderColor, twipsPerPixel);
for (int32_t spaceY = 0; spaceY < numDashSpaces; spaceY++) {
rect.y += rect.height + dashLength;
rect.height = (spaceY == (numDashSpaces - 1)) ? endDashLength : dashLength;
DrawSolidBorderSegment(aContext, rect, twipsPerPixel);
DrawSolidBorderSegment(aContext, rect, aBorderColor, twipsPerPixel);
}
}
}
@ -3655,7 +3664,8 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
if ((horizontal && (twipsPerPixel >= aBorder.height)) ||
(!horizontal && (twipsPerPixel >= aBorder.width))) {
// a one pixel border
DrawSolidBorderSegment(aContext, aBorder, twipsPerPixel, aStartBevelSide, aStartBevelOffset,
DrawSolidBorderSegment(aContext, aBorder, aBorderColor, twipsPerPixel,
aStartBevelSide, aStartBevelOffset,
aEndBevelSide, aEndBevelOffset);
}
else {
@ -3680,7 +3690,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
if (NS_SIDE_TOP == aEndBevelSide) {
rect.width -= endBevel;
}
DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide,
DrawSolidBorderSegment(aContext, rect, aBorderColor, twipsPerPixel, aStartBevelSide,
startBevel, aEndBevelSide, endBevel);
}
else { // left, right
@ -3693,7 +3703,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
if (NS_SIDE_LEFT == aEndBevelSide) {
rect.height -= endBevel;
}
DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide,
DrawSolidBorderSegment(aContext, rect, aBorderColor, twipsPerPixel, aStartBevelSide,
startBevel, aEndBevelSide, endBevel);
}
@ -3713,7 +3723,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
if (NS_SIDE_BOTTOM == aEndBevelSide) {
rect.width -= endBevel;
}
DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide,
DrawSolidBorderSegment(aContext, rect, aBorderColor, twipsPerPixel, aStartBevelSide,
startBevel, aEndBevelSide, endBevel);
}
else {
@ -3726,7 +3736,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
if (NS_SIDE_RIGHT == aEndBevelSide) {
rect.height -= endBevel;
}
DrawSolidBorderSegment(aContext, rect, twipsPerPixel, aStartBevelSide,
DrawSolidBorderSegment(aContext, rect, aBorderColor, twipsPerPixel, aStartBevelSide,
startBevel, aEndBevelSide, endBevel);
}
}
@ -3753,7 +3763,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
if (NS_SIDE_TOP == aEndBevelSide) {
topRect.width -= aEndBevelOffset - endBevel;
}
DrawSolidBorderSegment(aContext, topRect, twipsPerPixel, aStartBevelSide,
DrawSolidBorderSegment(aContext, topRect, aBorderColor, twipsPerPixel, aStartBevelSide,
startBevel, aEndBevelSide, endBevel);
// draw the botom line or rect
@ -3766,7 +3776,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
if (NS_SIDE_BOTTOM == aEndBevelSide) {
bottomRect.width -= aEndBevelOffset - endBevel;
}
DrawSolidBorderSegment(aContext, bottomRect, twipsPerPixel, aStartBevelSide,
DrawSolidBorderSegment(aContext, bottomRect, aBorderColor, twipsPerPixel, aStartBevelSide,
startBevel, aEndBevelSide, endBevel);
}
else { // left, right
@ -3780,7 +3790,7 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
if (NS_SIDE_LEFT == aEndBevelSide) {
leftRect.height -= aEndBevelOffset - endBevel;
}
DrawSolidBorderSegment(aContext, leftRect, twipsPerPixel, aStartBevelSide,
DrawSolidBorderSegment(aContext, leftRect, aBorderColor, twipsPerPixel, aStartBevelSide,
startBevel, aEndBevelSide, endBevel);
nscoord widthOffset = aBorder.width - thirdWidth;
@ -3792,14 +3802,14 @@ nsCSSRendering::DrawTableBorderSegment(nsRenderingContext& aContext,
if (NS_SIDE_RIGHT == aEndBevelSide) {
rightRect.height -= aEndBevelOffset - endBevel;
}
DrawSolidBorderSegment(aContext, rightRect, twipsPerPixel, aStartBevelSide,
DrawSolidBorderSegment(aContext, rightRect, aBorderColor, twipsPerPixel, aStartBevelSide,
startBevel, aEndBevelSide, endBevel);
}
break;
}
// else fall through to solid
case NS_STYLE_BORDER_STYLE_SOLID:
DrawSolidBorderSegment(aContext, aBorder, twipsPerPixel, aStartBevelSide,
DrawSolidBorderSegment(aContext, aBorder, aBorderColor, twipsPerPixel, aStartBevelSide,
aStartBevelOffset, aEndBevelSide, aEndBevelOffset);
break;
case NS_STYLE_BORDER_STYLE_OUTSET:

View File

@ -7035,8 +7035,18 @@ AutoMaybeDisableFontInflation::~AutoMaybeDisableFontInflation()
}
namespace mozilla {
Rect NSRectToRect(const nsRect& aRect, int32_t aAppUnitsPerPixel)
{
return Rect(Float(aRect.x) / aAppUnitsPerPixel,
Float(aRect.y) / aAppUnitsPerPixel,
Float(aRect.width) / aAppUnitsPerPixel,
Float(aRect.height) / aAppUnitsPerPixel);
}
namespace layout {
void
MaybeSetupTransactionIdAllocator(layers::LayerManager* aManager, nsView* aView)
{

View File

@ -122,6 +122,7 @@ class nsLayoutUtils
typedef mozilla::gfx::Color Color;
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::gfx::Float Float;
typedef mozilla::gfx::Point Point;
typedef mozilla::gfx::Rect Rect;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
typedef mozilla::gfx::StrokeOptions StrokeOptions;
@ -2392,6 +2393,25 @@ nsLayoutUtils::PointIsCloserToRect(PointType aPoint, const RectType& aRect,
}
namespace mozilla {
/**
* Converts an nsPoint in app units to a Moz2D Point in pixels (whether those
* are device pixels or CSS px depends on what the caller chooses to pass as
* aAppUnitsPerPixel).
*/
inline gfx::Point NSPointToPoint(const nsPoint& aPoint,
int32_t aAppUnitsPerPixel) {
return gfx::Point(gfx::Float(aPoint.x) / aAppUnitsPerPixel,
gfx::Float(aPoint.y) / aAppUnitsPerPixel);
}
/**
* Converts an nsRect in app units to a Moz2D Rect in pixels (whether those
* are device pixels or CSS px depends on what the caller chooses to pass as
* aAppUnitsPerPixel).
*/
gfx::Rect NSRectToRect(const nsRect& aRect, int32_t aAppUnitsPerPixel);
namespace layout {
/**

View File

@ -4,14 +4,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsGfxCheckboxControlFrame.h"
#include "mozilla/gfx/2D.h"
#include "nsIContent.h"
#include "nsCOMPtr.h"
#include "nsLayoutUtils.h"
#include "nsRenderingContext.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsDisplayList.h"
#include <algorithm>
using namespace mozilla;
using namespace mozilla::gfx;
static void
PaintCheckMark(nsIFrame* aFrame,
@ -34,16 +38,21 @@ PaintCheckMark(nsIFrame* aFrame,
nsPoint paintCenter(rect.x + rect.width / 2,
rect.y + rect.height / 2);
nsPoint paintPolygon[checkNumPoints];
// Convert checkmark for screen rendering
for (int32_t polyIndex = 0; polyIndex < checkNumPoints; polyIndex++) {
paintPolygon[polyIndex] = paintCenter +
nsPoint(checkPolygonX[polyIndex] * paintScale,
checkPolygonY[polyIndex] * paintScale);
}
DrawTarget* drawTarget = aCtx->GetDrawTarget();
RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder();
nsPoint p = paintCenter + nsPoint(checkPolygonX[0] * paintScale,
checkPolygonY[0] * paintScale);
aCtx->SetColor(aFrame->StyleColor()->mColor);
aCtx->FillPolygon(paintPolygon, checkNumPoints);
int32_t appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
builder->MoveTo(NSPointToPoint(p, appUnitsPerDevPixel));
for (int32_t polyIndex = 1; polyIndex < checkNumPoints; polyIndex++) {
p = paintCenter + nsPoint(checkPolygonX[polyIndex] * paintScale,
checkPolygonY[polyIndex] * paintScale);
builder->LineTo(NSPointToPoint(p, appUnitsPerDevPixel));
}
RefPtr<Path> path = builder->Finish();
drawTarget->Fill(path,
ColorPattern(ToDeviceColor(aFrame->StyleColor()->mColor)));
}
static void

View File

@ -391,27 +391,33 @@ nsBulletFrame::PaintBullet(nsRenderingContext& aRenderingContext, nsPoint aPt,
rect.x = pc->RoundAppUnitsToNearestDevPixels(rect.x);
rect.y = pc->RoundAppUnitsToNearestDevPixels(rect.y);
nsPoint points[3];
DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
RefPtr<PathBuilder> builder = drawTarget->CreatePathBuilder();
int32_t appUnitsPerDevPixel = pc->AppUnitsPerDevPixel();
if (isDown) {
// to bottom
points[0] = rect.TopLeft();
points[1] = rect.TopRight();
points[2] = (rect.BottomLeft() + rect.BottomRight()) / 2;
builder->MoveTo(NSPointToPoint(rect.TopLeft(), appUnitsPerDevPixel));
builder->LineTo(NSPointToPoint(rect.TopRight(), appUnitsPerDevPixel));
builder->LineTo(NSPointToPoint((rect.BottomLeft() + rect.BottomRight()) / 2,
appUnitsPerDevPixel));
} else {
bool isLR = isVertical ? wm.IsVerticalLR() : wm.IsBidiLTR();
if (isLR) {
// to right
points[0] = rect.TopLeft();
points[1] = (rect.TopRight() + rect.BottomRight()) / 2;
points[2] = rect.BottomLeft();
builder->MoveTo(NSPointToPoint(rect.TopLeft(), appUnitsPerDevPixel));
builder->LineTo(NSPointToPoint((rect.TopRight() + rect.BottomRight()) / 2,
appUnitsPerDevPixel));
builder->LineTo(NSPointToPoint(rect.BottomLeft(), appUnitsPerDevPixel));
} else {
// to left
points[0] = rect.TopRight();
points[1] = rect.BottomRight();
points[2] = (rect.TopLeft() + rect.BottomLeft()) / 2;
builder->MoveTo(NSPointToPoint(rect.TopRight(), appUnitsPerDevPixel));
builder->LineTo(NSPointToPoint(rect.BottomRight(), appUnitsPerDevPixel));
builder->LineTo(NSPointToPoint((rect.TopLeft() + rect.BottomLeft()) / 2,
appUnitsPerDevPixel));
}
}
aRenderingContext.FillPolygon(points, 3);
RefPtr<Path> path = builder->Finish();
drawTarget->Fill(path, color);
}
break;