/* -*- 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 Mozilla SVG Project code. * * The Initial Developer of the Original Code is * Jonathan Watt. * Portions created by the Initial Developer are Copyright (C) 2004 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Jonathan Watt <jonathan.watt@strath.ac.uk> (original author) * * Alternatively, the contents of this file may be used under the terms of * either of 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 MPL, 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 "nsSVGPreserveAspectRatio.h" #include "nsSVGValue.h" #include "nsCRT.h" #include "nsContentUtils.h" //////////////////////////////////////////////////////////////////////// // nsSVGPreserveAspectRatio class class nsSVGPreserveAspectRatio : public nsIDOMSVGPreserveAspectRatio, public nsSVGValue { protected: friend nsresult NS_NewSVGPreserveAspectRatio( nsIDOMSVGPreserveAspectRatio** result, PRUint16 aAlign, PRUint16 aMeetOrSlice); nsSVGPreserveAspectRatio(PRUint16 aAlign, PRUint16 aMeetOrSlice); ~nsSVGPreserveAspectRatio(); public: // nsISupports interface: NS_DECL_ISUPPORTS // nsIDOMSVGPreserveAspectRatio interface: NS_DECL_NSIDOMSVGPRESERVEASPECTRATIO // nsISVGValue interface: NS_IMETHOD SetValueString(const nsAString& aValue); NS_IMETHOD GetValueString(nsAString& aValue); protected: PRUint16 mAlign, mMeetOrSlice; }; //---------------------------------------------------------------------- // implementation: nsSVGPreserveAspectRatio::nsSVGPreserveAspectRatio(PRUint16 aAlign, PRUint16 aMeetOrSlice) : mAlign(aAlign), mMeetOrSlice(aMeetOrSlice) { } nsSVGPreserveAspectRatio::~nsSVGPreserveAspectRatio() { } //---------------------------------------------------------------------- // nsISupports methods: NS_IMPL_ADDREF(nsSVGPreserveAspectRatio) NS_IMPL_RELEASE(nsSVGPreserveAspectRatio) NS_INTERFACE_MAP_BEGIN(nsSVGPreserveAspectRatio) NS_INTERFACE_MAP_ENTRY(nsISVGValue) NS_INTERFACE_MAP_ENTRY(nsIDOMSVGPreserveAspectRatio) NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGPreserveAspectRatio) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue) NS_INTERFACE_MAP_END //---------------------------------------------------------------------- // nsISVGValue methods: NS_IMETHODIMP nsSVGPreserveAspectRatio::SetValueString(const nsAString& aValue) { char* str = ToNewCString(aValue); if (!str) return NS_ERROR_OUT_OF_MEMORY; nsresult rv = NS_OK; char* rest = str; char* token; const char* delimiters = "\x20\x9\xD\xA"; PRUint16 align, meetOrSlice; token = nsCRT::strtok(rest, delimiters, &rest); if (token && !strcmp(token, "defer")) // Ignore: only applicable for preserveAspectRatio on 'image' elements token = nsCRT::strtok(rest, delimiters, &rest); if (token) { if (!strcmp(token, "none")) align = SVG_PRESERVEASPECTRATIO_NONE; else if (!strcmp(token, "xMinYMin")) align = SVG_PRESERVEASPECTRATIO_XMINYMIN; else if (!strcmp(token, "xMidYMin")) align = SVG_PRESERVEASPECTRATIO_XMIDYMIN; else if (!strcmp(token, "xMaxYMin")) align = SVG_PRESERVEASPECTRATIO_XMAXYMIN; else if (!strcmp(token, "xMinYMid")) align = SVG_PRESERVEASPECTRATIO_XMINYMID; else if (!strcmp(token, "xMidYMid")) align = SVG_PRESERVEASPECTRATIO_XMIDYMID; else if (!strcmp(token, "xMaxYMid")) align = SVG_PRESERVEASPECTRATIO_XMAXYMID; else if (!strcmp(token, "xMinYMax")) align = SVG_PRESERVEASPECTRATIO_XMINYMAX; else if (!strcmp(token, "xMidYMax")) align = SVG_PRESERVEASPECTRATIO_XMIDYMAX; else if (!strcmp(token, "xMaxYMax")) align = SVG_PRESERVEASPECTRATIO_XMAXYMAX; else rv = NS_ERROR_FAILURE; if (NS_SUCCEEDED(rv)) { token = nsCRT::strtok(rest, delimiters, &rest); if (token) { if (!strcmp(token, "meet")) meetOrSlice = SVG_MEETORSLICE_MEET; else if (!strcmp(token, "slice")) meetOrSlice = SVG_MEETORSLICE_SLICE; else rv = NS_ERROR_FAILURE; } else meetOrSlice = SVG_MEETORSLICE_MEET; } } else // align not specified rv = NS_ERROR_FAILURE; if (nsCRT::strtok(rest, delimiters, &rest)) // there's more rv = NS_ERROR_FAILURE; if (NS_SUCCEEDED(rv)) { WillModify(); mAlign = align; mMeetOrSlice = meetOrSlice; DidModify(); } nsMemory::Free(str); return rv; } NS_IMETHODIMP nsSVGPreserveAspectRatio::GetValueString(nsAString& aValue) { // XXX: defer isn't stored switch (mAlign) { case SVG_PRESERVEASPECTRATIO_NONE: aValue.AssignLiteral("none"); break; case SVG_PRESERVEASPECTRATIO_XMINYMIN: aValue.AssignLiteral("xMinYMin"); break; case SVG_PRESERVEASPECTRATIO_XMIDYMIN: aValue.AssignLiteral("xMidYMin"); break; case SVG_PRESERVEASPECTRATIO_XMAXYMIN: aValue.AssignLiteral("xMaxYMin"); break; case SVG_PRESERVEASPECTRATIO_XMINYMID: aValue.AssignLiteral("xMinYMid"); break; case SVG_PRESERVEASPECTRATIO_XMIDYMID: aValue.AssignLiteral("xMidYMid"); break; case SVG_PRESERVEASPECTRATIO_XMAXYMID: aValue.AssignLiteral("xMaxYMid"); break; case SVG_PRESERVEASPECTRATIO_XMINYMAX: aValue.AssignLiteral("xMinYMax"); break; case SVG_PRESERVEASPECTRATIO_XMIDYMAX: aValue.AssignLiteral("xMidYMax"); break; case SVG_PRESERVEASPECTRATIO_XMAXYMAX: aValue.AssignLiteral("xMaxYMax"); break; default: NS_NOTREACHED("Unknown value for mAlign"); } // XXX: meetOrSlice may not have been specified in the attribute if (mAlign != SVG_PRESERVEASPECTRATIO_NONE) { switch (mMeetOrSlice) { case SVG_MEETORSLICE_MEET: aValue.AppendLiteral(" meet"); break; case SVG_MEETORSLICE_SLICE: aValue.AppendLiteral(" slice"); break; default: NS_NOTREACHED("Unknown value for mMeetOrSlice"); } } return NS_OK; } //---------------------------------------------------------------------- // nsIDOMSVGPreserveAspectRatio methods: /* attribute unsigned short align; */ NS_IMETHODIMP nsSVGPreserveAspectRatio::GetAlign(PRUint16 *aAlign) { *aAlign = mAlign; return NS_OK; } NS_IMETHODIMP nsSVGPreserveAspectRatio::SetAlign(PRUint16 aAlign) { if (aAlign < SVG_PRESERVEASPECTRATIO_NONE || aAlign > SVG_PRESERVEASPECTRATIO_XMAXYMAX) return NS_ERROR_FAILURE; WillModify(); mAlign = aAlign; DidModify(); return NS_OK; } /* attribute unsigned short meetOrSlice; */ NS_IMETHODIMP nsSVGPreserveAspectRatio::GetMeetOrSlice(PRUint16 *aMeetOrSlice) { *aMeetOrSlice = mMeetOrSlice; return NS_OK; } NS_IMETHODIMP nsSVGPreserveAspectRatio::SetMeetOrSlice(PRUint16 aMeetOrSlice) { if (aMeetOrSlice < SVG_MEETORSLICE_MEET || aMeetOrSlice > SVG_MEETORSLICE_SLICE) return NS_ERROR_FAILURE; WillModify(); mMeetOrSlice = aMeetOrSlice; DidModify(); return NS_OK; } //////////////////////////////////////////////////////////////////////// // Exported creation functions: nsresult NS_NewSVGPreserveAspectRatio(nsIDOMSVGPreserveAspectRatio** result, PRUint16 aAlign, PRUint16 aMeetOrSlice) { *result = (nsIDOMSVGPreserveAspectRatio*) new nsSVGPreserveAspectRatio(aAlign, aMeetOrSlice); if (!*result) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(*result); return NS_OK; }