зеркало из https://github.com/mozilla/pjs.git
Bug 307708 � filters should operate in linearRGB color space by default r=dbaron,r=tor,sr=roc
This commit is contained in:
Родитель
bb79257e15
Коммит
84928d38d8
|
@ -908,7 +908,9 @@ GK_ATOM(clip_rule, "clip-rule")
|
|||
GK_ATOM(clipPath, "clipPath")
|
||||
GK_ATOM(clipPathUnits, "clipPathUnits")
|
||||
GK_ATOM(cm, "cm")
|
||||
GK_ATOM(colorProfile,"color-profile")
|
||||
GK_ATOM(colorInterpolation, "color-interpolation")
|
||||
GK_ATOM(colorInterpolationFilters, "color-interpolation-filters")
|
||||
GK_ATOM(colorProfile, "color-profile")
|
||||
GK_ATOM(cursor, "cursor")
|
||||
GK_ATOM(cx, "cx")
|
||||
GK_ATOM(cy, "cy")
|
||||
|
@ -1004,6 +1006,7 @@ GK_ATOM(letter_spacing, "letter-spacing")
|
|||
GK_ATOM(lighten, "lighten")
|
||||
GK_ATOM(linear, "linear")
|
||||
GK_ATOM(linearGradient, "linearGradient")
|
||||
GK_ATOM(linearRGB, "linearRGB")
|
||||
GK_ATOM(magnify, "magnify")
|
||||
GK_ATOM(marker, "marker")
|
||||
GK_ATOM(marker_end, "marker-end")
|
||||
|
@ -1073,6 +1076,7 @@ GK_ATOM(skewY, "skewY")
|
|||
GK_ATOM(slope, "slope")
|
||||
GK_ATOM(spacing, "spacing")
|
||||
GK_ATOM(spreadMethod, "spreadMethod")
|
||||
GK_ATOM(sRGB, "sRGB")
|
||||
GK_ATOM(startOffset, "startOffset")
|
||||
GK_ATOM(stdDeviation, "stdDeviation")
|
||||
GK_ATOM(stitch, "stitch")
|
||||
|
|
|
@ -110,6 +110,7 @@ nsSVGDefsElement::IsAttributeMapped(const nsIAtom* name) const
|
|||
{
|
||||
static const MappedAttributeEntry* const map[] = {
|
||||
sFEFloodMap,
|
||||
sFiltersMap,
|
||||
sFontSpecificationMap,
|
||||
sGradientStopMap,
|
||||
sMarkersMap,
|
||||
|
|
|
@ -420,6 +420,7 @@ nsSVGElement::sFillStrokeMap[] = {
|
|||
nsSVGElement::sGraphicsMap[] = {
|
||||
{ &nsGkAtoms::clip_path },
|
||||
{ &nsGkAtoms::clip_rule },
|
||||
{ &nsGkAtoms::colorInterpolation },
|
||||
{ &nsGkAtoms::cursor },
|
||||
{ &nsGkAtoms::display },
|
||||
{ &nsGkAtoms::filter },
|
||||
|
@ -496,6 +497,13 @@ nsSVGElement::sColorMap[] = {
|
|||
{ nsnull }
|
||||
};
|
||||
|
||||
// PresentationAttributes-Filters
|
||||
/* static */ const nsGenericElement::MappedAttributeEntry
|
||||
nsSVGElement::sFiltersMap[] = {
|
||||
{ &nsGkAtoms::colorInterpolationFilters },
|
||||
{ nsnull }
|
||||
};
|
||||
|
||||
// PresentationAttributes-feFlood
|
||||
/* static */ const nsGenericElement::MappedAttributeEntry
|
||||
nsSVGElement::sFEFloodMap[] = {
|
||||
|
|
|
@ -98,6 +98,7 @@ public:
|
|||
static const MappedAttributeEntry sViewportsMap[];
|
||||
static const MappedAttributeEntry sMarkersMap[];
|
||||
static const MappedAttributeEntry sColorMap[];
|
||||
static const MappedAttributeEntry sFiltersMap[];
|
||||
static const MappedAttributeEntry sFEFloodMap[];
|
||||
|
||||
// nsIDOMNode
|
||||
|
|
|
@ -267,6 +267,7 @@ nsSVGFilterElement::IsAttributeMapped(const nsIAtom* name) const
|
|||
{
|
||||
static const MappedAttributeEntry* const map[] = {
|
||||
sFEFloodMap,
|
||||
sFiltersMap,
|
||||
sFontSpecificationMap,
|
||||
sGradientStopMap,
|
||||
sMarkersMap,
|
||||
|
|
|
@ -165,6 +165,25 @@ nsSVGFE::ScanDualValueAttribute(const nsAString& aValue, nsIAtom* aAttribute,
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsSVGFilterInstance::ColorModel
|
||||
nsSVGFE::GetColorModel(nsSVGFilterInstance::ColorModel::AlphaChannel aAlphaChannel)
|
||||
{
|
||||
nsSVGFilterInstance::ColorModel
|
||||
colorModel(nsSVGFilterInstance::ColorModel::LINEAR_RGB,
|
||||
aAlphaChannel);
|
||||
|
||||
nsIFrame* frame = GetPrimaryFrame();
|
||||
if (!frame)
|
||||
return colorModel;
|
||||
|
||||
nsStyleContext* style = frame->GetStyleContext();
|
||||
if (style->GetStyleSVG()->mColorInterpolationFilters ==
|
||||
NS_STYLE_COLOR_INTERPOLATION_SRGB)
|
||||
colorModel.mColorSpace = nsSVGFilterInstance::ColorModel::SRGB;
|
||||
|
||||
return colorModel;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMSVGFilterPrimitiveStandardAttributes methods
|
||||
|
||||
|
@ -246,7 +265,8 @@ class nsSVGFilterResource
|
|||
{
|
||||
|
||||
public:
|
||||
nsSVGFilterResource(nsSVGFilterInstance* aInstance);
|
||||
nsSVGFilterResource(nsSVGFilterInstance* aInstance,
|
||||
const nsSVGFilterInstance::ColorModel &aColorModel);
|
||||
~nsSVGFilterResource();
|
||||
|
||||
/*
|
||||
|
@ -316,16 +336,19 @@ private:
|
|||
PRUint8 *mSourceData, *mTargetData;
|
||||
PRUint32 mWidth, mHeight;
|
||||
PRInt32 mStride;
|
||||
nsSVGFilterInstance::ColorModel mColorModel;
|
||||
};
|
||||
|
||||
nsSVGFilterResource::nsSVGFilterResource(nsSVGFilterInstance* aInstance):
|
||||
nsSVGFilterResource::nsSVGFilterResource(nsSVGFilterInstance* aInstance,
|
||||
const nsSVGFilterInstance::ColorModel &aColorModel) :
|
||||
mTargetImage(nsnull),
|
||||
mInstance(aInstance),
|
||||
mSourceData(nsnull),
|
||||
mTargetData(nsnull),
|
||||
mWidth(0),
|
||||
mHeight(0),
|
||||
mStride(0)
|
||||
mStride(0),
|
||||
mColorModel(aColorModel)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -343,7 +366,7 @@ nsSVGFilterResource::AcquireSourceImage(nsIDOMSVGAnimatedString* aIn,
|
|||
|
||||
nsRect defaultRect;
|
||||
cairo_surface_t *surface;
|
||||
mInstance->LookupImage(mInput, &surface, &defaultRect);
|
||||
mInstance->LookupImage(mInput, &surface, &defaultRect, mColorModel);
|
||||
if (!surface) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -390,7 +413,7 @@ nsSVGFilterResource::ReleaseTarget()
|
|||
return;
|
||||
}
|
||||
FixupTarget();
|
||||
mInstance->DefineImage(mResult, mTargetImage, mRect);
|
||||
mInstance->DefineImage(mResult, mTargetImage, mRect, mColorModel);
|
||||
|
||||
// filter instance now owns the image
|
||||
cairo_surface_destroy(mTargetImage);
|
||||
|
@ -740,7 +763,8 @@ nsSVGFEGaussianBlurElement::Filter(nsSVGFilterInstance *instance)
|
|||
{
|
||||
nsresult rv;
|
||||
PRUint8 *sourceData, *targetData;
|
||||
nsSVGFilterResource fr(instance);
|
||||
nsSVGFilterResource fr(instance,
|
||||
GetColorModel(nsSVGFilterInstance::ColorModel::PREMULTIPLIED));
|
||||
|
||||
rv = fr.AcquireSourceImage(mIn1, this, &sourceData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -962,7 +986,8 @@ nsSVGFEBlendElement::Filter(nsSVGFilterInstance *instance)
|
|||
{
|
||||
nsresult rv;
|
||||
PRUint8 *sourceData, *targetData;
|
||||
nsSVGFilterResource fr(instance);
|
||||
nsSVGFilterResource fr(instance,
|
||||
GetColorModel(nsSVGFilterInstance::ColorModel::PREMULTIPLIED));
|
||||
|
||||
rv = fr.AcquireSourceImage(mIn1, this, &sourceData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -1237,7 +1262,8 @@ nsSVGFECompositeElement::Filter(nsSVGFilterInstance *instance)
|
|||
PRUint8 *sourceData, *targetData;
|
||||
cairo_surface_t *sourceSurface, *targetSurface;
|
||||
|
||||
nsSVGFilterResource fr(instance);
|
||||
nsSVGFilterResource fr(instance,
|
||||
GetColorModel(nsSVGFilterInstance::ColorModel::PREMULTIPLIED));
|
||||
rv = fr.AcquireSourceImage(mIn2, this, &sourceData, &sourceSurface);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = fr.AcquireTargetImage(mResult, &targetData, &targetSurface);
|
||||
|
@ -1446,7 +1472,8 @@ nsSVGFEComponentTransferElement::Filter(nsSVGFilterInstance *instance)
|
|||
{
|
||||
nsresult rv;
|
||||
PRUint8 *sourceData, *targetData;
|
||||
nsSVGFilterResource fr(instance);
|
||||
nsSVGFilterResource fr(instance,
|
||||
GetColorModel(nsSVGFilterInstance::ColorModel::UNPREMULTIPLIED));
|
||||
|
||||
rv = fr.AcquireSourceImage(mIn1, this, &sourceData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -1483,20 +1510,10 @@ nsSVGFEComponentTransferElement::Filter(nsSVGFilterInstance *instance)
|
|||
for (PRInt32 y = rect.y; y < rect.y + rect.height; y++)
|
||||
for (PRInt32 x = rect.x; x < rect.x + rect.width; x++) {
|
||||
PRInt32 targIndex = y * stride + x * 4;
|
||||
PRUint8 r, g, b, a;
|
||||
a = sourceData[targIndex + 3];
|
||||
if (a) {
|
||||
b = tableB[(255 * (PRUint32)sourceData[targIndex]) / a];
|
||||
g = tableG[(255 * (PRUint32)sourceData[targIndex + 1]) / a];
|
||||
r = tableR[(255 * (PRUint32)sourceData[targIndex + 2]) / a];
|
||||
} else {
|
||||
b = g = r = 0;
|
||||
}
|
||||
a = tableA[a];
|
||||
FAST_DIVIDE_BY_255(targetData[targIndex], b * a);
|
||||
FAST_DIVIDE_BY_255(targetData[targIndex + 1], g * a);
|
||||
FAST_DIVIDE_BY_255(targetData[targIndex + 2], r * a);
|
||||
targetData[targIndex + 3] = a;
|
||||
targetData[targIndex] = tableB[sourceData[targIndex]];
|
||||
targetData[targIndex + 1] = tableG[sourceData[targIndex + 1]];
|
||||
targetData[targIndex + 2] = tableR[sourceData[targIndex + 2]];
|
||||
targetData[targIndex + 3] = tableA[sourceData[targIndex + 3]];
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2084,7 +2101,8 @@ nsSVGFEMergeElement::Filter(nsSVGFilterInstance *instance)
|
|||
PRUint8 *sourceData, *targetData;
|
||||
cairo_surface_t *sourceSurface, *targetSurface;
|
||||
|
||||
nsSVGFilterResource fr(instance);
|
||||
nsSVGFilterResource fr(instance,
|
||||
GetColorModel(nsSVGFilterInstance::ColorModel::PREMULTIPLIED));
|
||||
rv = fr.AcquireTargetImage(mResult, &targetData, &targetSurface);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -2420,7 +2438,8 @@ nsSVGFEOffsetElement::Filter(nsSVGFilterInstance *instance)
|
|||
{
|
||||
nsresult rv;
|
||||
PRUint8 *sourceData, *targetData;
|
||||
nsSVGFilterResource fr(instance);
|
||||
nsSVGFilterResource fr(instance,
|
||||
GetColorModel(nsSVGFilterInstance::ColorModel::PREMULTIPLIED));
|
||||
|
||||
rv = fr.AcquireSourceImage(mIn1, this, &sourceData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -2588,7 +2607,11 @@ nsSVGFEFloodElement::Filter(nsSVGFilterInstance *instance)
|
|||
nsresult rv;
|
||||
PRUint8 *sourceData, *targetData;
|
||||
cairo_surface_t *targetSurface;
|
||||
nsSVGFilterResource fr(instance);
|
||||
// flood colour is sRGB
|
||||
nsSVGFilterInstance::ColorModel
|
||||
colorModel(nsSVGFilterInstance::ColorModel::SRGB,
|
||||
nsSVGFilterInstance::ColorModel::PREMULTIPLIED);
|
||||
nsSVGFilterResource fr(instance, colorModel);
|
||||
|
||||
rv = fr.AcquireSourceImage(mIn1, this, &sourceData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -2633,7 +2656,8 @@ NS_IMETHODIMP_(PRBool)
|
|||
nsSVGFEFloodElement::IsAttributeMapped(const nsIAtom* name) const
|
||||
{
|
||||
static const MappedAttributeEntry* const map[] = {
|
||||
sFEFloodMap
|
||||
sFEFloodMap,
|
||||
sFiltersMap
|
||||
};
|
||||
|
||||
return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) ||
|
||||
|
@ -2918,7 +2942,8 @@ nsSVGFETurbulenceElement::Filter(nsSVGFilterInstance *instance)
|
|||
{
|
||||
nsresult rv;
|
||||
PRUint8 *sourceData, *targetData;
|
||||
nsSVGFilterResource fr(instance);
|
||||
nsSVGFilterResource fr(instance,
|
||||
GetColorModel(nsSVGFilterInstance::ColorModel::PREMULTIPLIED));
|
||||
|
||||
nsIDOMSVGAnimatedString* sourceGraphic = nsnull;
|
||||
rv = NS_NewSVGAnimatedString(&sourceGraphic);
|
||||
|
@ -3383,7 +3408,8 @@ nsSVGFEMorphologyElement::Filter(nsSVGFilterInstance *instance)
|
|||
{
|
||||
nsresult rv;
|
||||
PRUint8 *sourceData, *targetData;
|
||||
nsSVGFilterResource fr(instance);
|
||||
nsSVGFilterResource fr(instance,
|
||||
GetColorModel(nsSVGFilterInstance::ColorModel::PREMULTIPLIED));
|
||||
|
||||
rv = fr.AcquireSourceImage(mIn1, this, &sourceData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -61,6 +61,9 @@ protected:
|
|||
NumberInfo* aInfo1, NumberInfo* aInfo2,
|
||||
nsAttrValue& aResult);
|
||||
|
||||
nsSVGFilterInstance::ColorModel
|
||||
GetColorModel(nsSVGFilterInstance::ColorModel::AlphaChannel aAlphaChannel);
|
||||
|
||||
public:
|
||||
// interfaces:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
|
|
@ -114,6 +114,7 @@ nsSVGForeignObjectElement::IsAttributeMapped(const nsIAtom* name) const
|
|||
{
|
||||
static const MappedAttributeEntry* const map[] = {
|
||||
sFEFloodMap,
|
||||
sFiltersMap,
|
||||
sFontSpecificationMap,
|
||||
sGradientStopMap,
|
||||
sMarkersMap,
|
||||
|
|
|
@ -111,10 +111,11 @@ NS_IMETHODIMP_(PRBool)
|
|||
nsSVGGElement::IsAttributeMapped(const nsIAtom* name) const
|
||||
{
|
||||
static const MappedAttributeEntry* const map[] = {
|
||||
sTextContentElementsMap,
|
||||
sFontSpecificationMap,
|
||||
sColorMap,
|
||||
sFEFloodMap
|
||||
sFEFloodMap,
|
||||
sFiltersMap,
|
||||
sFontSpecificationMap,
|
||||
sTextContentElementsMap,
|
||||
};
|
||||
|
||||
return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) ||
|
||||
|
|
|
@ -290,6 +290,7 @@ nsSVGMarkerElement::IsAttributeMapped(const nsIAtom* name) const
|
|||
{
|
||||
static const MappedAttributeEntry* const map[] = {
|
||||
sFEFloodMap,
|
||||
sFiltersMap,
|
||||
sFontSpecificationMap,
|
||||
sGradientStopMap,
|
||||
sMarkersMap,
|
||||
|
|
|
@ -184,6 +184,7 @@ nsSVGMaskElement::IsAttributeMapped(const nsIAtom* name) const
|
|||
{
|
||||
static const MappedAttributeEntry* const map[] = {
|
||||
sFEFloodMap,
|
||||
sFiltersMap,
|
||||
sFontSpecificationMap,
|
||||
sGradientStopMap,
|
||||
sMarkersMap,
|
||||
|
|
|
@ -280,6 +280,7 @@ nsSVGPatternElement::IsAttributeMapped(const nsIAtom* name) const
|
|||
{
|
||||
static const MappedAttributeEntry* const map[] = {
|
||||
sFEFloodMap,
|
||||
sFiltersMap,
|
||||
sFontSpecificationMap,
|
||||
sGradientStopMap,
|
||||
sMarkersMap,
|
||||
|
|
|
@ -1114,6 +1114,7 @@ nsSVGSVGElement::IsAttributeMapped(const nsIAtom* name) const
|
|||
static const MappedAttributeEntry* const map[] = {
|
||||
sColorMap,
|
||||
sFEFloodMap,
|
||||
sFiltersMap,
|
||||
sFillStrokeMap,
|
||||
sFontSpecificationMap,
|
||||
sGradientStopMap,
|
||||
|
|
|
@ -174,6 +174,7 @@ nsSVGSymbolElement::IsAttributeMapped(const nsIAtom* name) const
|
|||
{
|
||||
static const MappedAttributeEntry* const map[] = {
|
||||
sFEFloodMap,
|
||||
sFiltersMap,
|
||||
sFontSpecificationMap,
|
||||
sGradientStopMap,
|
||||
sMarkersMap,
|
||||
|
|
|
@ -578,6 +578,7 @@ nsSVGUseElement::IsAttributeMapped(const nsIAtom* name) const
|
|||
{
|
||||
static const MappedAttributeEntry* const map[] = {
|
||||
sFEFloodMap,
|
||||
sFiltersMap,
|
||||
sFontSpecificationMap,
|
||||
sGradientStopMap,
|
||||
sMarkersMap,
|
||||
|
|
|
@ -637,11 +637,7 @@
|
|||
#define NS_STYLE_COLUMN_COUNT_UNLIMITED (-1)
|
||||
|
||||
#ifdef MOZ_SVG
|
||||
// Some of our constants must map to the same values as those defined in
|
||||
// nsISVG{,Path,Glyph}GeometrySource.idl/
|
||||
// I don't want to add a dependency on the SVG module
|
||||
// everywhere by #include'ing nsISVG{,Path,Glyph}GeometrySource.h, so these consts
|
||||
// have to be kept in sync manually.
|
||||
// See nsStyleSVG
|
||||
|
||||
// dominant-baseline
|
||||
#define NS_STYLE_DOMINANT_BASELINE_AUTO 0
|
||||
|
@ -658,8 +654,8 @@
|
|||
#define NS_STYLE_DOMINANT_BASELINE_TEXT_BEFORE_EDGE 11
|
||||
|
||||
// fill-rule
|
||||
#define NS_STYLE_FILL_RULE_NONZERO 0 /* == nsISVGGeometrySource::FILL_RULE_NONZERO */
|
||||
#define NS_STYLE_FILL_RULE_EVENODD 1 /* == nsISVGGeometrySource::FILL_RULE_EVENODD */
|
||||
#define NS_STYLE_FILL_RULE_NONZERO 0
|
||||
#define NS_STYLE_FILL_RULE_EVENODD 1
|
||||
|
||||
// pointer-events
|
||||
#define NS_STYLE_POINTER_EVENTS_NONE 0
|
||||
|
@ -673,21 +669,20 @@
|
|||
#define NS_STYLE_POINTER_EVENTS_ALL 8
|
||||
|
||||
// shape-rendering
|
||||
#define NS_STYLE_SHAPE_RENDERING_AUTO 0 /* == nsISVGPathGeometrySource::SHAPE_RENDERING_AUTO */
|
||||
#define NS_STYLE_SHAPE_RENDERING_OPTIMIZESPEED 1 /* == nsISVGPathGeometrySource::SHAPE_RENDERING_OPTIMIZESPEED */
|
||||
#define NS_STYLE_SHAPE_RENDERING_CRISPEDGES 2 /* == nsISVGPathGeometrySource::SHAPE_RENDERING_CRISPEDGES */
|
||||
#define NS_STYLE_SHAPE_RENDERING_GEOMETRICPRECISION 3 /* == nsISVGPathGeometrySource::SHAPE_RENDERING_GEOMETRICPRECISION */
|
||||
|
||||
#define NS_STYLE_SHAPE_RENDERING_AUTO 0
|
||||
#define NS_STYLE_SHAPE_RENDERING_OPTIMIZESPEED 1
|
||||
#define NS_STYLE_SHAPE_RENDERING_CRISPEDGES 2
|
||||
#define NS_STYLE_SHAPE_RENDERING_GEOMETRICPRECISION 3
|
||||
|
||||
// stroke-linecap
|
||||
#define NS_STYLE_STROKE_LINECAP_BUTT 0 /* == nsISVGGeometrySource::STROKE_LINECAP_BUTT */
|
||||
#define NS_STYLE_STROKE_LINECAP_ROUND 1 /* == nsISVGGeometrySource::STROKE_LINECAP_ROUND */
|
||||
#define NS_STYLE_STROKE_LINECAP_SQUARE 2 /* == nsISVGGeometrySource::STROKE_LINECAP_SQUARE */
|
||||
#define NS_STYLE_STROKE_LINECAP_BUTT 0
|
||||
#define NS_STYLE_STROKE_LINECAP_ROUND 1
|
||||
#define NS_STYLE_STROKE_LINECAP_SQUARE 2
|
||||
|
||||
// stroke-linejoin
|
||||
#define NS_STYLE_STROKE_LINEJOIN_MITER 0 /* == nsISVGGeometrySource::STROKE_LINEJOIN_MITER */
|
||||
#define NS_STYLE_STROKE_LINEJOIN_ROUND 1 /* == nsISVGGeometrySource::STROKE_LINEJOIN_ROUND */
|
||||
#define NS_STYLE_STROKE_LINEJOIN_BEVEL 2 /* == nsISVGGeometrySource::STROKE_LINEJOIN_BEVEL */
|
||||
#define NS_STYLE_STROKE_LINEJOIN_MITER 0
|
||||
#define NS_STYLE_STROKE_LINEJOIN_ROUND 1
|
||||
#define NS_STYLE_STROKE_LINEJOIN_BEVEL 2
|
||||
|
||||
// text-anchor
|
||||
#define NS_STYLE_TEXT_ANCHOR_START 0
|
||||
|
@ -695,10 +690,15 @@
|
|||
#define NS_STYLE_TEXT_ANCHOR_END 2
|
||||
|
||||
// text-rendering
|
||||
#define NS_STYLE_TEXT_RENDERING_AUTO 0 /* == nsISVGGlyphGeometrySource::TEXT_RENDERING_AUTO */
|
||||
#define NS_STYLE_TEXT_RENDERING_OPTIMIZESPEED 1 /* == nsISVGG.G.S.::TEXT_RENDERING_OPTIMIZESPEED */
|
||||
#define NS_STYLE_TEXT_RENDERING_OPTIMIZELEGIBILITY 2 /* == nsISVGG.G.S.::TEXT_RENDERING_OPTIMIZELEGIBILITY */
|
||||
#define NS_STYLE_TEXT_RENDERING_GEOMETRICPRECISION 3 /* == nsISVGG.G.S.::TEXT_RENDERING_GEOMETRICPRECISION */
|
||||
#define NS_STYLE_TEXT_RENDERING_AUTO 0
|
||||
#define NS_STYLE_TEXT_RENDERING_OPTIMIZESPEED 1
|
||||
#define NS_STYLE_TEXT_RENDERING_OPTIMIZELEGIBILITY 2
|
||||
#define NS_STYLE_TEXT_RENDERING_GEOMETRICPRECISION 3
|
||||
|
||||
// color-interpolation and color-interpolation-filters
|
||||
#define NS_STYLE_COLOR_INTERPOLATION_AUTO 0
|
||||
#define NS_STYLE_COLOR_INTERPOLATION_SRGB 1
|
||||
#define NS_STYLE_COLOR_INTERPOLATION_LINEARRGB 2
|
||||
|
||||
#endif // MOZ_SVG
|
||||
|
||||
|
|
|
@ -549,6 +549,7 @@ CSS_KEY(fill, fill)
|
|||
CSS_KEY(geometricprecision, geometricprecision)
|
||||
CSS_KEY(hanging, hanging)
|
||||
CSS_KEY(ideographic, ideographic)
|
||||
CSS_KEY(linearrgb, linearrgb)
|
||||
CSS_KEY(mathematical, mathematical)
|
||||
//CSS_KEY(middle, middle)
|
||||
CSS_KEY(miter, miter)
|
||||
|
@ -562,6 +563,7 @@ CSS_KEY(reset-size, reset_size)
|
|||
CSS_KEY(round, round)
|
||||
//CSS_KEY(square, square)
|
||||
//CSS_KEY(start, start)
|
||||
CSS_KEY(srgb, srgb)
|
||||
CSS_KEY(stroke, stroke)
|
||||
CSS_KEY(text-after-edge, text_after_edge)
|
||||
CSS_KEY(text-before-edge, text_before_edge)
|
||||
|
|
|
@ -4525,6 +4525,10 @@ PRBool CSSParserImpl::ParseSingleValueProperty(nsresult& aErrorCode,
|
|||
case eCSSProperty_clip_rule:
|
||||
return ParseVariant(aErrorCode, aValue, VARIANT_HK,
|
||||
nsCSSProps::kFillRuleKTable);
|
||||
case eCSSProperty_color_interpolation:
|
||||
case eCSSProperty_color_interpolation_filters:
|
||||
return ParseVariant(aErrorCode, aValue, VARIANT_AHK,
|
||||
nsCSSProps::kColorInterpolationKTable);
|
||||
case eCSSProperty_dominant_baseline:
|
||||
return ParseVariant(aErrorCode, aValue, VARIANT_AHK,
|
||||
nsCSSProps::kDominantBaselineKTable);
|
||||
|
|
|
@ -471,6 +471,8 @@ CSS_PROP_XUL(-moz-box-ordinal-group, box_ordinal_group, MozBoxOrdinalGroup, XUL,
|
|||
#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
|
||||
CSS_PROP_SVGRESET(clip-path, clip_path, ClipPath, SVG, mClipPath, eCSSType_Value, nsnull)
|
||||
CSS_PROP_SVG(clip-rule, clip_rule, ClipRule, SVG, mClipRule, eCSSType_Value, kFillRuleKTable)
|
||||
CSS_PROP_SVG(color-interpolation, color_interpolation, ColorInterpolation, SVG, mColorInterpolation, eCSSType_Value, kColorInterpolationKTable)
|
||||
CSS_PROP_SVG(color-interpolation-filters, color_interpolation_filters, ColorInterpolationFilters, SVG, mColorInterpolationFilters, eCSSType_Value, kColorInterpolationKTable)
|
||||
CSS_PROP_SVGRESET(dominant-baseline, dominant_baseline, DominantBaseline, SVG, mDominantBaseline, eCSSType_Value, kDominantBaselineKTable)
|
||||
CSS_PROP_SVG(fill, fill, Fill, SVG, mFill, eCSSType_ValuePair, nsnull)
|
||||
CSS_PROP_SVG(fill-opacity, fill_opacity, FillOpacity, SVG, mFillOpacity, eCSSType_Value, nsnull)
|
||||
|
|
|
@ -1048,6 +1048,12 @@ const PRInt32 nsCSSProps::kTextRenderingKTable[] = {
|
|||
eCSSKeyword_UNKNOWN, -1
|
||||
};
|
||||
|
||||
const PRInt32 nsCSSProps::kColorInterpolationKTable[] = {
|
||||
eCSSKeyword_srgb, NS_STYLE_COLOR_INTERPOLATION_SRGB,
|
||||
eCSSKeyword_linearrgb, NS_STYLE_COLOR_INTERPOLATION_LINEARRGB,
|
||||
eCSSKeyword_UNKNOWN, -1
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
PRBool
|
||||
|
|
|
@ -138,6 +138,7 @@ public:
|
|||
static const PRInt32 kStrokeLinejoinKTable[];
|
||||
static const PRInt32 kTextAnchorKTable[];
|
||||
static const PRInt32 kTextRenderingKTable[];
|
||||
static const PRInt32 kColorInterpolationKTable[];
|
||||
#endif
|
||||
static const PRInt32 kBoxPropSourceKTable[];
|
||||
static const PRInt32 kBoxSizingKTable[];
|
||||
|
|
|
@ -496,6 +496,8 @@ struct nsCSSSVG : public nsCSSStruct {
|
|||
|
||||
nsCSSValue mClipPath;
|
||||
nsCSSValue mClipRule;
|
||||
nsCSSValue mColorInterpolation;
|
||||
nsCSSValue mColorInterpolationFilters;
|
||||
nsCSSValue mDominantBaseline;
|
||||
nsCSSValuePair mFill;
|
||||
nsCSSValue mFillOpacity;
|
||||
|
|
|
@ -4069,6 +4069,36 @@ nsRuleNode::ComputeSVGData(nsStyleStruct* aStartStruct,
|
|||
svg->mClipRule = parentSVG->mClipRule;
|
||||
}
|
||||
|
||||
// color-interpolation: auto, sRGB, linearRGB, inherit
|
||||
if (eCSSUnit_Enumerated == SVGData.mColorInterpolation.GetUnit()) {
|
||||
svg->mColorInterpolation = SVGData.mColorInterpolation.GetIntValue();
|
||||
}
|
||||
else if (eCSSUnit_Auto == SVGData.mColorInterpolation.GetUnit()) {
|
||||
svg->mColorInterpolation = NS_STYLE_COLOR_INTERPOLATION_AUTO;
|
||||
}
|
||||
else if (eCSSUnit_Inherit == SVGData.mColorInterpolation.GetUnit()) {
|
||||
inherited = PR_TRUE;
|
||||
svg->mColorInterpolation = parentSVG->mColorInterpolation;
|
||||
}
|
||||
else if (eCSSUnit_Initial == SVGData.mColorInterpolation.GetUnit()) {
|
||||
svg->mColorInterpolation = NS_STYLE_COLOR_INTERPOLATION_SRGB;
|
||||
}
|
||||
|
||||
// color-interpolation-filters: auto, sRGB, linearRGB, inherit
|
||||
if (eCSSUnit_Enumerated == SVGData.mColorInterpolationFilters.GetUnit()) {
|
||||
svg->mColorInterpolationFilters = SVGData.mColorInterpolationFilters.GetIntValue();
|
||||
}
|
||||
else if (eCSSUnit_Auto == SVGData.mColorInterpolationFilters.GetUnit()) {
|
||||
svg->mColorInterpolationFilters = NS_STYLE_COLOR_INTERPOLATION_AUTO;
|
||||
}
|
||||
else if (eCSSUnit_Inherit == SVGData.mColorInterpolationFilters.GetUnit()) {
|
||||
inherited = PR_TRUE;
|
||||
svg->mColorInterpolationFilters = parentSVG->mColorInterpolationFilters;
|
||||
}
|
||||
else if (eCSSUnit_Initial == SVGData.mColorInterpolation.GetUnit()) {
|
||||
svg->mColorInterpolation = NS_STYLE_COLOR_INTERPOLATION_LINEARRGB;
|
||||
}
|
||||
|
||||
// fill:
|
||||
SetSVGPaint(SVGData.mFill, parentSVG->mFill, mPresContext, aContext, svg->mFill, inherited);
|
||||
|
||||
|
|
|
@ -884,10 +884,12 @@ void nsStyleContext::DumpRegressionData(nsPresContext* aPresContext, FILE* out,
|
|||
svg->mStrokeMiterlimit,
|
||||
svg->mStrokeOpacity);
|
||||
svg->mStrokeWidth.ToString(str);
|
||||
fprintf(out, "%s %d %d %d %d %d %d %d %d %d\" />\n",
|
||||
fprintf(out, "%s %d %d %d %d %d %d %d %d %d %d %d\" />\n",
|
||||
NS_ConvertUTF16toUTF8(str).get(),
|
||||
(int)svg->mStrokeDasharrayLength,
|
||||
(int)svg->mClipRule,
|
||||
(int)svg->mColorInterpolation,
|
||||
(int)svg->mColorInterpolationFilters,
|
||||
(int)svg->mFillRule,
|
||||
(int)svg->mPointerEvents,
|
||||
(int)svg->mShapeRendering,
|
||||
|
|
|
@ -652,6 +652,8 @@ nsStyleSVG::nsStyleSVG()
|
|||
|
||||
mStrokeDasharrayLength = 0;
|
||||
mClipRule = NS_STYLE_FILL_RULE_NONZERO;
|
||||
mColorInterpolation = NS_STYLE_COLOR_INTERPOLATION_SRGB;
|
||||
mColorInterpolationFilters = NS_STYLE_COLOR_INTERPOLATION_LINEARRGB;
|
||||
mFillRule = NS_STYLE_FILL_RULE_NONZERO;
|
||||
mPointerEvents = NS_STYLE_POINTER_EVENTS_VISIBLEPAINTED;
|
||||
mShapeRendering = NS_STYLE_SHAPE_RENDERING_AUTO;
|
||||
|
@ -698,6 +700,8 @@ nsStyleSVG::nsStyleSVG(const nsStyleSVG& aSource)
|
|||
mStrokeOpacity = aSource.mStrokeOpacity;
|
||||
|
||||
mClipRule = aSource.mClipRule;
|
||||
mColorInterpolation = aSource.mColorInterpolation;
|
||||
mColorInterpolationFilters = aSource.mColorInterpolationFilters;
|
||||
mFillRule = aSource.mFillRule;
|
||||
mPointerEvents = aSource.mPointerEvents;
|
||||
mShapeRendering = aSource.mShapeRendering;
|
||||
|
@ -724,6 +728,8 @@ nsChangeHint nsStyleSVG::CalcDifference(const nsStyleSVG& aOther) const
|
|||
mStrokeOpacity != aOther.mStrokeOpacity ||
|
||||
|
||||
mClipRule != aOther.mClipRule ||
|
||||
mColorInterpolation != aOther.mColorInterpolation ||
|
||||
mColorInterpolationFilters != aOther.mColorInterpolationFilters ||
|
||||
mFillRule != aOther.mFillRule ||
|
||||
mPointerEvents != aOther.mPointerEvents ||
|
||||
mShapeRendering != aOther.mShapeRendering ||
|
||||
|
|
|
@ -1285,6 +1285,8 @@ struct nsStyleSVG : public nsStyleStruct {
|
|||
|
||||
PRUint32 mStrokeDasharrayLength;
|
||||
PRUint8 mClipRule; // [inherited]
|
||||
PRUint8 mColorInterpolation; // [inherited] see nsStyleConsts.h
|
||||
PRUint8 mColorInterpolationFilters; // [inherited] see nsStyleConsts.h
|
||||
PRUint8 mFillRule; // [inherited] see nsStyleConsts.h
|
||||
PRUint8 mPointerEvents; // [inherited] see nsStyleConsts.h
|
||||
PRUint8 mShapeRendering; // [inherited] see nsStyleConsts.h
|
||||
|
|
|
@ -379,6 +379,9 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext,
|
|||
x, y, width, height,
|
||||
filterResX, filterResY,
|
||||
type);
|
||||
nsSVGFilterInstance::ColorModel
|
||||
colorModel(nsSVGFilterInstance::ColorModel::SRGB,
|
||||
nsSVGFilterInstance::ColorModel::PREMULTIPLIED);
|
||||
|
||||
if (requirements & NS_FE_SOURCEALPHA) {
|
||||
cairo_surface_t *alpha =
|
||||
|
@ -403,14 +406,14 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext,
|
|||
}
|
||||
|
||||
instance.DefineImage(NS_LITERAL_STRING("SourceAlpha"), alpha,
|
||||
nsRect(0, 0, filterResX, filterResY));
|
||||
nsRect(0, 0, filterResX, filterResY), colorModel);
|
||||
}
|
||||
|
||||
// this always needs to be defined last because the default image
|
||||
// for the first filter element is supposed to be SourceGraphic
|
||||
instance.DefineImage(NS_LITERAL_STRING("SourceGraphic"),
|
||||
tmpSurface->CairoSurface(),
|
||||
nsRect(0, 0, filterResX, filterResY));
|
||||
nsRect(0, 0, filterResX, filterResY), colorModel);
|
||||
|
||||
for (PRUint32 k=0; k<count; ++k) {
|
||||
nsIContent* child = mContent->GetChildAt(k);
|
||||
|
@ -426,7 +429,8 @@ nsSVGFilterFrame::FilterPaint(nsSVGRenderState *aContext,
|
|||
nsRect filterRect;
|
||||
nsRefPtr<gfxASurface> resultSurface;
|
||||
|
||||
instance.LookupImage(NS_LITERAL_STRING(""), &filterResult, &filterRect);
|
||||
instance.LookupImage(NS_LITERAL_STRING(""),
|
||||
&filterResult, &filterRect, colorModel);
|
||||
|
||||
if (filterResult)
|
||||
resultSurface = gfxASurface::Wrap(filterResult);
|
||||
|
@ -648,7 +652,8 @@ nsSVGFilterInstance::GetImage()
|
|||
void
|
||||
nsSVGFilterInstance::LookupImage(const nsAString &aName,
|
||||
cairo_surface_t **aImage,
|
||||
nsRect *aRegion)
|
||||
nsRect *aRegion,
|
||||
const ColorModel &aRequiredColorModel)
|
||||
{
|
||||
ImageEntry *entry;
|
||||
|
||||
|
@ -660,6 +665,29 @@ nsSVGFilterInstance::LookupImage(const nsAString &aName,
|
|||
if (entry) {
|
||||
*aImage = entry->mImage;
|
||||
*aRegion = entry->mRegion;
|
||||
|
||||
if (aRequiredColorModel == entry->mColorModel)
|
||||
return;
|
||||
|
||||
// convert image to desired format
|
||||
PRUint8 *data = cairo_image_surface_get_data(entry->mImage);
|
||||
PRInt32 stride = cairo_image_surface_get_stride(entry->mImage);
|
||||
|
||||
if (entry->mColorModel.mAlphaChannel == ColorModel::PREMULTIPLIED)
|
||||
nsSVGUtils::UnPremultiplyImageDataAlpha(data, stride, entry->mRegion);
|
||||
|
||||
if (aRequiredColorModel.mColorSpace != entry->mColorModel.mColorSpace) {
|
||||
|
||||
if (aRequiredColorModel.mColorSpace == ColorModel::LINEAR_RGB)
|
||||
nsSVGUtils::ConvertImageDataToLinearRGB(data, stride, entry->mRegion);
|
||||
else
|
||||
nsSVGUtils::ConvertImageDataFromLinearRGB(data, stride, entry->mRegion);
|
||||
}
|
||||
if (aRequiredColorModel.mAlphaChannel == ColorModel::PREMULTIPLIED)
|
||||
nsSVGUtils::PremultiplyImageDataAlpha(data, stride, entry->mRegion);
|
||||
|
||||
entry->mColorModel = aRequiredColorModel;
|
||||
|
||||
} else {
|
||||
*aImage = nsnull;
|
||||
aRegion->Empty();
|
||||
|
@ -669,9 +697,10 @@ nsSVGFilterInstance::LookupImage(const nsAString &aName,
|
|||
void
|
||||
nsSVGFilterInstance::DefineImage(const nsAString &aName,
|
||||
cairo_surface_t *aImage,
|
||||
nsRect aRegion)
|
||||
const nsRect &aRegion,
|
||||
const ColorModel &aColorModel)
|
||||
{
|
||||
ImageEntry *entry = new ImageEntry(aImage, aRegion);
|
||||
ImageEntry *entry = new ImageEntry(aImage, aRegion, aColorModel);
|
||||
|
||||
if (entry)
|
||||
mImageDictionary.Put(aName, entry);
|
||||
|
|
|
@ -55,6 +55,21 @@ class nsSVGElement;
|
|||
class nsSVGFilterInstance
|
||||
{
|
||||
public:
|
||||
class ColorModel {
|
||||
public:
|
||||
enum ColorSpace { SRGB, LINEAR_RGB };
|
||||
enum AlphaChannel { UNPREMULTIPLIED, PREMULTIPLIED };
|
||||
|
||||
ColorModel(ColorSpace aColorSpace, AlphaChannel aAlphaChannel) :
|
||||
mColorSpace(aColorSpace), mAlphaChannel(aAlphaChannel) {}
|
||||
PRBool operator==(const ColorModel& aOther) const {
|
||||
return mColorSpace == aOther.mColorSpace &&
|
||||
mAlphaChannel == aOther.mAlphaChannel;
|
||||
}
|
||||
ColorSpace mColorSpace;
|
||||
PRPackedBool mAlphaChannel;
|
||||
};
|
||||
|
||||
float GetPrimitiveLength(nsSVGLength2 *aLength);
|
||||
|
||||
void GetFilterSubregion(nsIContent *aFilter,
|
||||
|
@ -63,9 +78,13 @@ public:
|
|||
|
||||
cairo_surface_t *GetImage();
|
||||
void LookupImage(const nsAString &aName,
|
||||
cairo_surface_t **aImage, nsRect *aRegion);
|
||||
cairo_surface_t **aImage,
|
||||
nsRect *aRegion,
|
||||
const ColorModel &aColorModel);
|
||||
void DefineImage(const nsAString &aName,
|
||||
cairo_surface_t *aImage, nsRect aRegion);
|
||||
cairo_surface_t *aImage,
|
||||
const nsRect &aRegion,
|
||||
const ColorModel &aColorModel);
|
||||
void GetFilterBox(float *x, float *y, float *width, float *height) {
|
||||
*x = mFilterX;
|
||||
*y = mFilterY;
|
||||
|
@ -92,12 +111,19 @@ public:
|
|||
private:
|
||||
class ImageEntry {
|
||||
public:
|
||||
ImageEntry(cairo_surface_t *aImage, nsRect aRegion) :
|
||||
mImage(aImage), mRegion(aRegion) { cairo_surface_reference(aImage); }
|
||||
~ImageEntry() { cairo_surface_destroy(mImage); }
|
||||
ImageEntry(cairo_surface_t *aImage,
|
||||
const nsRect &aRegion,
|
||||
const ColorModel &aColorModel) :
|
||||
mImage(aImage), mRegion(aRegion), mColorModel(aColorModel) {
|
||||
cairo_surface_reference(aImage);
|
||||
}
|
||||
~ImageEntry() {
|
||||
cairo_surface_destroy(mImage);
|
||||
}
|
||||
|
||||
cairo_surface_t *mImage;
|
||||
nsRect mRegion;
|
||||
ColorModel mColorModel;
|
||||
};
|
||||
|
||||
nsClassHashtable<nsStringHashKey,ImageEntry> mImageDictionary;
|
||||
|
|
|
@ -98,42 +98,6 @@ nsSVGMaskFrame::InitSVG()
|
|||
}
|
||||
|
||||
|
||||
/* sRGB -> linearRGB mapping table */
|
||||
static unsigned char rgb2lin[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 2,
|
||||
2, 2, 2, 2, 2, 3, 3, 3,
|
||||
3, 3, 4, 4, 4, 4, 4, 5,
|
||||
5, 5, 5, 6, 6, 6, 6, 7,
|
||||
7, 7, 8, 8, 8, 9, 9, 9,
|
||||
10, 10, 10, 11, 11, 11, 12, 12,
|
||||
13, 13, 13, 14, 14, 15, 15, 16,
|
||||
16, 16, 17, 17, 18, 18, 19, 19,
|
||||
20, 20, 21, 22, 22, 23, 23, 24,
|
||||
24, 25, 26, 26, 27, 27, 28, 29,
|
||||
29, 30, 31, 31, 32, 33, 33, 34,
|
||||
35, 36, 36, 37, 38, 38, 39, 40,
|
||||
41, 42, 42, 43, 44, 45, 46, 47,
|
||||
47, 48, 49, 50, 51, 52, 53, 54,
|
||||
55, 55, 56, 57, 58, 59, 60, 61,
|
||||
62, 63, 64, 65, 66, 67, 68, 70,
|
||||
71, 72, 73, 74, 75, 76, 77, 78,
|
||||
80, 81, 82, 83, 84, 85, 87, 88,
|
||||
89, 90, 92, 93, 94, 95, 97, 98,
|
||||
99, 101, 102, 103, 105, 106, 107, 109,
|
||||
110, 112, 113, 114, 116, 117, 119, 120,
|
||||
122, 123, 125, 126, 128, 129, 131, 132,
|
||||
134, 135, 137, 139, 140, 142, 144, 145,
|
||||
147, 148, 150, 152, 153, 155, 157, 159,
|
||||
160, 162, 164, 166, 167, 169, 171, 173,
|
||||
175, 176, 178, 180, 182, 184, 186, 188,
|
||||
190, 192, 193, 195, 197, 199, 201, 203,
|
||||
205, 207, 209, 211, 213, 215, 218, 220,
|
||||
222, 224, 226, 228, 230, 232, 235, 237,
|
||||
239, 241, 243, 245, 248, 250, 252, 255
|
||||
};
|
||||
|
||||
cairo_pattern_t *
|
||||
nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRenderState *aContext,
|
||||
nsISVGChildFrame* aParent,
|
||||
|
@ -250,37 +214,27 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRenderState *aContext,
|
|||
cairo_destroy(transferCtx);
|
||||
cairo_pattern_destroy(pattern);
|
||||
|
||||
/* Now convert to intensity (sRGB -> linearRGB -> intensity) and
|
||||
store in alpha channel. Reuse the transfer image instead of
|
||||
allocating another CAIRO_FORMAT_A8 image. */
|
||||
|
||||
PRUint32 width = cairo_image_surface_get_width(image);
|
||||
PRUint32 height = cairo_image_surface_get_height(image);
|
||||
PRUint8 *data = cairo_image_surface_get_data(image);
|
||||
PRInt32 stride = cairo_image_surface_get_stride(image);
|
||||
|
||||
nsRect rect(0, 0, width, height);
|
||||
nsSVGUtils::UnPremultiplyImageDataAlpha(data, stride, rect);
|
||||
nsSVGUtils::ConvertImageDataToLinearRGB(data, stride, rect);
|
||||
|
||||
for (PRUint32 y = 0; y < height; y++)
|
||||
for (PRUint32 x = 0; x < width; x++) {
|
||||
PRUint32 a;
|
||||
float r, g, b, intensity;
|
||||
|
||||
/* un-premultiply and sRGB -> linearRGB conversion */
|
||||
a = data[stride * y + 4 * x + 3];
|
||||
if (a) {
|
||||
b = rgb2lin[(255 * (PRUint32)data[stride * y + 4 * x]) / a] / 255.0;
|
||||
g = rgb2lin[(255 * (PRUint32)data[stride * y + 4 * x + 1]) / a] / 255.0;
|
||||
r = rgb2lin[(255 * (PRUint32)data[stride * y + 4 * x + 2]) / a] / 255.0;
|
||||
} else {
|
||||
b = g = r = 0.0f;
|
||||
}
|
||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||
|
||||
/* linearRGB -> intensity */
|
||||
intensity = (r * 0.2125 + g * 0.7154 + b * 0.0721) * (a / 255.0) * aOpacity;
|
||||
|
||||
data[stride * y + 4 * x] = 255;
|
||||
data[stride * y + 4 * x + 1] = 255;
|
||||
data[stride * y + 4 * x + 2] = 255;
|
||||
data[stride * y + 4 * x + 3] = (unsigned char)(intensity * 255);
|
||||
pixel[3] = (PRUint8)((pixel[2] * 0.2125 +
|
||||
pixel[1] * 0.7154 +
|
||||
pixel[0] * 0.0721) *
|
||||
(pixel[3] / 255.0) * aOpacity);
|
||||
pixel[0] = 255;
|
||||
pixel[1] = 255;
|
||||
pixel[2] = 255;
|
||||
}
|
||||
|
||||
cairo_pattern_t *retval = cairo_pattern_create_for_surface(image);
|
||||
|
|
|
@ -88,6 +88,80 @@ struct nsSVGFilterProperty {
|
|||
cairo_surface_t *nsSVGUtils::mCairoComputationalSurface = nsnull;
|
||||
gfxASurface *nsSVGUtils::mThebesComputationalSurface = nsnull;
|
||||
|
||||
// c = n / 255
|
||||
// (c <= 0.0031308 ? c * 12.92 : 1.055 * pow(c, 1 / 2.4) - 0.055) * 255 + 0.5
|
||||
static const PRUint8 glinearRGBTosRGBMap[256] = {
|
||||
0, 13, 22, 28, 34, 38, 42, 46,
|
||||
50, 53, 56, 59, 61, 64, 66, 69,
|
||||
71, 73, 75, 77, 79, 81, 83, 85,
|
||||
86, 88, 90, 92, 93, 95, 96, 98,
|
||||
99, 101, 102, 104, 105, 106, 108, 109,
|
||||
110, 112, 113, 114, 115, 117, 118, 119,
|
||||
120, 121, 122, 124, 125, 126, 127, 128,
|
||||
129, 130, 131, 132, 133, 134, 135, 136,
|
||||
137, 138, 139, 140, 141, 142, 143, 144,
|
||||
145, 146, 147, 148, 148, 149, 150, 151,
|
||||
152, 153, 154, 155, 155, 156, 157, 158,
|
||||
159, 159, 160, 161, 162, 163, 163, 164,
|
||||
165, 166, 167, 167, 168, 169, 170, 170,
|
||||
171, 172, 173, 173, 174, 175, 175, 176,
|
||||
177, 178, 178, 179, 180, 180, 181, 182,
|
||||
182, 183, 184, 185, 185, 186, 187, 187,
|
||||
188, 189, 189, 190, 190, 191, 192, 192,
|
||||
193, 194, 194, 195, 196, 196, 197, 197,
|
||||
198, 199, 199, 200, 200, 201, 202, 202,
|
||||
203, 203, 204, 205, 205, 206, 206, 207,
|
||||
208, 208, 209, 209, 210, 210, 211, 212,
|
||||
212, 213, 213, 214, 214, 215, 215, 216,
|
||||
216, 217, 218, 218, 219, 219, 220, 220,
|
||||
221, 221, 222, 222, 223, 223, 224, 224,
|
||||
225, 226, 226, 227, 227, 228, 228, 229,
|
||||
229, 230, 230, 231, 231, 232, 232, 233,
|
||||
233, 234, 234, 235, 235, 236, 236, 237,
|
||||
237, 238, 238, 238, 239, 239, 240, 240,
|
||||
241, 241, 242, 242, 243, 243, 244, 244,
|
||||
245, 245, 246, 246, 246, 247, 247, 248,
|
||||
248, 249, 249, 250, 250, 251, 251, 251,
|
||||
252, 252, 253, 253, 254, 254, 255, 255
|
||||
};
|
||||
|
||||
// c = n / 255
|
||||
// c <= 0.04045 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4)) * 255 + 0.5
|
||||
static const PRUint8 gsRGBToLinearRGBMap[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 5, 5, 5,
|
||||
5, 6, 6, 6, 6, 7, 7, 7,
|
||||
8, 8, 8, 8, 9, 9, 9, 10,
|
||||
10, 10, 11, 11, 12, 12, 12, 13,
|
||||
13, 13, 14, 14, 15, 15, 16, 16,
|
||||
17, 17, 17, 18, 18, 19, 19, 20,
|
||||
20, 21, 22, 22, 23, 23, 24, 24,
|
||||
25, 25, 26, 27, 27, 28, 29, 29,
|
||||
30, 30, 31, 32, 32, 33, 34, 35,
|
||||
35, 36, 37, 37, 38, 39, 40, 41,
|
||||
41, 42, 43, 44, 45, 45, 46, 47,
|
||||
48, 49, 50, 51, 51, 52, 53, 54,
|
||||
55, 56, 57, 58, 59, 60, 61, 62,
|
||||
63, 64, 65, 66, 67, 68, 69, 70,
|
||||
71, 72, 73, 74, 76, 77, 78, 79,
|
||||
80, 81, 82, 84, 85, 86, 87, 88,
|
||||
90, 91, 92, 93, 95, 96, 97, 99,
|
||||
100, 101, 103, 104, 105, 107, 108, 109,
|
||||
111, 112, 114, 115, 116, 118, 119, 121,
|
||||
122, 124, 125, 127, 128, 130, 131, 133,
|
||||
134, 136, 138, 139, 141, 142, 144, 146,
|
||||
147, 149, 151, 152, 154, 156, 157, 159,
|
||||
161, 163, 164, 166, 168, 170, 171, 173,
|
||||
175, 177, 179, 181, 183, 184, 186, 188,
|
||||
190, 192, 194, 196, 198, 200, 202, 204,
|
||||
206, 208, 210, 212, 214, 216, 218, 220,
|
||||
222, 224, 226, 229, 231, 233, 235, 237,
|
||||
239, 242, 244, 246, 248, 250, 253, 255
|
||||
};
|
||||
|
||||
static PRBool gSVGEnabled;
|
||||
static const char SVG_PREF_STR[] = "svg.enabled";
|
||||
|
||||
|
@ -123,6 +197,84 @@ NS_SVGEnabled()
|
|||
return gSVGEnabled;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGUtils::UnPremultiplyImageDataAlpha(PRUint8 *data,
|
||||
PRInt32 stride,
|
||||
const nsRect &rect)
|
||||
{
|
||||
for (PRInt32 y = rect.y; y < rect.YMost(); y++) {
|
||||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||
|
||||
PRUint8 a = pixel[3];
|
||||
if (a == 255)
|
||||
continue;
|
||||
|
||||
if (a) {
|
||||
pixel[0] = (255 * pixel[0]) / a;
|
||||
pixel[1] = (255 * pixel[1]) / a;
|
||||
pixel[2] = (255 * pixel[2]) / a;
|
||||
} else {
|
||||
pixel[0] = 0;
|
||||
pixel[1] = 0;
|
||||
pixel[2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGUtils::PremultiplyImageDataAlpha(PRUint8 *data,
|
||||
PRInt32 stride,
|
||||
const nsRect &rect)
|
||||
{
|
||||
for (PRInt32 y = rect.y; y < rect.YMost(); y++) {
|
||||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||
|
||||
PRUint8 a = pixel[3];
|
||||
if (a == 255)
|
||||
continue;
|
||||
|
||||
FAST_DIVIDE_BY_255(pixel[0], pixel[0] * a);
|
||||
FAST_DIVIDE_BY_255(pixel[1], pixel[1] * a);
|
||||
FAST_DIVIDE_BY_255(pixel[2], pixel[2] * a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGUtils::ConvertImageDataToLinearRGB(PRUint8 *data,
|
||||
PRInt32 stride,
|
||||
const nsRect &rect)
|
||||
{
|
||||
for (PRInt32 y = rect.y; y < rect.YMost(); y++) {
|
||||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||
|
||||
pixel[0] = gsRGBToLinearRGBMap[pixel[0]];
|
||||
pixel[1] = gsRGBToLinearRGBMap[pixel[1]];
|
||||
pixel[2] = gsRGBToLinearRGBMap[pixel[2]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGUtils::ConvertImageDataFromLinearRGB(PRUint8 *data,
|
||||
PRInt32 stride,
|
||||
const nsRect &rect)
|
||||
{
|
||||
for (PRInt32 y = rect.y; y < rect.YMost(); y++) {
|
||||
for (PRInt32 x = rect.x; x < rect.XMost(); x++) {
|
||||
PRUint8 *pixel = data + stride * y + 4 * x;
|
||||
|
||||
pixel[0] = glinearRGBTosRGBMap[pixel[0]];
|
||||
pixel[1] = glinearRGBTosRGBMap[pixel[1]];
|
||||
pixel[2] = glinearRGBTosRGBMap[pixel[2]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGUtils::ReportToConsole(nsIDocument* doc,
|
||||
const char* aWarning,
|
||||
|
|
|
@ -142,6 +142,31 @@ private:
|
|||
class nsSVGUtils
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* Converts image data from premultipled to unpremultiplied alpha
|
||||
*/
|
||||
static void UnPremultiplyImageDataAlpha(PRUint8 *data,
|
||||
PRInt32 stride,
|
||||
const nsRect &rect);
|
||||
/*
|
||||
* Converts image data from unpremultipled to premultiplied alpha
|
||||
*/
|
||||
static void PremultiplyImageDataAlpha(PRUint8 *data,
|
||||
PRInt32 stride,
|
||||
const nsRect &rect);
|
||||
/*
|
||||
* Converts image data from premultiplied sRGB to Linear RGB
|
||||
*/
|
||||
static void ConvertImageDataToLinearRGB(PRUint8 *data,
|
||||
PRInt32 stride,
|
||||
const nsRect &rect);
|
||||
/*
|
||||
* Converts image data from LinearRGB to premultiplied sRGB
|
||||
*/
|
||||
static void ConvertImageDataFromLinearRGB(PRUint8 *data,
|
||||
PRInt32 stride,
|
||||
const nsRect &rect);
|
||||
|
||||
/*
|
||||
* Report a localized error message to the error console.
|
||||
*/
|
||||
|
|
Загрузка…
Ссылка в новой задаче