#include <math.h> before libart's headers, so that M_PI isn't already
defined. libart has an #ifdef guard, math.h obviously doesn't. Hopefully fixes AIX build bustage. Not part of defaut build.
This commit is contained in:
Родитель
eafd9f9e37
Коммит
31218aebc6
|
@ -1,285 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ----- BEGIN LICENSE BLOCK -----
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Crocodile Clips Ltd..
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ----- END LICENSE BLOCK ----- */
|
||||
|
||||
#include "nsSVGBPathBuilder.h"
|
||||
#include <math.h>
|
||||
#include<stdio.h>
|
||||
nsSVGBPathBuilder::nsSVGBPathBuilder()
|
||||
: mBPath(nsnull),
|
||||
mBPathSize(0),
|
||||
mBPathEnd(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PRBool nsSVGBPathBuilder::IsEmpty()
|
||||
{
|
||||
return (!mBPath);
|
||||
}
|
||||
|
||||
ArtBpath* nsSVGBPathBuilder::GetBPath()
|
||||
{
|
||||
if (mBPath)
|
||||
EnsureBPathTerminated();
|
||||
return mBPath;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsASVGPathBuilder methods
|
||||
|
||||
void nsSVGBPathBuilder::Moveto(float x, float y)
|
||||
{
|
||||
EnsureBPathSpace();
|
||||
|
||||
mBPath[mBPathEnd].code = ART_MOVETO_OPEN;
|
||||
mBPath[mBPathEnd].x3 = x;
|
||||
mBPath[mBPathEnd].y3 = y;
|
||||
|
||||
++mBPathEnd;
|
||||
}
|
||||
|
||||
void nsSVGBPathBuilder::Lineto(float x, float y)
|
||||
{
|
||||
EnsureBPathSpace();
|
||||
|
||||
mBPath[mBPathEnd].code = ART_LINETO;
|
||||
mBPath[mBPathEnd].x3 = x;
|
||||
mBPath[mBPathEnd].y3 = y;
|
||||
|
||||
++mBPathEnd;
|
||||
}
|
||||
|
||||
void nsSVGBPathBuilder::Curveto(float x, float y, float x1, float y1, float x2, float y2)
|
||||
{
|
||||
EnsureBPathSpace();
|
||||
|
||||
mBPath[mBPathEnd].code = ART_CURVETO;
|
||||
mBPath[mBPathEnd].x1 = x1;
|
||||
mBPath[mBPathEnd].y1 = y1;
|
||||
mBPath[mBPathEnd].x2 = x2;
|
||||
mBPath[mBPathEnd].y2 = y2;
|
||||
mBPath[mBPathEnd].x3 = x;
|
||||
mBPath[mBPathEnd].y3 = y;
|
||||
|
||||
++mBPathEnd;
|
||||
}
|
||||
|
||||
void nsSVGBPathBuilder::Arcto(float x2, float y2, float rx, float ry, float angle,
|
||||
PRBool largeArcFlag, PRBool sweepFlag)
|
||||
{
|
||||
const double pi = 3.14159265359;
|
||||
const double radPerDeg = pi/180.0;
|
||||
|
||||
float x1=0.0f, y1=0.0f;
|
||||
NS_ASSERTION(mBPathEnd > 0, "Arcto needs a start position");
|
||||
if (mBPathEnd > 0) {
|
||||
x1 = (float)(mBPath[mBPathEnd-1].x3);
|
||||
y1 = (float)(mBPath[mBPathEnd-1].y3);
|
||||
}
|
||||
|
||||
// 1. Treat out-of-range parameters as described in
|
||||
// http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
|
||||
|
||||
// If the endpoints (x1, y1) and (x2, y2) are identical, then this
|
||||
// is equivalent to omitting the elliptical arc segment entirely
|
||||
if (x1 == x2 && y1 == y2) return;
|
||||
|
||||
// If rX = 0 or rY = 0 then this arc is treated as a straight line
|
||||
// segment (a "lineto") joining the endpoints.
|
||||
if (rx == 0.0f || ry == 0.0f) {
|
||||
Lineto(x2, y2);
|
||||
return;
|
||||
}
|
||||
|
||||
// If rX or rY have negative signs, these are dropped; the absolute
|
||||
// value is used instead.
|
||||
if (rx<0.0) rx = -rx;
|
||||
if (ry<0.0) ry = -ry;
|
||||
|
||||
// 2. convert to center parameterization as shown in
|
||||
// http://www.w3.org/TR/SVG/implnote.html
|
||||
double sinPhi = sin(angle*radPerDeg);
|
||||
double cosPhi = cos(angle*radPerDeg);
|
||||
|
||||
double x1dash = cosPhi * (x1-x2)/2.0 + sinPhi * (y1-y2)/2.0;
|
||||
double y1dash = -sinPhi * (x1-x2)/2.0 + cosPhi * (y1-y2)/2.0;
|
||||
|
||||
double root;
|
||||
double numerator = rx*rx*ry*ry - rx*rx*y1dash*y1dash - ry*ry*x1dash*x1dash;
|
||||
|
||||
if (numerator < 0.0) {
|
||||
// If rX , rY and are such that there is no solution (basically,
|
||||
// the ellipse is not big enough to reach from (x1, y1) to (x2,
|
||||
// y2)) then the ellipse is scaled up uniformly until there is
|
||||
// exactly one solution (until the ellipse is just big enough).
|
||||
|
||||
// -> find factor s, such that numerator' with rx'=s*rx and
|
||||
// ry'=s*ry becomes 0 :
|
||||
float s = (float)sqrt(1.0 - numerator/(rx*rx*ry*ry));
|
||||
|
||||
rx *= s;
|
||||
ry *= s;
|
||||
root = 0.0;
|
||||
|
||||
}
|
||||
else {
|
||||
root = (largeArcFlag == sweepFlag ? -1.0 : 1.0) *
|
||||
sqrt( numerator/(rx*rx*y1dash*y1dash+ry*ry*x1dash*x1dash) );
|
||||
}
|
||||
|
||||
double cxdash = root*rx*y1dash/ry;
|
||||
double cydash = -root*ry*x1dash/rx;
|
||||
|
||||
double cx = cosPhi * cxdash - sinPhi * cydash + (x1+x2)/2.0;
|
||||
double cy = sinPhi * cxdash + cosPhi * cydash + (y1+y2)/2.0;
|
||||
double theta1 = CalcVectorAngle(1.0, 0.0, (x1dash-cxdash)/rx, (y1dash-cydash)/ry);
|
||||
double dtheta = CalcVectorAngle((x1dash-cxdash)/rx, (y1dash-cydash)/ry,
|
||||
(-x1dash-cxdash)/rx, (-y1dash-cydash)/ry);
|
||||
if (!sweepFlag && dtheta>0)
|
||||
dtheta -= 2.0*pi;
|
||||
else if (sweepFlag && dtheta<0)
|
||||
dtheta += 2.0*pi;
|
||||
|
||||
// 3. convert into cubic bezier segments <= 90deg
|
||||
int segments = (int)ceil(fabs(dtheta/(pi/2.0)));
|
||||
double delta = dtheta/segments;
|
||||
double t = 8.0/3.0 * sin(delta/4.0) * sin(delta/4.0) / sin(delta/2.0);
|
||||
|
||||
for (int i = 0; i < segments; ++i) {
|
||||
double cosTheta1 = cos(theta1);
|
||||
double sinTheta1 = sin(theta1);
|
||||
double theta2 = theta1 + delta;
|
||||
double cosTheta2 = cos(theta2);
|
||||
double sinTheta2 = sin(theta2);
|
||||
|
||||
// a) calculate endpoint of the segment:
|
||||
double xe = cosPhi * rx*cosTheta2 - sinPhi * ry*sinTheta2 + cx;
|
||||
double ye = sinPhi * rx*cosTheta2 + cosPhi * ry*sinTheta2 + cy;
|
||||
|
||||
// b) calculate gradients at start/end points of segment:
|
||||
double dx1 = t * ( - cosPhi * rx*sinTheta1 - sinPhi * ry*cosTheta1);
|
||||
double dy1 = t * ( - sinPhi * rx*sinTheta1 + cosPhi * ry*cosTheta1);
|
||||
|
||||
double dxe = t * ( cosPhi * rx*sinTheta2 + sinPhi * ry*cosTheta2);
|
||||
double dye = t * ( sinPhi * rx*sinTheta2 - cosPhi * ry*cosTheta2);
|
||||
|
||||
// c) draw the cubic bezier:
|
||||
Curveto((float)xe, (float)ye, (float)(x1+dx1), (float)(y1+dy1),
|
||||
(float)(xe+dxe), (float)(ye+dye));
|
||||
|
||||
// do next segment
|
||||
theta1 = theta2;
|
||||
x1 = (float)xe;
|
||||
y1 = (float)ye;
|
||||
}
|
||||
}
|
||||
|
||||
void nsSVGBPathBuilder::ClosePath(float *currX, float *currY)
|
||||
{
|
||||
PRInt32 subpath = GetLastOpenBPath();
|
||||
NS_ASSERTION(subpath>=0, "no open subpath");
|
||||
if (subpath<0) return;
|
||||
|
||||
// insert closing line if needed:
|
||||
if (mBPath[subpath].x3 != mBPath[mBPathEnd-1].x3 ||
|
||||
mBPath[subpath].y3 != mBPath[mBPathEnd-1].y3) {
|
||||
Lineto((float)mBPath[subpath].x3, (float)mBPath[subpath].y3);
|
||||
}
|
||||
|
||||
mBPath[subpath].code = ART_MOVETO;
|
||||
|
||||
*currX = mBPath[subpath].x3;
|
||||
*currY = mBPath[subpath].y3;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// helpers
|
||||
|
||||
void nsSVGBPathBuilder::EnsureBPathSpace(PRUint32 space)
|
||||
{
|
||||
const PRInt32 minGrowSize = 10;
|
||||
|
||||
if (mBPathSize - mBPathEnd >= space)
|
||||
return;
|
||||
|
||||
if (space < minGrowSize)
|
||||
space = minGrowSize;
|
||||
|
||||
mBPathSize += space;
|
||||
|
||||
if (!mBPath) {
|
||||
mBPath = art_new(ArtBpath, mBPathSize);
|
||||
}
|
||||
else {
|
||||
mBPath = art_renew(mBPath, ArtBpath, mBPathSize);
|
||||
}
|
||||
}
|
||||
|
||||
void nsSVGBPathBuilder::EnsureBPathTerminated()
|
||||
{
|
||||
NS_ASSERTION (mBPath, "no bpath");
|
||||
NS_ASSERTION (mBPathEnd>0, "trying to terminate empty bpath");
|
||||
|
||||
if (mBPathEnd>0 && mBPath[mBPathEnd-1].code == ART_END) return;
|
||||
|
||||
EnsureBPathSpace(1);
|
||||
mBPath[mBPathEnd++].code = ART_END;
|
||||
}
|
||||
|
||||
PRInt32 nsSVGBPathBuilder::GetLastOpenBPath()
|
||||
{
|
||||
if (!mBPath) return -1;
|
||||
|
||||
PRInt32 i = mBPathEnd;
|
||||
while (--i >= 0) {
|
||||
if (mBPath[i].code == ART_MOVETO_OPEN)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
double nsSVGBPathBuilder::CalcVectorAngle(double ux, double uy, double vx, double vy)
|
||||
{
|
||||
double ta = atan2(uy, ux);
|
||||
double tb = atan2(vy, vx);
|
||||
if (tb >= ta)
|
||||
return tb-ta;
|
||||
return 6.28318530718 - (ta-tb);
|
||||
}
|
||||
|
|
@ -37,13 +37,14 @@
|
|||
*
|
||||
* ----- END LICENSE BLOCK ----- */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "nsSVGGraphicFrame.h"
|
||||
#include "nsIDOMSVGAnimatedPathData.h"
|
||||
#include "nsIDOMSVGPathSegList.h"
|
||||
#include "nsIDOMSVGPathSeg.h"
|
||||
#include "nsASVGPathBuilder.h"
|
||||
#include "nsIDOMSVGMatrix.h"
|
||||
#include <math.h>
|
||||
|
||||
class nsSVGPathFrame : public nsSVGGraphicFrame
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче